diff options
author | Vincent Ambo <mail@tazj.in> | 2020-11-28T16·32+0100 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2020-11-28T16·55+0000 |
commit | 97505eb1e1de6eb09c786fff0042767ba413ec76 (patch) | |
tree | 9f2df91024206b11c9de6fc2566e1ff275586953 /users/tazjin | |
parent | 47aa92b87d235e22974efb1b8f495c39f4b92a71 (diff) |
feat(tazjin/rlox): Implement number scanning r/1954
Change-Id: Ide0126d1c2274d56903092816ff9cd531c03f513 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2191 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin')
-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; |