From 97505eb1e1de6eb09c786fff0042767ba413ec76 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 28 Nov 2020 17:32:44 +0100 Subject: [PATCH] feat(tazjin/rlox): Implement number scanning Change-Id: Ide0126d1c2274d56903092816ff9cd531c03f513 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2191 Reviewed-by: tazjin Tested-by: BuildkiteCI --- users/tazjin/rlox/src/scanner.rs | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/users/tazjin/rlox/src/scanner.rs b/users/tazjin/rlox/src/scanner.rs index 187ccb2f6..c6db9de8c 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::() + .parse() + .expect("float parsing should always work"); + + self.add_token(TokenKind::Number(num)); + } + fn scan_tokens(mut self) -> Vec> { while !self.is_at_end() { self.start = self.current;