diff options
Diffstat (limited to 'users/tazjin/rlox/src/scanner.rs')
-rw-r--r-- | users/tazjin/rlox/src/scanner.rs | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/users/tazjin/rlox/src/scanner.rs b/users/tazjin/rlox/src/scanner.rs index 187ccb2f61cb..c6db9de8c5d0 100644 --- a/users/tazjin/rlox/src/scanner.rs +++ b/users/tazjin/rlox/src/scanner.rs @@ -28,7 +28,7 @@ pub enum TokenKind { // Literals. Identifier, String(String), - Number, + Number(f64), // Keywords. And, @@ -127,6 +127,8 @@ impl<'a> Scanner<'a> { '"' => self.scan_string(), + digit if digit.is_digit(10) => self.scan_number(), + unexpected => self.errors.push(Error { line: self.line, kind: ErrorKind::UnexpectedChar(unexpected), @@ -159,8 +161,16 @@ impl<'a> Scanner<'a> { } } + fn peek_next(&self) -> char { + if (self.current + 1 >= self.source.len()) { + return '\0'; + } else { + return self.source[self.current + 1]; + } + } + fn scan_string(&mut self) { - while (self.peek() != '"' && !self.is_at_end()) { + while self.peek() != '"' && !self.is_at_end() { if self.peek() == '\n' { self.line += 1; } @@ -186,6 +196,30 @@ impl<'a> Scanner<'a> { self.add_token(TokenKind::String(string)); } + fn scan_number(&mut self) { + while self.peek().is_digit(10) { + self.advance(); + } + + // Look for a fractional part + if self.peek() == '.' && self.peek_next().is_digit(10) { + // consume '.' + self.advance(); + + while self.peek().is_digit(10) { + self.advance(); + } + } + + let num: f64 = self.source[self.start..self.current] + .iter() + .collect::<String>() + .parse() + .expect("float parsing should always work"); + + self.add_token(TokenKind::Number(num)); + } + fn scan_tokens(mut self) -> Vec<Token<'a>> { while !self.is_at_end() { self.start = self.current; |