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)
|
||||
}
|
||||
|
||||
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
|
||||
.instructions_mut()
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.skip(minimum)
|
||||
.take(maximum)
|
||||
.find_map(|(instruction, _)| {
|
||||
if let Operation::LoadBoolean | Operation::LoadConstant = instruction.operation() {
|
||||
Some(instruction)
|
||||
@ -1124,7 +1130,7 @@ impl<'src> Compiler<'src> {
|
||||
let if_block_type = self.previous_expression_type.clone();
|
||||
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()?;
|
||||
|
||||
if let Token::LeftBrace = self.current_token {
|
||||
@ -1158,8 +1164,10 @@ impl<'src> Compiler<'src> {
|
||||
|
||||
match else_block_distance {
|
||||
0 => {}
|
||||
1 if !has_else_statement => {
|
||||
if let Some(skippable) = self.get_last_jumpable_mut() {
|
||||
1 => {
|
||||
if let Some(skippable) =
|
||||
self.get_last_jumpable_mut_between(1, if_block_distance as usize)
|
||||
{
|
||||
skippable.set_c_to_boolean(true);
|
||||
} else {
|
||||
if_block_distance += 1;
|
||||
@ -1173,7 +1181,6 @@ impl<'src> Compiler<'src> {
|
||||
);
|
||||
}
|
||||
}
|
||||
1 => {}
|
||||
2.. => {
|
||||
if_block_distance += 1;
|
||||
|
||||
|
@ -333,18 +333,20 @@ fn if_else_false() {
|
||||
.set_c_is_constant(),
|
||||
Span(5, 7)
|
||||
),
|
||||
(Instruction::jump(1, true), Span(10, 11)),
|
||||
(Instruction::jump(2, true), Span(10, 11)),
|
||||
(
|
||||
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||
Span(12, 19)
|
||||
),
|
||||
(Instruction::load_constant(1, 2, true), Span(29, 31)),
|
||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
||||
(Instruction::r#return(true), Span(33, 33)),
|
||||
(Instruction::load_constant(0, 2, true), Span(21, 22)),
|
||||
(Instruction::load_constant(1, 3, false), Span(32, 34)),
|
||||
(Instruction::r#move(1, 0), Span(36, 36)),
|
||||
(Instruction::r#return(true), Span(36, 36)),
|
||||
],
|
||||
vec![
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(0),
|
||||
ConcreteValue::Integer(42)
|
||||
],
|
||||
vec![]
|
||||
@ -374,16 +376,22 @@ fn if_else_true() {
|
||||
.set_c_is_constant(),
|
||||
Span(5, 7)
|
||||
),
|
||||
(Instruction::jump(1, true), Span(10, 11)),
|
||||
(Instruction::load_constant(0, 1, true), Span(12, 14)),
|
||||
(Instruction::jump(2, true), Span(10, 11)),
|
||||
(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)
|
||||
),
|
||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
||||
(Instruction::r#return(true), Span(33, 33))
|
||||
(Instruction::load_constant(1, 2, false), Span(33, 34)),
|
||||
(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![]
|
||||
)),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user