scanner now recognizes numeric (f64) literals
This commit is contained in:
parent
650a31889b
commit
071f584e92
3 changed files with 81 additions and 22 deletions
|
|
@ -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
|
||||
|
|
|
|||
11
src/tests.rs
11
src/tests.rs
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue