about summary refs log tree commit diff
path: root/users/tazjin
diff options
context:
space:
mode:
Diffstat (limited to 'users/tazjin')
-rw-r--r--users/tazjin/rlox/src/bytecode/compiler.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler.rs b/users/tazjin/rlox/src/bytecode/compiler.rs
index 9a8f80ae2b7d..8e70067e3182 100644
--- a/users/tazjin/rlox/src/bytecode/compiler.rs
+++ b/users/tazjin/rlox/src/bytecode/compiler.rs
@@ -174,7 +174,13 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
     }
 
     fn declaration(&mut self) -> LoxResult<()> {
-        self.statement()
+        self.statement()?;
+
+        if self.panic {
+            self.synchronise();
+        }
+
+        Ok(())
     }
 
     fn statement(&mut self) -> LoxResult<()> {
@@ -396,6 +402,31 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
     fn check(&self, token: &TokenKind) -> bool {
         return self.current().kind == *token;
     }
+
+    fn synchronise(&mut self) {
+        self.panic = false;
+
+        while self.current().kind != TokenKind::Eof {
+            if self.previous().kind == TokenKind::Semicolon {
+                return;
+            }
+
+            match self.current().kind {
+                TokenKind::Class
+                | TokenKind::Fun
+                | TokenKind::Var
+                | TokenKind::For
+                | TokenKind::If
+                | TokenKind::While
+                | TokenKind::Print
+                | TokenKind::Return => return,
+
+                _ => {
+                    self.advance();
+                }
+            }
+        }
+    }
 }
 
 pub fn compile(code: &str) -> Result<(Interner, Chunk), Vec<Error>> {