about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/bytecode/compiler.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-02-27T13·45+0200
committertazjin <mail@tazj.in>2021-02-27T19·22+0000
commitb13a6736ddf87e9689a207d5980dd28b9aa83dd4 (patch)
treeff8e95d5693d51ab5ccd755a420278a1a4046ff8 /users/tazjin/rlox/src/bytecode/compiler.rs
parentee974b3eddffa47d0d16beeada6658f37a21a8d4 (diff)
chore(tazjin/rlox): Set up some scaffolding for panic mode r/2238
This lets us suppress reporting of additional errors from the compiler
until a synchronisation point is reached.

Change-Id: Iacf90949f868fbdb4349750065b5e458cf74d32a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2557
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src/bytecode/compiler.rs')
-rw-r--r--users/tazjin/rlox/src/bytecode/compiler.rs27
1 files changed, 22 insertions, 5 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler.rs b/users/tazjin/rlox/src/bytecode/compiler.rs
index 0197885a52d2..ab5a970ffd12 100644
--- a/users/tazjin/rlox/src/bytecode/compiler.rs
+++ b/users/tazjin/rlox/src/bytecode/compiler.rs
@@ -4,10 +4,10 @@ use super::opcode::OpCode;
 use crate::scanner;
 
 struct Compiler<T: Iterator<Item = scanner::Token>> {
-    // panic: bool,
-    errors: Vec<Error>,
     tokens: T,
     chunk: Chunk,
+    panic: bool,
+    errors: Vec<Error>,
 
     // TODO(tazjin): Restructure so that these don't need to be Option?
     current: Option<scanner::Token>,
@@ -48,16 +48,32 @@ impl<T: Iterator<Item = scanner::Token>> Compiler<T> {
     }
 
     fn end_compiler(&mut self) -> LoxResult<()> {
-        let line = self.previous().line;
-        self.current_chunk().add_op(OpCode::OpReturn, line);
+        self.emit_op(OpCode::OpReturn);
         Ok(())
     }
 
+    fn emit_op(&mut self, op: OpCode) {
+        let line = self.previous().line;
+        self.current_chunk().add_op(op, line);
+    }
+
     fn previous(&self) -> &scanner::Token {
         self.previous
             .as_ref()
             .expect("invalid internal compiler state: missing previous token")
     }
+
+    fn error_at(&mut self, token: &scanner::Token, kind: ErrorKind) {
+        if self.panic {
+            return;
+        }
+
+        self.panic = true;
+        self.errors.push(Error {
+            kind,
+            line: token.line,
+        })
+    }
 }
 
 pub fn compile(code: &str) -> Result<Chunk, Vec<Error>> {
@@ -68,10 +84,11 @@ pub fn compile(code: &str) -> Result<Chunk, Vec<Error>> {
 
     let mut compiler = Compiler {
         tokens: tokens.into_iter().peekable(),
+        chunk: Default::default(),
+        panic: false,
         errors: vec![],
         current: None,
         previous: None,
-        chunk: Default::default(),
     };
 
     compiler.compile()?;