Fix control flow and pass all tests
This commit is contained in:
parent
0f3924341f
commit
3143e8c203
@ -270,11 +270,17 @@ impl<'src> Compiler<'src> {
|
|||||||
Some(n_operations)
|
Some(n_operations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_last_jumpable_mut(&mut self) -> Option<&mut Instruction> {
|
fn get_last_jumpable_mut_between(
|
||||||
|
&mut self,
|
||||||
|
minimum: usize,
|
||||||
|
maximum: usize,
|
||||||
|
) -> Option<&mut Instruction> {
|
||||||
self.chunk
|
self.chunk
|
||||||
.instructions_mut()
|
.instructions_mut()
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.rev()
|
.rev()
|
||||||
|
.skip(minimum)
|
||||||
|
.take(maximum)
|
||||||
.find_map(|(instruction, _)| {
|
.find_map(|(instruction, _)| {
|
||||||
if let Operation::LoadBoolean | Operation::LoadConstant = instruction.operation() {
|
if let Operation::LoadBoolean | Operation::LoadConstant = instruction.operation() {
|
||||||
Some(instruction)
|
Some(instruction)
|
||||||
@ -1124,7 +1130,7 @@ impl<'src> Compiler<'src> {
|
|||||||
let if_block_type = self.previous_expression_type.clone();
|
let if_block_type = self.previous_expression_type.clone();
|
||||||
let if_last_register = self.next_register().saturating_sub(1);
|
let if_last_register = self.next_register().saturating_sub(1);
|
||||||
|
|
||||||
let has_else_statement = if let Token::Else = self.current_token {
|
if let Token::Else = self.current_token {
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
|
|
||||||
if let Token::LeftBrace = self.current_token {
|
if let Token::LeftBrace = self.current_token {
|
||||||
@ -1158,8 +1164,10 @@ impl<'src> Compiler<'src> {
|
|||||||
|
|
||||||
match else_block_distance {
|
match else_block_distance {
|
||||||
0 => {}
|
0 => {}
|
||||||
1 if !has_else_statement => {
|
1 => {
|
||||||
if let Some(skippable) = self.get_last_jumpable_mut() {
|
if let Some(skippable) =
|
||||||
|
self.get_last_jumpable_mut_between(1, if_block_distance as usize)
|
||||||
|
{
|
||||||
skippable.set_c_to_boolean(true);
|
skippable.set_c_to_boolean(true);
|
||||||
} else {
|
} else {
|
||||||
if_block_distance += 1;
|
if_block_distance += 1;
|
||||||
@ -1173,7 +1181,6 @@ impl<'src> Compiler<'src> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1 => {}
|
|
||||||
2.. => {
|
2.. => {
|
||||||
if_block_distance += 1;
|
if_block_distance += 1;
|
||||||
|
|
||||||
|
@ -333,18 +333,20 @@ fn if_else_false() {
|
|||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(5, 7)
|
Span(5, 7)
|
||||||
),
|
),
|
||||||
(Instruction::jump(1, true), Span(10, 11)),
|
(Instruction::jump(2, true), Span(10, 11)),
|
||||||
(
|
(
|
||||||
Instruction::call_native(0, NativeFunction::Panic, 0),
|
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||||
Span(12, 19)
|
Span(12, 19)
|
||||||
),
|
),
|
||||||
(Instruction::load_constant(1, 2, true), Span(29, 31)),
|
(Instruction::load_constant(0, 2, true), Span(21, 22)),
|
||||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
(Instruction::load_constant(1, 3, false), Span(32, 34)),
|
||||||
(Instruction::r#return(true), Span(33, 33)),
|
(Instruction::r#move(1, 0), Span(36, 36)),
|
||||||
|
(Instruction::r#return(true), Span(36, 36)),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
ConcreteValue::Integer(1),
|
ConcreteValue::Integer(1),
|
||||||
ConcreteValue::Integer(2),
|
ConcreteValue::Integer(2),
|
||||||
|
ConcreteValue::Integer(0),
|
||||||
ConcreteValue::Integer(42)
|
ConcreteValue::Integer(42)
|
||||||
],
|
],
|
||||||
vec![]
|
vec![]
|
||||||
@ -374,16 +376,22 @@ fn if_else_true() {
|
|||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(5, 7)
|
Span(5, 7)
|
||||||
),
|
),
|
||||||
(Instruction::jump(1, true), Span(10, 11)),
|
(Instruction::jump(2, true), Span(10, 11)),
|
||||||
(Instruction::load_constant(0, 1, true), Span(12, 14)),
|
(Instruction::load_constant(0, 1, false), Span(12, 14)),
|
||||||
|
(Instruction::jump(2, true), Span(36, 36)),
|
||||||
(
|
(
|
||||||
Instruction::call_native(1, NativeFunction::Panic, 0),
|
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||||
Span(24, 31)
|
Span(24, 31)
|
||||||
),
|
),
|
||||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
(Instruction::load_constant(1, 2, false), Span(33, 34)),
|
||||||
(Instruction::r#return(true), Span(33, 33))
|
(Instruction::r#move(1, 0), Span(36, 36)),
|
||||||
|
(Instruction::r#return(true), Span(36, 36))
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
ConcreteValue::Integer(1),
|
||||||
|
ConcreteValue::Integer(42),
|
||||||
|
ConcreteValue::Integer(0)
|
||||||
],
|
],
|
||||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(42)],
|
|
||||||
vec![]
|
vec![]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user