From 00f35bd3aec61bd0bc7c6f506cf4d8f6015eff33 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 11 Feb 2025 06:44:26 -0500 Subject: [PATCH] Bring back the assignment error tests --- dust-lang/Cargo.toml | 4 + dust-lang/src/compiler/mod.rs | 51 +++++++----- .../compiler_errors/assignment_errors.rs | 81 +++++++++++++++++++ 3 files changed, 116 insertions(+), 20 deletions(-) create mode 100644 dust-lang/tests/compiler_errors/assignment_errors.rs diff --git a/dust-lang/Cargo.toml b/dust-lang/Cargo.toml index 66826f0..810d1c6 100644 --- a/dust-lang/Cargo.toml +++ b/dust-lang/Cargo.toml @@ -106,3 +106,7 @@ path = "tests/logic/and_or.rs" [[test]] name = "or_and" path = "tests/logic/or_and.rs" + +[[test]] +name = "assignment_errors" +path = "tests/compiler_errors/assignment_errors.rs" diff --git a/dust-lang/src/compiler/mod.rs b/dust-lang/src/compiler/mod.rs index 99235bb..09214e9 100644 --- a/dust-lang/src/compiler/mod.rs +++ b/dust-lang/src/compiler/mod.rs @@ -1239,7 +1239,6 @@ impl<'src> Compiler<'src> { let mut item_type = Type::None; let mut start_register = None; - let mut close_instructions = Vec::new(); while !self.allow(Token::RightBracket)? { let next_boolean_register = self.next_boolean_register(); @@ -1271,22 +1270,26 @@ impl<'src> Compiler<'src> { self.next_boolean_register() - next_boolean_register; if used_boolean_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_boolean_register, self.next_boolean_register() - 2, TypeCode::BOOLEAN, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::Byte => { let used_byte_registers = self.next_byte_register() - next_byte_register; if used_byte_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_byte_register, self.next_byte_register() - 2, TypeCode::BYTE, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::Character => { @@ -1294,22 +1297,26 @@ impl<'src> Compiler<'src> { self.next_character_register() - next_character_register; if used_character_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_character_register, - self.next_byte_register() - 2, + self.next_character_register() - 2, TypeCode::CHARACTER, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::Float => { let used_float_registers = self.next_float_register() - next_float_register; if used_float_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_float_register, self.next_float_register() - 2, TypeCode::FLOAT, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::Integer => { @@ -1317,33 +1324,39 @@ impl<'src> Compiler<'src> { self.next_integer_register() - next_integer_register; if used_integer_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_integer_register, self.next_integer_register() - 2, TypeCode::INTEGER, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::String => { let used_string_registers = self.next_string_register() - next_string_register; if used_string_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_string_register, self.next_string_register() - 2, TypeCode::STRING, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } Type::List { .. } => { let used_list_registers = self.next_list_register() - next_list_register; if used_list_registers > 1 { - close_instructions.push(Instruction::close( + let close = Instruction::close( next_list_register, self.next_list_register() - 2, TypeCode::LIST, - )); + ); + + self.emit_instruction(close, Type::None, self.current_position); } } _ => unimplemented!(), @@ -1371,10 +1384,8 @@ impl<'src> Compiler<'src> { ); let list_length = end_register - start_register.unwrap_or(0) + 1; - if list_length > 1 { - for close_instruction in close_instructions { - self.emit_instruction(close_instruction, item_type.clone(), Span(start, end)); - } + if list_length == 1 && self.get_last_operation() == Some(Operation::CLOSE) { + self.instructions.pop(); } self.emit_instruction( diff --git a/dust-lang/tests/compiler_errors/assignment_errors.rs b/dust-lang/tests/compiler_errors/assignment_errors.rs new file mode 100644 index 0000000..a117612 --- /dev/null +++ b/dust-lang/tests/compiler_errors/assignment_errors.rs @@ -0,0 +1,81 @@ +use dust_lang::*; + +#[test] +fn add_assign_expects_mutable_variable() { + let source = "1 += 2"; + + assert_eq!( + compile(source), + Err(DustError::Compile { + error: CompileError::ExpectedMutableVariable { + found: Token::Integer("1").to_owned(), + position: Span(0, 1) + }, + source + }) + ); +} + +#[test] +fn divide_assign_expects_mutable_variable() { + let source = "1 -= 2"; + + assert_eq!( + compile(source), + Err(DustError::Compile { + error: CompileError::ExpectedMutableVariable { + found: Token::Integer("1").to_owned(), + position: Span(0, 1) + }, + source + }) + ); +} + +#[test] +fn multiply_assign_expects_mutable_variable() { + let source = "1 *= 2"; + + assert_eq!( + compile(source), + Err(DustError::Compile { + error: CompileError::ExpectedMutableVariable { + found: Token::Integer("1").to_owned(), + position: Span(0, 1) + }, + source + }) + ); +} + +#[test] +fn subtract_assign_expects_mutable_variable() { + let source = "1 -= 2"; + + assert_eq!( + compile(source), + Err(DustError::Compile { + error: CompileError::ExpectedMutableVariable { + found: Token::Integer("1").to_owned(), + position: Span(0, 1) + }, + source + }) + ); +} + +#[test] +fn modulo_assign_expects_mutable_variable() { + let source = "1 %= 2"; + + assert_eq!( + compile(source), + Err(DustError::Compile { + error: CompileError::ExpectedMutableVariable { + found: Token::Integer("1").to_owned(), + position: Span(0, 1) + }, + source + }) + ); +}