From 1d03876b89c13df8e96c1e480adc0570e3e6e18b Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 24 Sep 2024 01:30:21 -0400 Subject: [PATCH] Write tests --- dust-lang/src/parser/mod.rs | 77 ++++------------------------------- dust-lang/src/parser/tests.rs | 22 ++++------ dust-lang/tests/operations.rs | 5 ++- 3 files changed, 20 insertions(+), 84 deletions(-) diff --git a/dust-lang/src/parser/mod.rs b/dust-lang/src/parser/mod.rs index fc0537d..a0e96d5 100644 --- a/dust-lang/src/parser/mod.rs +++ b/dust-lang/src/parser/mod.rs @@ -162,44 +162,8 @@ impl<'src> Parser<'src> { self.advance()?; - let previous_operations = self.chunk.get_last_n_operations::<2>(); - - if let [Some(Operation::LoadBoolean), Some(Operation::LoadBoolean)] = previous_operations { - let (second_boolean, second_position) = - self.chunk.pop_instruction(self.current_position)?; - let (first_boolean, first_position) = - self.chunk.pop_instruction(self.current_position)?; - - if first_boolean.first_argument_as_boolean() == boolean { - let skip = first_boolean.second_argument_as_boolean(); - - self.emit_instruction( - Instruction::load_boolean(self.current_register, boolean, skip), - position, - ); - - return Ok(()); - } - - if second_boolean.first_argument_as_boolean() == boolean { - let skip = second_boolean.second_argument_as_boolean(); - - self.emit_instruction( - Instruction::load_boolean(self.current_register, boolean, skip), - position, - ); - - return Ok(()); - } - - self.emit_instruction(first_boolean, first_position); - self.emit_instruction(second_boolean, second_position); - } - - let skip = previous_operations[0] == Some(Operation::Jump); - self.emit_instruction( - Instruction::load_boolean(self.current_register, boolean, skip), + Instruction::load_boolean(self.current_register, boolean, false), position, ); @@ -745,22 +709,13 @@ impl<'src> Parser<'src> { } fn parse_if(&mut self, allow_assignment: bool, allow_return: bool) -> Result<(), ParseError> { - let position = self.current_position; - self.advance()?; self.parse_expression()?; - let (mut condition, condition_position) = - self.chunk.pop_instruction(self.current_position)?; - - if let Operation::LoadBoolean = condition.operation() { - condition.set_second_argument_to_boolean(true); + if self.allow(TokenKind::LeftCurlyBrace)? { + self.parse_block(allow_assignment, allow_return)?; } - self.emit_instruction(condition, condition_position); - self.emit_instruction(Instruction::jump(1, true), condition_position); - self.parse_block(allow_assignment, allow_return)?; - let jump_position = self.current_position; let jump_start = self.current_register; let jump_index = self.chunk.len(); @@ -773,32 +728,16 @@ impl<'src> Parser<'src> { if self.allow(TokenKind::LeftCurlyBrace)? { self.parse_block(allow_assignment, allow_return)?; } - - return Err(ParseError::ExpectedTokenMultiple { - expected: &[TokenKind::If, TokenKind::LeftCurlyBrace], - found: self.current_token.to_owned(), - position: self.current_position, - }); } if let [Some(Operation::LoadBoolean), Some(Operation::LoadBoolean)] = self.chunk.get_last_n_operations() { - // Do not emit a jump if the last two instructions were LoadBoolean operations. However, - // we need to set them to the same destination register and decrement the register count. - - let (mut second_load_boolean, second_position) = - self.chunk.pop_instruction(self.current_position)?; - let (first_load_boolean, _) = self.chunk.get_previous().unwrap(); - - second_load_boolean.set_destination(first_load_boolean.destination()); - self.emit_instruction(second_load_boolean, second_position); - } else if let Some(Operation::LoadBoolean) = self.chunk.get_last_operation() { - let (mut load_boolean, position) = self.chunk.pop_instruction(self.current_position)?; - - load_boolean.set_second_argument_to_boolean(true); - - self.emit_instruction(load_boolean, position); + // Do not emit a jump if the last two instructions were LoadBoolean operations. + } else if let [Some(Operation::LoadConstant), Some(Operation::LoadConstant)] = + self.chunk.get_last_n_operations() + { + // Do not emit a jump if the last two instructions were LoadConstant operations. } else { let jump_end = self.current_register; let jump_distance = (jump_end - jump_start).max(1); diff --git a/dust-lang/src/parser/tests.rs b/dust-lang/src/parser/tests.rs index 3dd2c2c..3f0d13c 100644 --- a/dust-lang/src/parser/tests.rs +++ b/dust-lang/src/parser/tests.rs @@ -195,8 +195,8 @@ fn equality_assignment_long() { Span(13, 15) ), (Instruction::jump(1, true), Span(13, 15)), - (Instruction::load_boolean(0, true, true), Span(20, 24)), - (Instruction::load_boolean(0, false, false), Span(34, 39)), + (Instruction::load_boolean(0, true, true), Span(13, 15)), + (Instruction::load_boolean(0, false, false), Span(13, 15)), (Instruction::define_local(0, 0, false), Span(4, 5)), ], vec![Value::integer(4), Value::integer(4)], @@ -245,10 +245,10 @@ fn if_expression() { Span(5, 7) ), (Instruction::jump(1, true), Span(5, 7)), - (Instruction::load_constant(0, 2), Span(12, 13)), - (Instruction::jump(1, true), Span(5, 7)), + (Instruction::load_boolean(0, true, true), Span(5, 7)), + (Instruction::load_boolean(0, false, false), Span(5, 7)), ], - vec![Value::integer(1), Value::integer(1), Value::integer(2)], + vec![Value::integer(1), Value::integer(1)], vec![] )), ); @@ -269,16 +269,10 @@ fn if_else_expression() { Span(5, 7) ), (Instruction::jump(1, true), Span(5, 7)), - (Instruction::load_constant(0, 2), Span(12, 13)), - (Instruction::jump(1, true), Span(5, 7)), - (Instruction::load_constant(0, 3), Span(23, 24)), - ], - vec![ - Value::integer(1), - Value::integer(1), - Value::integer(2), - Value::integer(3) + (Instruction::load_boolean(0, true, true), Span(5, 7)), + (Instruction::load_boolean(0, false, false), Span(5, 7)), ], + vec![Value::integer(1), Value::integer(1)], vec![] )), ); diff --git a/dust-lang/tests/operations.rs b/dust-lang/tests/operations.rs index 3fa7649..b2fa42d 100644 --- a/dust-lang/tests/operations.rs +++ b/dust-lang/tests/operations.rs @@ -3,7 +3,10 @@ use dust_lang::*; #[test] fn if_expression() { assert_eq!(run("if true { 1 }"), Ok(Some(Value::integer(1)))); - assert_eq!(run("if false { 1 }"), Ok(None)); + assert_eq!( + run("if 42 == 42 { 1 } else { 2 }"), + Ok(Some(Value::integer(2))) + ); } #[test]