diff --git a/dust-lang/src/chunk/mod.rs b/dust-lang/src/chunk/mod.rs index 8f3c700..d29bdae 100644 --- a/dust-lang/src/chunk/mod.rs +++ b/dust-lang/src/chunk/mod.rs @@ -110,6 +110,7 @@ impl PartialEq for Chunk { self.name == other.name && self.r#type == other.r#type && self.instructions == other.instructions + && self.positions == other.positions && self.constants == other.constants && self.locals == other.locals && self.prototypes == other.prototypes diff --git a/dust-lang/src/compiler/mod.rs b/dust-lang/src/compiler/mod.rs index 0fca7aa..ae18555 100644 --- a/dust-lang/src/compiler/mod.rs +++ b/dust-lang/src/compiler/mod.rs @@ -280,9 +280,10 @@ impl<'src> Compiler<'src> { self.instructions .iter() .rev() - .find_map(|(instruction, _, _)| { - if instruction.operation() == Operation::LOAD_ENCODED - && instruction.b_type() == TypeCode::BYTE + .find_map(|(instruction, r#type, _)| { + if (r#type == &Type::Byte) + || (instruction.operation() == Operation::LOAD_ENCODED + && instruction.b_type() == TypeCode::BYTE) { return Some(instruction.a_field() + 1); } @@ -324,19 +325,24 @@ impl<'src> Compiler<'src> { } fn next_integer_register(&self) -> u16 { - self.instructions + println!("{:?}", self.instructions); + + let next = self + .instructions .iter() .rev() .find_map(|(instruction, r#type, _)| { - if r#type == &Type::Integer - || (instruction.b_type() == TypeCode::INTEGER && instruction.yields_value()) - { + if r#type == &Type::Integer { Some(instruction.a_field() + 1) } else { None } }) - .unwrap_or(self.minimum_integer_register) + .unwrap_or(self.minimum_integer_register); + + println!("{}", next); + + next } fn next_string_register(&self) -> u16 { @@ -580,7 +586,7 @@ impl<'src> Compiler<'src> { Type::Float => self.next_float_register(), Type::Integer => self.next_integer_register(), Type::String => self.next_string_register(), - _ => todo!(), + _ => unreachable!(), }; let load_constant = Instruction::load_constant(destination, constant_index, r#type.type_code(), false); diff --git a/dust-lang/tests/math/add.rs b/dust-lang/tests/math/add.rs index cc7dca3..8689b6b 100644 --- a/dust-lang/tests/math/add.rs +++ b/dust-lang/tests/math/add.rs @@ -27,6 +27,51 @@ fn add_bytes() { assert_eq!(return_value, run(source).unwrap()); } +#[test] +fn add_many_bytes() { + let source = "0x28 + 0x02 + 0x02 + 0x02"; + let chunk = Chunk { + r#type: FunctionType::new([], [], Type::Byte), + instructions: vec![ + Instruction::load_encoded(0, 40, TypeCode::BYTE, false), + Instruction::load_encoded(1, 2, TypeCode::BYTE, false), + Instruction::add( + 2, + Operand::Register(0, TypeCode::BYTE), + Operand::Register(1, TypeCode::BYTE), + ), + Instruction::load_encoded(3, 2, TypeCode::BYTE, false), + Instruction::add( + 4, + Operand::Register(2, TypeCode::BYTE), + Operand::Register(3, TypeCode::BYTE), + ), + Instruction::load_encoded(5, 2, TypeCode::BYTE, false), + Instruction::add( + 6, + Operand::Register(4, TypeCode::BYTE), + Operand::Register(5, TypeCode::BYTE), + ), + Instruction::r#return(true, 6, TypeCode::BYTE), + ], + positions: vec![ + Span(0, 4), + Span(7, 11), + Span(5, 6), + Span(14, 18), + Span(12, 13), + Span(21, 25), + Span(19, 20), + Span(25, 25), + ], + ..Chunk::default() + }; + let return_value = Some(Value::byte(46)); + + assert_eq!(chunk, compile(source).unwrap()); + assert_eq!(return_value, run(source).unwrap()); +} + #[test] fn add_characters() { let source = "'a' + 'b'"; @@ -63,7 +108,7 @@ fn add_floats() { ), Instruction::r#return(true, 0, TypeCode::FLOAT), ], - positions: vec![Span(0, 4), Span(7, 11), Span(5, 6), Span(11, 11)], + positions: vec![Span(5, 6), Span(12, 12)], constants: vec![ConcreteValue::Float(2.40), ConcreteValue::Float(40.02)], ..Chunk::default() }; @@ -86,7 +131,7 @@ fn add_integers() { ), Instruction::r#return(true, 0, TypeCode::INTEGER), ], - positions: vec![Span(3, 4), Span(7, 7)], + positions: vec![Span(3, 4), Span(6, 6)], constants: vec![ConcreteValue::Integer(40), ConcreteValue::Integer(2)], ..Chunk::default() }; @@ -109,7 +154,7 @@ fn add_strings() { ), Instruction::r#return(true, 0, TypeCode::STRING), ], - positions: vec![Span(0, 8), Span(11, 18), Span(9, 10), Span(19, 25)], + positions: vec![Span(10, 11), Span(20, 20)], constants: vec![ ConcreteValue::String(DustString::from("Hello, ")), ConcreteValue::String(DustString::from("World!")), diff --git a/dust-lang/tests/values.rs b/dust-lang/tests/values.rs index 14fc2d6..ea0d1e6 100644 --- a/dust-lang/tests/values.rs +++ b/dust-lang/tests/values.rs @@ -48,7 +48,7 @@ fn load_byte() { Instruction::load_encoded(0, 0x2a, TypeCode::BYTE, false), Instruction::r#return(true, 0, TypeCode::BYTE), ], - positions: vec![Span(0, 6), Span(6, 6)], + positions: vec![Span(0, 4), Span(4, 4)], ..Chunk::default() }; let return_value = Some(Value::byte(0x2a)); @@ -85,7 +85,7 @@ fn load_float() { Instruction::load_constant(0, 0, TypeCode::FLOAT, false), Instruction::r#return(true, 0, TypeCode::FLOAT), ], - positions: vec![Span(0, 4), Span(4, 4)], + positions: vec![Span(0, 5), Span(5, 5)], constants: vec![ConcreteValue::Float(42.42)], ..Chunk::default() }; @@ -144,7 +144,7 @@ fn load_boolean_list() { Instruction::load_list(0, TypeCode::BOOLEAN, 0, 1, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 13), Span(13, 13)], + positions: vec![Span(1, 5), Span(7, 12), Span(0, 13), Span(13, 13)], ..Chunk::default() }; let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ @@ -167,7 +167,7 @@ fn load_byte_list() { Instruction::load_list(0, TypeCode::BYTE, 0, 1, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 15), Span(15, 15)], + positions: vec![Span(1, 5), Span(7, 11), Span(0, 12), Span(12, 12)], ..Chunk::default() }; let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ @@ -190,7 +190,7 @@ fn load_character_list() { Instruction::load_list(0, TypeCode::CHARACTER, 0, 1, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 9), Span(9, 9)], + positions: vec![Span(1, 4), Span(6, 9), Span(0, 10), Span(10, 10)], constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')], ..Chunk::default() }; @@ -214,7 +214,7 @@ fn load_float_list() { Instruction::load_list(0, TypeCode::FLOAT, 0, 1, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 15), Span(15, 15)], + positions: vec![Span(1, 6), Span(8, 13), Span(0, 14), Span(14, 14)], constants: vec![ConcreteValue::Float(42.42), ConcreteValue::Float(24.24)], ..Chunk::default() }; @@ -239,7 +239,7 @@ fn load_integer_list() { Instruction::load_list(0, TypeCode::INTEGER, 0, 2, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 9), Span(9, 9)], + positions: vec![Span(1, 2), Span(4, 5), Span(7, 8), Span(0, 9), Span(9, 9)], constants: vec![ ConcreteValue::Integer(1), ConcreteValue::Integer(2), @@ -268,7 +268,7 @@ fn load_string_list() { Instruction::load_list(0, TypeCode::STRING, 0, 1, false), Instruction::r#return(true, 0, TypeCode::LIST), ], - positions: vec![Span(0, 19), Span(19, 19)], + positions: vec![Span(1, 8), Span(10, 17), Span(0, 18), Span(18, 18)], constants: vec![ ConcreteValue::String(DustString::from("Hello")), ConcreteValue::String(DustString::from("World")), @@ -359,7 +359,7 @@ fn load_deeply_nested_list() { Span(14, 15), Span(10, 16), Span(1, 17), - Span(17, 18), + Span(19, 20), Span(21, 22), Span(24, 25), Span(20, 26),