From 42a68e9ba3a1cad64989c7f376bb39cc4405cba2 Mon Sep 17 00:00:00 2001 From: Divyanshu Agrawal Date: Mon, 15 Apr 2024 18:35:11 +0530 Subject: [PATCH] Implement synchronization. --- compiler/src/common.rs | 1 + compiler/src/compiler.rs | 38 ++++++++++++++++++++++++++++++++++++++ compiler/src/debug.rs | 1 + compiler/src/vm.rs | 15 +++++++++------ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/compiler/src/common.rs b/compiler/src/common.rs index f40f54e..e1f4764 100644 --- a/compiler/src/common.rs +++ b/compiler/src/common.rs @@ -16,6 +16,7 @@ pub enum Opcode { True, False, Greater, + Pop, Equal, Less, } diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 65dd3e6..8554503 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -188,6 +188,32 @@ impl Parser { self.error_at_current(current_source.as_ref()); } } + + fn synchronize(&mut self) { + self.panic_mode = false; + + while self.current.typ != TokenType::EOF { + if self.previous.typ == TokenType::Semicolon { + return; + } + + match self.current.typ { + TokenType::Class + | TokenType::Fun + | TokenType::Var + | TokenType::For + | TokenType::If + | TokenType::While + | TokenType::Print + | TokenType::Return => { + return; + } + _ => {} + } + + self.advance() + } + } } pub struct Compiler<'src> { @@ -271,6 +297,12 @@ impl<'src> Compiler<'src> { self.parse_precedence(Precedence::Assignment); } + fn expression_statement(&mut self) { + self.expression(); + self.parser.consume(TokenType::Semicolon, "Expect ';' after expression"); + self.emit_byte(Opcode::Pop as u8); + } + fn print_statement(&mut self) { self.expression(); self.parser.consume(TokenType::Semicolon, "Expect ';' after expression"); @@ -279,11 +311,17 @@ impl<'src> Compiler<'src> { fn declaration(&mut self) { self.statement(); + + if self.parser.panic_mode { + self.parser.synchronize(); + } } fn statement(&mut self) { if self.parser.match_tt(TokenType::Print) { self.print_statement(); + } else { + self.expression_statement(); } } diff --git a/compiler/src/debug.rs b/compiler/src/debug.rs index 846a801..71d647a 100644 --- a/compiler/src/debug.rs +++ b/compiler/src/debug.rs @@ -26,6 +26,7 @@ pub fn disassemble_instruction(chunk: &Chunk, offset: usize, interner: &Interner | Opcode::Greater | Opcode::Less | Opcode::Print + | Opcode::Pop | Opcode::Not => simple_instruction(chunk, instruction, offset), }; diff --git a/compiler/src/vm.rs b/compiler/src/vm.rs index 0666c90..b123263 100644 --- a/compiler/src/vm.rs +++ b/compiler/src/vm.rs @@ -121,8 +121,16 @@ impl<'src> Vm<'src> { } } } - Opcode::False => vm.stack.push(Bool(false)), Opcode::True => vm.stack.push(Bool(true)), + Opcode::False => vm.stack.push(Bool(false)), + Opcode::Pop => { + vm.pop()?; + } + Opcode::Equal => { + let a = vm.pop()?; + let b = vm.pop()?; + vm.stack.push(Bool(a == b)) + } Opcode::Nil => vm.stack.push(Nil), Opcode::Add => { let b = vm.pop()?; @@ -150,11 +158,6 @@ impl<'src> Vm<'src> { let val = vm.pop()?; vm.stack.push(Bool(vm.is_falsey(val))) } - Opcode::Equal => { - let a = vm.pop()?; - let b = vm.pop()?; - vm.stack.push(Bool(a == b)) - } Opcode::Greater => binop!(vm, Bool, >), Opcode::Less => binop!(vm, Bool, <), }