diff options
author | Vincent Ambo <mail@tazj.in> | 2020-11-28T16·18+0100 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2020-11-28T16·33+0000 |
commit | 47aa92b87d235e22974efb1b8f495c39f4b92a71 (patch) | |
tree | 35133ec7ae023a51de3d375612dead8a0f0aaf27 /users/tazjin | |
parent | 800d2ccde875551a2aa2a54b122696818111a2d8 (diff) |
feat(tazjin/rlox): Implement string scanning r/1953
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 <mail@tazj.in> Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin')
-rw-r--r-- | users/tazjin/rlox/src/errors.rs | 1 | ||||
-rw-r--r-- | users/tazjin/rlox/src/scanner.rs | 41 |
2 files changed, 36 insertions, 6 deletions
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<Token<'a>> { while !self.is_at_end() { self.start = self.current; |