diff --git a/src/parser.rs b/src/parser.rs index 67096fba..9d8b1161 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -391,6 +391,57 @@ 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, + } + } + let out: String = result.iter().cloned().skip(2).collect(); + if let Ok(val) = i64::from_str_radix(&out, 16) { + return Some(Token::IntConst(val)); + } + } + '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, + } + } + let out: String = result.iter().cloned().skip(2).collect(); + if let Ok(val) = i64::from_str_radix(&out, 8) { + return Some(Token::IntConst(val)); + } + } + '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, + } + } + let out: String = result.iter().cloned().skip(2).filter(|c| c != &'_').collect(); + if let Ok(val) = i64::from_str_radix(&out, 2) { + return Some(Token::IntConst(val)); + } + } _ => break, } } diff --git a/src/tests.rs b/src/tests.rs index b9dd0711..bc76c046 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -688,4 +688,55 @@ fn test_right_shift_equals() { } else { assert!(false); } +} + +#[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_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); + } } \ No newline at end of file