about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-11-28T16·18+0100
committertazjin <mail@tazj.in>2020-11-28T16·33+0000
commit47aa92b87d235e22974efb1b8f495c39f4b92a71 (patch)
tree35133ec7ae023a51de3d375612dead8a0f0aaf27
parent800d2ccde875551a2aa2a54b122696818111a2d8 (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
-rw-r--r--users/tazjin/rlox/src/errors.rs1
-rw-r--r--users/tazjin/rlox/src/scanner.rs41
2 files changed, 36 insertions, 6 deletions
diff --git a/users/tazjin/rlox/src/errors.rs b/users/tazjin/rlox/src/errors.rs
index 46c739ef2f..306cfec4ca 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 17c474ba9b..187ccb2f61 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;