From 47aa92b87d235e22974efb1b8f495c39f4b92a71 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 28 Nov 2020 17:18:48 +0100 Subject: feat(tazjin/rlox): Implement string scanning Note that Lox does not support escapes, and I don't care about that. Change-Id: Ie848cbc1164c4b005b15e29aad8fe723aaa68d1b Reviewed-on: https://cl.tvl.fyi/c/depot/+/2190 Reviewed-by: tazjin Tested-by: BuildkiteCI --- users/tazjin/rlox/src/errors.rs | 1 + users/tazjin/rlox/src/scanner.rs | 41 ++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) (limited to 'users/tazjin') diff --git a/users/tazjin/rlox/src/errors.rs b/users/tazjin/rlox/src/errors.rs index 46c739ef2f46..306cfec4ca34 100644 --- a/users/tazjin/rlox/src/errors.rs +++ b/users/tazjin/rlox/src/errors.rs @@ -1,6 +1,7 @@ #[derive(Debug)] pub enum ErrorKind { UnexpectedChar(char), + UnterminatedString, } #[derive(Debug)] diff --git a/users/tazjin/rlox/src/scanner.rs b/users/tazjin/rlox/src/scanner.rs index 17c474ba9b2d..187ccb2f61cb 100644 --- a/users/tazjin/rlox/src/scanner.rs +++ b/users/tazjin/rlox/src/scanner.rs @@ -27,7 +27,7 @@ pub enum TokenKind { // Literals. Identifier, - String, + String(String), Number, // Keywords. @@ -76,7 +76,7 @@ impl<'a> Scanner<'a> { fn advance(&mut self) -> char { self.current += 1; - self.source[self.current-1] + self.source[self.current - 1] } fn add_token(&mut self, kind: TokenKind) { @@ -117,14 +117,16 @@ impl<'a> Scanner<'a> { } else { self.add_token(TokenKind::Slash); } - }, + } // ignore whitespace - ' ' => {}, - '\r' => {}, - '\t' => {}, + ' ' => {} + '\r' => {} + '\t' => {} '\n' => self.line += 1, + '"' => self.scan_string(), + unexpected => self.errors.push(Error { line: self.line, kind: ErrorKind::UnexpectedChar(unexpected), @@ -157,6 +159,33 @@ impl<'a> Scanner<'a> { } } + fn scan_string(&mut self) { + while (self.peek() != '"' && !self.is_at_end()) { + if self.peek() == '\n' { + self.line += 1; + } + + self.advance(); + } + + if self.is_at_end() { + self.errors.push(Error { + line: self.line, + kind: ErrorKind::UnterminatedString, + }); + return; + } + + // closing '"' + self.advance(); + + // add token without surrounding quotes + let string: String = self.source[(self.start + 1)..(self.current - 1)] + .iter() + .collect(); + self.add_token(TokenKind::String(string)); + } + fn scan_tokens(mut self) -> Vec> { while !self.is_at_end() { self.start = self.current; -- cgit 1.4.1