1
0

Add move instruction to fix assignment to conditionals

This commit is contained in:
Jeff 2024-11-01 02:51:18 -04:00
parent 32ff52d9b3
commit 7e4f6654a4
3 changed files with 81 additions and 1 deletions

View File

@ -1003,11 +1003,21 @@ impl<'src> Parser<'src> {
if let Token::Else = self.current_token {
let else_start = self.chunk.len();
let if_last_register = self.next_register().saturating_sub(1);
self.parse_else(allowed, block_allowed)?;
let else_last_register = self.next_register().saturating_sub(1);
let else_end = self.chunk.len();
let jump_distance = (else_end - else_start) as u8;
if if_last_register < else_last_register {
self.emit_instruction(
Instruction::r#move(else_last_register, if_last_register),
self.current_position,
);
}
self.current_is_expression = if_block_is_expression
&& self
.chunk

View File

@ -65,7 +65,12 @@ impl Vm {
);
match instruction.operation() {
Operation::Move => todo!(),
Operation::Move => {
let to_register = instruction.a();
let from_register = instruction.b();
self.set_pointer(to_register, from_register, position)?;
}
Operation::Close => {
let from_register = instruction.b();
let to_register = instruction.c();

View File

@ -60,6 +60,70 @@ fn equality_assignment_short() {
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
}
#[test]
fn if_else_assigment() {
let source = r#"
let a = if 4 == 4 {
1; 2; 3; 4;
42
} else {
1; 2; 3; 4;
panic()
};
a"#;
assert_eq!(
parse(source),
Ok(Chunk::with_data(
None,
vec![
(
*Instruction::equal(true, 0, 1)
.set_b_is_constant()
.set_c_is_constant(),
Span(22, 24)
),
(Instruction::jump(5, true), Span(22, 24)),
(Instruction::load_constant(0, 2, false), Span(41, 42)),
(Instruction::load_constant(1, 3, false), Span(44, 45)),
(Instruction::load_constant(2, 4, false), Span(47, 48)),
(Instruction::load_constant(3, 5, false), Span(50, 51)),
(Instruction::load_constant(4, 6, false), Span(65, 67)),
(Instruction::jump(6, true), Span(138, 139)),
(Instruction::jump(5, true), Span(138, 139)),
(Instruction::load_constant(5, 7, false), Span(97, 98)),
(Instruction::load_constant(6, 8, false), Span(100, 101)),
(Instruction::load_constant(7, 9, false), Span(103, 104)),
(Instruction::load_constant(8, 10, false), Span(106, 107)),
(
Instruction::call_native(9, NativeFunction::Panic, 0),
Span(121, 128)
),
(Instruction::r#move(8, 4), Span(138, 139)),
(Instruction::define_local(8, 0, false), Span(13, 14)),
(Instruction::get_local(9, 0), Span(148, 149)),
(Instruction::r#return(true), Span(149, 149)),
],
vec![
Value::integer(4),
Value::integer(4),
Value::integer(1),
Value::integer(2),
Value::integer(3),
Value::integer(4),
Value::integer(42),
Value::integer(1),
Value::integer(2),
Value::integer(3),
Value::integer(4),
],
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
)),
);
assert_eq!(run(source), Ok(Some(Value::integer(42))));
}
#[test]
fn if_else_complex() {
let source = "
@ -91,6 +155,7 @@ fn if_else_complex() {
(Instruction::load_constant(5, 7, false), Span(77, 78)),
(Instruction::load_constant(6, 8, false), Span(80, 81)),
(Instruction::load_constant(7, 9, false), Span(83, 84)),
(Instruction::r#move(7, 3), Span(95, 95)),
(Instruction::r#return(true), Span(95, 95)),
],
vec![