diff --git a/src/parser.rs b/src/parser.rs index 0bc7ccfa..ec8db86b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -372,6 +372,7 @@ impl<'a> TokenIterator<'a> { match c { '0'...'9' => { let mut result = Vec::new(); + let mut radix_base: Option = None; result.push(c); while let Some(&nxt) = self.char_stream.peek() { @@ -393,10 +394,59 @@ impl<'a> TokenIterator<'a> { } } } + 'x' | 'X' => { + result.push(nxt); + self.char_stream.next(); + while let Some(&nxt_hex) = self.char_stream.peek() { + match nxt_hex { + '0'...'9' | 'a'...'f' | 'A'...'F' => { + result.push(nxt_hex); + self.char_stream.next(); + } + _ => break, + } + } + radix_base = Some(16); + } + 'o' | 'O' => { + result.push(nxt); + self.char_stream.next(); + while let Some(&nxt_oct) = self.char_stream.peek() { + match nxt_oct { + '0'...'8' => { + result.push(nxt_oct); + self.char_stream.next(); + } + _ => break, + } + } + radix_base = Some(8); + } + 'b' | 'B' => { + result.push(nxt); + self.char_stream.next(); + while let Some(&nxt_bin) = self.char_stream.peek() { + match nxt_bin { + '0' | '1' | '_' => { + result.push(nxt_bin); + self.char_stream.next(); + } + _ => break, + } + } + radix_base = Some(2); + } _ => break, } } + if let Some(radix) = radix_base { + let out: String = result.iter().cloned().skip(2).filter(|c| c != &'_').collect(); + if let Ok(val) = i64::from_str_radix(&out, radix) { + return Some(Token::IntConst(val)); + } + } + let out: String = result.iter().cloned().collect(); if let Ok(val) = out.parse::() { diff --git a/src/tests.rs b/src/tests.rs index c19225ef..9ff3fc65 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -690,6 +690,23 @@ fn test_right_shift_equals() { } } +#[test] +fn test_hex_literal() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = 0xf; x") { + assert_eq!(result, 15); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("let x = 0xff; x") { + assert_eq!(result, 255); + } else { + assert!(false); + } +} + #[test] fn test_modulo_equals() { let mut engine = Engine::new(); @@ -701,6 +718,40 @@ fn test_modulo_equals() { } } +#[test] +fn test_octal_literal() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = 0o77; x") { + assert_eq!(result, 63); + } else { + assert!(false) + } + + if let Ok(result) = engine.eval::("let x = 0o1234; x") { + assert_eq!(result, 668); + } else { + assert!(false); + } +} + +#[test] +fn test_binary_literal() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = 0b1111; x") { + assert_eq!(result, 15); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("let x = 0b0011_1100_1010_0101; x") { + assert_eq!(result, 15525); + } else { + assert!(false); + } +} + #[test] fn test_binary_ops() { let mut engine = Engine::new();