scanner now recognizes numeric (f64) literals

This commit is contained in:
Sander Hautvast 2020-01-24 13:50:12 +01:00
parent 650a31889b
commit 071f584e92
3 changed files with 81 additions and 22 deletions

View file

@ -102,9 +102,35 @@ impl Scanner<'_> {
'\t' => {}
'\r' => {}
'\"' => self.string(),
_ => {}
_ => {
if next_char.is_digit(10) {
self.number();
} else {
self.report_error(self.line, "unexpected character");
}
}
}
}
/// handle number literals
/// advances while characters are considered part of the number
/// finally adds a number token to the list.
fn number(&mut self) {
while self.peek(0).is_digit(10) {
self.advance();
}
if self.peek(0) == '.' && self.peek(1).is_digit(10) {
self.advance();
while self.peek(0).is_digit(10) {
self.advance();
}
}
let value: f64 = self.source[self.start..self.current].parse().expect("not a number");
self.add_token_literal(NUMBER, Box::new(value));
}
/// handle string literals
/// advances until a terminating double quote is found and then adds the string token to the list

View file

@ -46,3 +46,14 @@ fn test_scan_string_literals() {
assert_eq!(token.lexeme, "\"hello world\"");
assert_eq!(token.get_literal_as_string().unwrap(), "hello world");
}
#[test]
fn test_scan_numeric_literals() {
let tokens = scan_tokens("0.1").unwrap();
assert_eq!(tokens.len(), 2);
let token = tokens.get(0).unwrap();
assert_eq!(token.token_type, NUMBER);
assert_eq!(token.lexeme, "0.1");
assert_eq!(token.get_literal_as_float().unwrap(), 0.1);
}

View file

@ -16,9 +16,13 @@ pub struct Token<'a> {
pub token_type: TokenType,
}
impl Token<'_>{
pub fn get_literal_as_string(&self) -> Option<&str>{
self.literal.downcast_ref::<String>().map(|s|s.as_str())
impl Token<'_> {
pub fn get_literal_as_string(&self) -> Option<&str> {
self.literal.downcast_ref::<String>().map(|s| s.as_str())
}
pub fn get_literal_as_float(&self) -> Option<f64> {
self.literal.downcast_ref::<f64>().map(|f| *f)
}
}
@ -40,30 +44,48 @@ impl fmt::Debug for Token<'_> {
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
pub enum TokenType {
// Single-character tokens.
LEFTPAREN, // (
RIGHTPAREN, // )
LEFTBRACE, // [
RIGHTBRACE, // ]
COMMA, // ,
DOT, // .
MINUS, // -
PLUS, // +
SEMICOLON, // ;
STAR, // *
LEFTPAREN,
// (
RIGHTPAREN,
// )
LEFTBRACE,
// [
RIGHTBRACE,
// ]
COMMA,
// ,
DOT,
// .
MINUS,
// -
PLUS,
// +
SEMICOLON,
// ;
STAR,
// *
SLASH, // /
// One or two character tokens.
BANG, // !
BANGEQUAL, // !=
EQUAL, // =
EQUALEQUAL, // ==
GREATER, // >
GREATEREQUAL, // >=
LESS, // <
BANG,
// !
BANGEQUAL,
// !=
EQUAL,
// =
EQUALEQUAL,
// ==
GREATER,
// >
GREATEREQUAL,
// >=
LESS,
// <
LESSEQUAL, // <=
// Literals.
STRING,
NUMBER,
EOF // end of file
EOF, // end of file
}