From 9d1996c9ec1858c02358143007fff5a26b344b66 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 1 Oct 2024 20:07:57 -0400 Subject: [PATCH] Simplify parsing comparison expressions --- dust-lang/src/chunk.rs | 13 ++++++++++ dust-lang/src/parser/mod.rs | 48 ++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/dust-lang/src/chunk.rs b/dust-lang/src/chunk.rs index b110ff4..68628ca 100644 --- a/dust-lang/src/chunk.rs +++ b/dust-lang/src/chunk.rs @@ -87,6 +87,19 @@ impl Chunk { Ok((instruction, position)) } + pub fn get_last_n_instructions(&self) -> [Option<&(Instruction, Span)>; N] { + let mut instructions = [None; N]; + + for i in 0..N { + let index = self.instructions.len().saturating_sub(i + 1); + let instruction = self.instructions.get(index); + + instructions[i] = instruction; + } + + instructions + } + pub fn find_last_instruction(&mut self, operation: Operation) -> Option { self.instructions .iter() diff --git a/dust-lang/src/parser/mod.rs b/dust-lang/src/parser/mod.rs index da53ee8..50e0dbe 100644 --- a/dust-lang/src/parser/mod.rs +++ b/dust-lang/src/parser/mod.rs @@ -477,21 +477,6 @@ impl<'src> Parser<'src> { } fn parse_comparison_binary(&mut self) -> Result<(), ParseError> { - let is_repetition = matches!( - self.chunk.get_last_n_operations(), - [ - Some(_), - Some(_), - Some(Operation::Jump), - Some(Operation::Equal | Operation::Less | Operation::LessEqual) - ] - ); - - if is_repetition { - self.decrement_register()?; - self.decrement_register()?; - } - let (left_instruction, left_position) = self.chunk.pop_instruction(self.current_position)?; let (push_back_left, left_is_constant, left) = @@ -551,15 +536,6 @@ impl<'src> Parser<'src> { self.emit_instruction(instruction, operator_position); self.emit_instruction(Instruction::jump(1, true), operator_position); - self.emit_instruction( - Instruction::load_boolean(self.current_register, true, true), - operator_position, - ); - self.emit_instruction( - Instruction::load_boolean(self.current_register, false, false), - operator_position, - ); - self.increment_register()?; Ok(()) } @@ -837,7 +813,29 @@ impl<'src> Parser<'src> { } fn parse_expression(&mut self) -> Result<(), ParseError> { - self.parse(Precedence::None) + self.parse(Precedence::None)?; + + if let [Some((jump, _)), Some((comparison, comparison_position))] = + self.chunk.get_last_n_instructions() + { + if let (Operation::Jump, Operation::Equal | Operation::Less | Operation::LessEqual) = + (jump.operation(), comparison.operation()) + { + let comparison_position = *comparison_position; + + self.emit_instruction( + Instruction::load_boolean(self.current_register, true, true), + comparison_position, + ); + self.emit_instruction( + Instruction::load_boolean(self.current_register, false, false), + comparison_position, + ); + self.increment_register()?; + } + } + + Ok(()) } fn parse_statement(&mut self, allow_return: bool) -> Result<(), ParseError> {