Add repeat until

This commit is contained in:
Sofia 2026-03-19 21:36:05 +02:00
parent 42164ef6fe
commit 50e826061b
3 changed files with 27 additions and 4 deletions

View File

@ -1,8 +1,8 @@
local i = 0 local i = 0
print("before") print("before")
while i < 10 do repeat
i = i + 1 i = i + 1
print(i) print(i)
end until i >= 10
print("after") print("after")

View File

@ -238,6 +238,7 @@ impl Parse for Block {
Token::Keyword(Keyword::End) Token::Keyword(Keyword::End)
| Token::Keyword(Keyword::ElseIf) | Token::Keyword(Keyword::ElseIf)
| Token::Keyword(Keyword::Else) | Token::Keyword(Keyword::Else)
| Token::Keyword(Keyword::Until)
| Token::Eof | Token::Eof
) )
) { ) {

View File

@ -491,7 +491,9 @@ impl Statement {
0, 0,
))); )));
let block_instructions = block.compile(state, scope); let mut inner_scope = scope.clone();
let block_instructions = block.compile(state, &mut inner_scope);
let block_instr_len = block_instructions.len() as i32; let block_instr_len = block_instructions.len() as i32;
instructions.push(PreInstr::Instr(Instruction::Jmp(block_instr_len + 1))); instructions.push(PreInstr::Instr(Instruction::Jmp(block_instr_len + 1)));
@ -501,7 +503,27 @@ impl Statement {
-(block_instr_len + expr_instr_len + 2), -(block_instr_len + expr_instr_len + 2),
))); )));
} }
Statement::Repeat(block, expr) => todo!(), Statement::Repeat(block, expr) => {
let mut inner_scope = scope.clone();
let block_instructions = block.compile(state, &mut inner_scope);
let block_instr_len = block_instructions.len() as i32;
instructions.extend(block_instructions);
let (instr, expr_regs) = expr.kind.compile(state, scope, Some(1));
let expr_instr_len = instr.len() as i32;
instructions.extend(instr);
instructions.push(PreInstr::Instr(Instruction::Test(
scope.register_counter.next(),
*expr_regs.first().unwrap(),
0,
)));
instructions.push(PreInstr::Instr(Instruction::Jmp(
-(block_instr_len + expr_instr_len + 2),
)));
}
Statement::Break => instructions.push(PreInstr::Break), Statement::Break => instructions.push(PreInstr::Break),
Statement::Label(node) => instructions.push(PreInstr::Label(node.kind.clone())), Statement::Label(node) => instructions.push(PreInstr::Label(node.kind.clone())),
Statement::GoTo(node) => instructions.push(PreInstr::GoTo(node.kind.clone())), Statement::GoTo(node) => instructions.push(PreInstr::GoTo(node.kind.clone())),