diff --git a/examples/test.lua b/examples/test.lua index 2a7fe67..12a744f 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -42,4 +42,7 @@ global value, table = f(10, 11, 12) print("hello") for i=1,#table do print(table[i]) + if i > 2 then + break + end end \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index c9d87b8..f2fd157 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -263,6 +263,7 @@ pub enum Statement { Node, Block, ), + Break, } impl Parse for Statement { @@ -354,6 +355,9 @@ impl Parse for Statement { )) } else if let Ok(expr) = stream.parse() { Ok(Self::Expression(expr)) + } else if let Some(Token::Keyword(Keyword::Break)) = stream.peek() { + stream.next(); + Ok(Self::Break) } else { Err(stream.expecting_err("statement")) } diff --git a/src/compile.rs b/src/compile.rs index 1f3ea5a..04055b4 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -179,6 +179,7 @@ impl Statement { constants.extend(block.find_constants(scope, Vec::new())); constants } + Statement::Break => HashSet::new(), } } @@ -417,13 +418,20 @@ impl Statement { let instr_len = instr.len() as i32; instructions.push(PreInstr::Instr(Instruction::Jmp(instr_len + 2))); - instructions.extend(instr); + for (i, pre_instr) in instr.into_iter().enumerate() { + match pre_instr { + PreInstr::Break => instructions + .push(PreInstr::Instr(Instruction::Jmp(instr_len - i as i32 + 1))), + _ => instructions.push(pre_instr), + } + } instructions.push(PreInstr::Instr(Instruction::Add( *init_reg, *init_reg, *step_reg, ))); instructions.push(PreInstr::Instr(Instruction::Jmp(-(instr_len + 4)))); } + Statement::Break => instructions.push(PreInstr::Break), } for reg in 0..scope.register_counter.0 { diff --git a/src/token_stream/lexer.rs b/src/token_stream/lexer.rs index cada511..de85d74 100644 --- a/src/token_stream/lexer.rs +++ b/src/token_stream/lexer.rs @@ -22,6 +22,7 @@ pub enum Keyword { Not, For, Do, + Break, } impl Keyword { @@ -40,6 +41,7 @@ impl Keyword { "not" => Keyword::Not, "for" => Keyword::For, "do" => Keyword::Do, + "break" => Keyword::Break, _ => None?, }) } @@ -61,6 +63,7 @@ impl ToString for Keyword { Keyword::Not => "not", Keyword::For => "for", Keyword::Do => "do", + Keyword::Break => "break", } .to_string() }