wright/parser/literal/
integer.rs1use crate::parser::Parser;
4use crate::parser::error::{ParserError, ParserErrorKind};
5use crate::{ast::literal::IntegerLiteral, lexer::token::TokenTy};
6use num::{BigUint, Num};
7
8impl IntegerLiteral {
9 pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
11 let int_lit_token = parser.next_if_is(TokenTy::IntegerLiteral).ok_or_else(|| {
13 ParserErrorKind::ExpectedIntegerLiteral.at(parser.peek_fragment_or_rest_cloned())
14 })?;
15
16 let mut parse_str: &str = int_lit_token.fragment.as_str();
18 let mut chars = parse_str.chars();
19
20 let prefix: [char; 2] = [chars.next().unwrap(), chars.next().unwrap_or('\0')];
24
25 let radix: u32 = match prefix {
27 ['0', 'x' | 'X'] => {
29 parse_str = &parse_str[2..];
30 16
31 }
32
33 ['0', 'b' | 'B'] => {
35 parse_str = &parse_str[2..];
36 2
37 }
38
39 ['0', 'o'] => {
41 parse_str = &parse_str[2..];
42 8
43 }
44
45 _ => 10,
47 };
48
49 let value = BigUint::from_str_radix(parse_str, radix)
51 .expect("num should successfully parse");
54
55 Ok(IntegerLiteral {
56 fragment: int_lit_token.fragment,
57 value,
58 })
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use num::BigUint;
65
66 use crate::{ast::literal::IntegerLiteral, lexer::Lexer, parser::Parser};
67
68 #[test]
69 fn normal() {
70 let mut parser = Parser::new(Lexer::new_test("1000"));
71
72 let int_lit = IntegerLiteral::parse(&mut parser).unwrap();
73
74 assert_eq!(int_lit.value, BigUint::new(vec![1000]));
75 assert_eq!(parser.lexer.remaining.as_str(), "");
76 assert_eq!(int_lit.fragment.as_str(), "1000");
77 }
78
79 }