Fix bugs and pass tests
This commit is contained in:
parent
e53ecd93fe
commit
e19ddbe2f3
@ -110,6 +110,7 @@ impl PartialEq for Chunk {
|
|||||||
self.name == other.name
|
self.name == other.name
|
||||||
&& self.r#type == other.r#type
|
&& self.r#type == other.r#type
|
||||||
&& self.instructions == other.instructions
|
&& self.instructions == other.instructions
|
||||||
|
&& self.positions == other.positions
|
||||||
&& self.constants == other.constants
|
&& self.constants == other.constants
|
||||||
&& self.locals == other.locals
|
&& self.locals == other.locals
|
||||||
&& self.prototypes == other.prototypes
|
&& self.prototypes == other.prototypes
|
||||||
|
@ -280,9 +280,10 @@ impl<'src> Compiler<'src> {
|
|||||||
self.instructions
|
self.instructions
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find_map(|(instruction, _, _)| {
|
.find_map(|(instruction, r#type, _)| {
|
||||||
if instruction.operation() == Operation::LOAD_ENCODED
|
if (r#type == &Type::Byte)
|
||||||
&& instruction.b_type() == TypeCode::BYTE
|
|| (instruction.operation() == Operation::LOAD_ENCODED
|
||||||
|
&& instruction.b_type() == TypeCode::BYTE)
|
||||||
{
|
{
|
||||||
return Some(instruction.a_field() + 1);
|
return Some(instruction.a_field() + 1);
|
||||||
}
|
}
|
||||||
@ -324,19 +325,24 @@ impl<'src> Compiler<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn next_integer_register(&self) -> u16 {
|
fn next_integer_register(&self) -> u16 {
|
||||||
self.instructions
|
println!("{:?}", self.instructions);
|
||||||
|
|
||||||
|
let next = self
|
||||||
|
.instructions
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find_map(|(instruction, r#type, _)| {
|
.find_map(|(instruction, r#type, _)| {
|
||||||
if r#type == &Type::Integer
|
if r#type == &Type::Integer {
|
||||||
|| (instruction.b_type() == TypeCode::INTEGER && instruction.yields_value())
|
|
||||||
{
|
|
||||||
Some(instruction.a_field() + 1)
|
Some(instruction.a_field() + 1)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or(self.minimum_integer_register)
|
.unwrap_or(self.minimum_integer_register);
|
||||||
|
|
||||||
|
println!("{}", next);
|
||||||
|
|
||||||
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_string_register(&self) -> u16 {
|
fn next_string_register(&self) -> u16 {
|
||||||
@ -580,7 +586,7 @@ impl<'src> Compiler<'src> {
|
|||||||
Type::Float => self.next_float_register(),
|
Type::Float => self.next_float_register(),
|
||||||
Type::Integer => self.next_integer_register(),
|
Type::Integer => self.next_integer_register(),
|
||||||
Type::String => self.next_string_register(),
|
Type::String => self.next_string_register(),
|
||||||
_ => todo!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let load_constant =
|
let load_constant =
|
||||||
Instruction::load_constant(destination, constant_index, r#type.type_code(), false);
|
Instruction::load_constant(destination, constant_index, r#type.type_code(), false);
|
||||||
|
@ -27,6 +27,51 @@ fn add_bytes() {
|
|||||||
assert_eq!(return_value, run(source).unwrap());
|
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]
|
#[test]
|
||||||
fn add_characters() {
|
fn add_characters() {
|
||||||
let source = "'a' + 'b'";
|
let source = "'a' + 'b'";
|
||||||
@ -63,7 +108,7 @@ fn add_floats() {
|
|||||||
),
|
),
|
||||||
Instruction::r#return(true, 0, TypeCode::FLOAT),
|
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)],
|
constants: vec![ConcreteValue::Float(2.40), ConcreteValue::Float(40.02)],
|
||||||
..Chunk::default()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
@ -86,7 +131,7 @@ fn add_integers() {
|
|||||||
),
|
),
|
||||||
Instruction::r#return(true, 0, TypeCode::INTEGER),
|
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)],
|
constants: vec![ConcreteValue::Integer(40), ConcreteValue::Integer(2)],
|
||||||
..Chunk::default()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
@ -109,7 +154,7 @@ fn add_strings() {
|
|||||||
),
|
),
|
||||||
Instruction::r#return(true, 0, TypeCode::STRING),
|
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![
|
constants: vec![
|
||||||
ConcreteValue::String(DustString::from("Hello, ")),
|
ConcreteValue::String(DustString::from("Hello, ")),
|
||||||
ConcreteValue::String(DustString::from("World!")),
|
ConcreteValue::String(DustString::from("World!")),
|
||||||
|
@ -48,7 +48,7 @@ fn load_byte() {
|
|||||||
Instruction::load_encoded(0, 0x2a, TypeCode::BYTE, false),
|
Instruction::load_encoded(0, 0x2a, TypeCode::BYTE, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::BYTE),
|
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()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
let return_value = Some(Value::byte(0x2a));
|
let return_value = Some(Value::byte(0x2a));
|
||||||
@ -85,7 +85,7 @@ fn load_float() {
|
|||||||
Instruction::load_constant(0, 0, TypeCode::FLOAT, false),
|
Instruction::load_constant(0, 0, TypeCode::FLOAT, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::FLOAT),
|
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)],
|
constants: vec![ConcreteValue::Float(42.42)],
|
||||||
..Chunk::default()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
@ -144,7 +144,7 @@ fn load_boolean_list() {
|
|||||||
Instruction::load_list(0, TypeCode::BOOLEAN, 0, 1, false),
|
Instruction::load_list(0, TypeCode::BOOLEAN, 0, 1, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
|
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::load_list(0, TypeCode::BYTE, 0, 1, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
|
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::load_list(0, TypeCode::CHARACTER, 0, 1, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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')],
|
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||||
..Chunk::default()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
@ -214,7 +214,7 @@ fn load_float_list() {
|
|||||||
Instruction::load_list(0, TypeCode::FLOAT, 0, 1, false),
|
Instruction::load_list(0, TypeCode::FLOAT, 0, 1, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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)],
|
constants: vec![ConcreteValue::Float(42.42), ConcreteValue::Float(24.24)],
|
||||||
..Chunk::default()
|
..Chunk::default()
|
||||||
};
|
};
|
||||||
@ -239,7 +239,7 @@ fn load_integer_list() {
|
|||||||
Instruction::load_list(0, TypeCode::INTEGER, 0, 2, false),
|
Instruction::load_list(0, TypeCode::INTEGER, 0, 2, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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![
|
constants: vec![
|
||||||
ConcreteValue::Integer(1),
|
ConcreteValue::Integer(1),
|
||||||
ConcreteValue::Integer(2),
|
ConcreteValue::Integer(2),
|
||||||
@ -268,7 +268,7 @@ fn load_string_list() {
|
|||||||
Instruction::load_list(0, TypeCode::STRING, 0, 1, false),
|
Instruction::load_list(0, TypeCode::STRING, 0, 1, false),
|
||||||
Instruction::r#return(true, 0, TypeCode::LIST),
|
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![
|
constants: vec![
|
||||||
ConcreteValue::String(DustString::from("Hello")),
|
ConcreteValue::String(DustString::from("Hello")),
|
||||||
ConcreteValue::String(DustString::from("World")),
|
ConcreteValue::String(DustString::from("World")),
|
||||||
@ -359,7 +359,7 @@ fn load_deeply_nested_list() {
|
|||||||
Span(14, 15),
|
Span(14, 15),
|
||||||
Span(10, 16),
|
Span(10, 16),
|
||||||
Span(1, 17),
|
Span(1, 17),
|
||||||
Span(17, 18),
|
Span(19, 20),
|
||||||
Span(21, 22),
|
Span(21, 22),
|
||||||
Span(24, 25),
|
Span(24, 25),
|
||||||
Span(20, 26),
|
Span(20, 26),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user