From 4c9b9085fd126ccf77adbd8a14644a4925538fa0 Mon Sep 17 00:00:00 2001 From: Sofia Date: Thu, 19 Mar 2026 17:46:47 +0200 Subject: [PATCH] Add if/elseif/else --- examples/test.lua | 51 ++++++++++++++++++++++++++++++++++++++++++++++- src/ast.rs | 26 +++++++++++++++++------- src/compile.rs | 7 ------- src/lib.rs | 2 +- 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/examples/test.lua b/examples/test.lua index d569215..8a11c15 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -1,5 +1,54 @@ +global b = 5 -local test = 11 +function add(x) + return function (y) + x = x + 1 + b = b + 1 + return x + y, 1, 2, b + end +end + +function min(x, y) + local m = x + if y < x then + m = y + end + return m +end + + +function f(x, ...) + local b = {10, ..., add(10)(15)} + return x + 5, b +end + +global sometable = {} +sometable["hello"] = { 100, 150, add(10)(15) } +print(#sometable["hello"]) +sometable["hello"].there = "my dude" +print(sometable.hello.there) + +print(max(11.12345, 9)) +print(add(10)(15)) +print(add(10)(15)) +print(b) +print(min(11, 9)) +print(10 - 15) +print("hello there!") +print(true or 0) + +global value, table = f(10, 11, 12) + +print("hello") +for i=1,#table do + print(table[i]) + if i > 2 then + goto test + end +end +::test:: + +local test = table[1] if test == 10 then print("first") elseif test == 11 then diff --git a/src/ast.rs b/src/ast.rs index 9ca6e25..c5a9ca9 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -261,7 +261,6 @@ pub enum Statement { Return(ExpressionList), If { if_part: (Node, Block), - elif: Vec<(Node, Block)>, else_block: Block, }, Expression(Node), @@ -309,16 +308,16 @@ impl Parse for Statement { stream.expect(Token::Keyword(Keyword::Then))?; let if_block = stream.parse()?; - let mut elif = Vec::new(); + let mut elif_statements = Vec::new(); while let Some(Token::Keyword(Keyword::ElseIf)) = stream.peek() { stream.next(); - let elif_cond = stream.parse()?; + let elif_cond: Node = stream.parse()?; stream.expect(Token::Keyword(Keyword::Then))?; - let elif_block = stream.parse()?; - elif.push((elif_cond, elif_block)); + let elif_block: Block = stream.parse()?; + elif_statements.push((elif_cond, elif_block)) } - let else_block = if let Some(Token::Keyword(Keyword::Else)) = stream.peek() { + let mut else_block = if let Some(Token::Keyword(Keyword::Else)) = stream.peek() { stream.next(); stream.parse()? } else { @@ -328,10 +327,23 @@ impl Parse for Statement { } }; + for elif_statement in elif_statements.into_iter().rev() { + let elif_meta = elif_statement.0.meta.clone() + elif_statement.1._meta.clone(); + else_block = Block { + statements: vec![Node { + kind: Statement::If { + if_part: elif_statement, + else_block: else_block.clone(), + }, + meta: elif_meta.clone(), + }], + _meta: elif_meta + else_block._meta, + } + } + stream.expect(Token::Keyword(Keyword::End))?; Ok(Self::If { if_part: (if_cond, if_block), - elif: elif, else_block, }) } else if let Some(Token::Keyword(Keyword::Local | Keyword::Global)) = peeked { diff --git a/src/compile.rs b/src/compile.rs index 70236d5..c54efe1 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -189,18 +189,12 @@ impl Statement { } Statement::If { if_part, - elif, else_block, } => { let mut constants = HashSet::new(); constants.extend(if_part.0.kind.find_constants(scope)); constants.extend(if_part.1.find_constants(scope, Vec::new())); - for (cond, block) in elif { - constants.extend(cond.kind.find_constants(scope)); - constants.extend(block.find_constants(scope, Vec::new())); - } - constants.extend(else_block.find_constants(scope, Vec::new())); constants } @@ -410,7 +404,6 @@ impl Statement { } Statement::If { if_part, - elif, else_block, } => { let (instr, regs) = if_part.0.kind.compile(state, scope, Some(1)); diff --git a/src/lib.rs b/src/lib.rs index f6d5cbe..5edb62e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,7 +110,7 @@ pub fn compile( let chunk = stream.parse::()?; stream.expect(Token::Eof)?; - // dbg!(&chunk); + dbg!(&chunk); let constants = chunk .find_constants(