about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-11-27T17·10+0100
committertazjin <mail@tazj.in>2020-11-27T17·29+0000
commit3f6b88bce231cfdc00fc7521fcb83d7114ad9142 (patch)
tree101d1de088a51594a38b5f12c4ae2e6c8751e4af
parent6363efbebf2c9f567fb5f007b45aab619c4f7e25 (diff)
feat(tazjin/rlox): Implement multi-character scanning r/1926
Change-Id: Ic5a246a7f5834477aeb97824fa30ba74a8422bc1
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2161
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
-rw-r--r--users/tazjin/rlox/src/scanner.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/users/tazjin/rlox/src/scanner.rs b/users/tazjin/rlox/src/scanner.rs
index 78a019592ca4..659f280de72b 100644
--- a/users/tazjin/rlox/src/scanner.rs
+++ b/users/tazjin/rlox/src/scanner.rs
@@ -90,6 +90,7 @@ impl<'a> Scanner<'a> {
 
     fn scan_token(&mut self) {
         match self.advance() {
+            // simple single-character tokens
             '(' => self.add_token(TokenKind::LeftParen),
             ')' => self.add_token(TokenKind::RightParen),
             '{' => self.add_token(TokenKind::LeftBrace),
@@ -101,6 +102,12 @@ impl<'a> Scanner<'a> {
             ';' => self.add_token(TokenKind::Semicolon),
             '*' => self.add_token(TokenKind::Star),
 
+            // possible multi-character tokens
+            '!' => self.add_if_next('=', TokenKind::BangEqual, TokenKind::Bang),
+            '=' => self.add_if_next('=', TokenKind::EqualEqual, TokenKind::Equal),
+            '<' => self.add_if_next('=', TokenKind::LessEqual, TokenKind::Less),
+            '>' => self.add_if_next('=', TokenKind::GreaterEqual, TokenKind::Greater),
+
             unexpected => self.errors.push(Error {
                 line: self.line,
                 kind: ErrorKind::UnexpectedChar(unexpected),
@@ -108,6 +115,15 @@ impl<'a> Scanner<'a> {
         };
     }
 
+    fn add_if_next(&mut self, expected:char, then: TokenKind, or: TokenKind) {
+        if self.is_at_end() || self.source[self.current] != expected {
+            self.add_token(or);
+        } else {
+            self.current += 1;
+            self.add_token(then);
+        }
+    }
+
     fn scan_tokens(mut self) -> Vec<Token<'a>> {
         while !self.is_at_end() {
             self.start = self.current;