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' => {}
|
'\t' => {}
|
||||||
'\r' => {}
|
'\r' => {}
|
||||||
'\"' => self.string(),
|
'\"' => 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
|
/// handle string literals
|
||||||
/// advances until a terminating double quote is found and then adds the string token to the list
|
/// 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.lexeme, "\"hello world\"");
|
||||||
assert_eq!(token.get_literal_as_string().unwrap(), "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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ impl Token<'_>{
|
||||||
pub fn get_literal_as_string(&self) -> Option<&str> {
|
pub fn get_literal_as_string(&self) -> Option<&str> {
|
||||||
self.literal.downcast_ref::<String>().map(|s| s.as_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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Token<'_> {
|
impl fmt::Debug for Token<'_> {
|
||||||
|
|
@ -40,30 +44,48 @@ impl fmt::Debug for Token<'_> {
|
||||||
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
|
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
|
||||||
pub enum TokenType {
|
pub enum TokenType {
|
||||||
// Single-character tokens.
|
// Single-character tokens.
|
||||||
LEFTPAREN, // (
|
LEFTPAREN,
|
||||||
RIGHTPAREN, // )
|
// (
|
||||||
LEFTBRACE, // [
|
RIGHTPAREN,
|
||||||
RIGHTBRACE, // ]
|
// )
|
||||||
COMMA, // ,
|
LEFTBRACE,
|
||||||
DOT, // .
|
// [
|
||||||
MINUS, // -
|
RIGHTBRACE,
|
||||||
PLUS, // +
|
// ]
|
||||||
SEMICOLON, // ;
|
COMMA,
|
||||||
STAR, // *
|
// ,
|
||||||
|
DOT,
|
||||||
|
// .
|
||||||
|
MINUS,
|
||||||
|
// -
|
||||||
|
PLUS,
|
||||||
|
// +
|
||||||
|
SEMICOLON,
|
||||||
|
// ;
|
||||||
|
STAR,
|
||||||
|
// *
|
||||||
SLASH, // /
|
SLASH, // /
|
||||||
|
|
||||||
// One or two character tokens.
|
// One or two character tokens.
|
||||||
BANG, // !
|
BANG,
|
||||||
BANGEQUAL, // !=
|
// !
|
||||||
EQUAL, // =
|
BANGEQUAL,
|
||||||
EQUALEQUAL, // ==
|
// !=
|
||||||
GREATER, // >
|
EQUAL,
|
||||||
GREATEREQUAL, // >=
|
// =
|
||||||
LESS, // <
|
EQUALEQUAL,
|
||||||
|
// ==
|
||||||
|
GREATER,
|
||||||
|
// >
|
||||||
|
GREATEREQUAL,
|
||||||
|
// >=
|
||||||
|
LESS,
|
||||||
|
// <
|
||||||
LESSEQUAL, // <=
|
LESSEQUAL, // <=
|
||||||
|
|
||||||
// Literals.
|
// Literals.
|
||||||
STRING,
|
STRING,
|
||||||
|
NUMBER,
|
||||||
|
|
||||||
EOF // end of file
|
EOF, // end of file
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue