From c31991cc24292fb501d124a20ff89f005bb414cf Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 23 Sep 2024 23:38:49 -0400 Subject: [PATCH] Fix and pass tests --- dust-lang/src/instruction.rs | 2 +- dust-lang/src/parser/mod.rs | 78 ++++++++++++++---------------------- dust-lang/src/vm.rs | 8 ++-- 3 files changed, 35 insertions(+), 53 deletions(-) diff --git a/dust-lang/src/instruction.rs b/dust-lang/src/instruction.rs index c15fc0a..97ac855 100644 --- a/dust-lang/src/instruction.rs +++ b/dust-lang/src/instruction.rs @@ -467,7 +467,7 @@ impl Instruction { let (first_argument, second_argument) = format_arguments(); - format!("if {first_argument} {comparison_symbol} {second_argument} {{ IP += 1 }}",) + format!("if {first_argument} {comparison_symbol} {second_argument} IP++",) } Operation::Less => { let comparison_symbol = if self.destination_as_boolean() { diff --git a/dust-lang/src/parser/mod.rs b/dust-lang/src/parser/mod.rs index e0b1cd5..0257423 100644 --- a/dust-lang/src/parser/mod.rs +++ b/dust-lang/src/parser/mod.rs @@ -384,12 +384,7 @@ impl<'src> Parser<'src> { instruction.first_argument() } - Operation::LoadBoolean => { - is_constant = true; - push_back = true; - - instruction.destination() - } + Operation::LoadBoolean => instruction.destination(), Operation::Close => { return Err(ParseError::ExpectedExpression { found: self.previous_token.to_owned(), @@ -470,26 +465,20 @@ impl<'src> Parser<'src> { } fn parse_comparison_binary(&mut self) -> Result<(), ParseError> { - let (previous_booleans, equal_argument) = if let [Some(Operation::LoadBoolean), Some(Operation::LoadBoolean), Some(Operation::Jump), Some(Operation::Equal)] = - self.chunk.get_last_n_operations() - { - let load_booleans = ( - self.chunk.pop_instruction(self.current_position)?, - self.chunk.pop_instruction(self.current_position)?, - ); + let is_repetition = matches!( + self.chunk.get_last_n_operations(), + [ + Some(_), + Some(_), + Some(Operation::Jump), + Some(Operation::Equal | Operation::Less | Operation::LessEqual) + ] + ); - let (jump, jump_position) = self.chunk.pop_instruction(self.current_position)?; - let (equal, equal_position) = self.chunk.pop_instruction(self.current_position)?; - let equal_argument = equal.second_argument(); - let is_constant = equal.second_argument_is_constant(); - - self.emit_instruction(equal, equal_position); - self.emit_instruction(jump, jump_position); - - (Some(load_booleans), Some((equal_argument, is_constant))) - } else { - (None, None) - }; + if is_repetition { + self.decrement_register()?; + self.decrement_register()?; + } let (left_instruction, left_position) = self.chunk.pop_instruction(self.current_position)?; @@ -532,13 +521,7 @@ impl<'src> Parser<'src> { instruction.set_second_argument(right); - if let Some((equal_argument, is_constant)) = equal_argument { - instruction.set_first_argument(equal_argument); - - if is_constant { - instruction.set_first_argument_to_constant(); - } - } else if left_is_constant { + if left_is_constant { instruction.set_first_argument_to_constant(); } @@ -546,25 +529,24 @@ impl<'src> Parser<'src> { instruction.set_second_argument_to_constant(); } - if push_back_left { - self.emit_instruction(left_instruction, left_position); - self.increment_register()?; - } + if push_back_left || push_back_right { + if push_back_left { + self.emit_instruction(left_instruction, left_position); + } - if push_back_right { - self.emit_instruction(right_instruction, right_position); - self.increment_register()?; - } + if push_back_right { + self.emit_instruction(right_instruction, right_position); + } - self.emit_instruction(instruction, operator_position); - self.emit_instruction(Instruction::jump(1, true), operator_position); - - if let Some(((left_boolean, left_position), (right_boolean, right_position))) = - previous_booleans - { - self.emit_instruction(right_boolean, right_position); - self.emit_instruction(left_boolean, left_position); + self.emit_instruction(instruction, operator_position); + self.emit_instruction(Instruction::jump(1, true), operator_position); + self.emit_instruction( + Instruction::r#move(self.current_register, instruction.destination()), + operator_position, + ); } else { + 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, diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 17c710e..53371cf 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -37,7 +37,7 @@ impl Vm { } pub fn run(&mut self) -> Result, VmError> { - // DRY helper to take constants or clone registers for binary operations + // DRY helper to get constant or register values for binary operations fn get_arguments( vm: &mut Vm, instruction: Instruction, @@ -225,7 +225,7 @@ impl Vm { let compare_to = instruction.destination_as_boolean(); if let Some(boolean) = equal.as_boolean() { - if boolean == compare_to { + if boolean && compare_to { self.ip += 1; } } @@ -235,7 +235,7 @@ impl Vm { let less = left .less_than(right) .map_err(|error| VmError::Value { error, position })?; - let compare_to = instruction.destination() != 0; + let compare_to = instruction.destination_as_boolean(); if let Some(boolean) = less.as_boolean() { if boolean == compare_to { @@ -248,7 +248,7 @@ impl Vm { let less_equal = left .less_than_or_equal(right) .map_err(|error| VmError::Value { error, position })?; - let compare_to = instruction.destination() != 0; + let compare_to = instruction.destination_as_boolean(); if let Some(boolean) = less_equal.as_boolean() { if boolean == compare_to {