Add parsing of elseif and else

This commit is contained in:
Sofia 2026-03-19 17:31:12 +02:00
parent 0faeeae0ea
commit b6a38101f7
4 changed files with 73 additions and 58 deletions

View File

@ -1,49 +1,10 @@
global b = 5
function add(x)
return function (y)
x = x + 1
b = b + 1
return x + y, 1, 2, b
end
local test = 10
if test == 10 then
print("first")
elseif test == 11 then
print("second")
else
print("third")
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::
print("after")

View File

@ -234,7 +234,12 @@ impl Parse for Block {
while !matches!(
stream.peek(),
Some(Token::Keyword(Keyword::End) | Token::Eof)
Some(
Token::Keyword(Keyword::End)
| Token::Keyword(Keyword::ElseIf)
| Token::Keyword(Keyword::Else)
| Token::Eof
)
) {
statements.push(stream.parse()?);
}
@ -254,7 +259,11 @@ pub enum Statement {
ExpressionList,
),
Return(ExpressionList),
If(Node<Expression>, Block),
If {
if_part: (Node<Expression>, Block),
elif: Vec<(Node<Expression>, Block)>,
else_block: Block,
},
Expression(Node<Expression>),
NumericalFor(
Node<String>,
@ -296,11 +305,35 @@ impl Parse for Statement {
Ok(Statement::Return(stream.parse()?))
} else if peeked == Some(Token::Keyword(Keyword::If)) {
stream.next(); // Consume if
let cond = stream.parse()?;
let if_cond = stream.parse()?;
stream.expect(Token::Keyword(Keyword::Then))?;
let then = stream.parse()?;
let if_block = stream.parse()?;
let mut elif = Vec::new();
while let Some(Token::Keyword(Keyword::ElseIf)) = stream.peek() {
stream.next();
let elif_cond = stream.parse()?;
stream.expect(Token::Keyword(Keyword::Then))?;
let elif_block = stream.parse()?;
elif.push((elif_cond, elif_block));
}
let else_block = if let Some(Token::Keyword(Keyword::Else)) = stream.peek() {
stream.next();
stream.parse()?
} else {
Block {
statements: Vec::new(),
_meta: Metadata::empty(),
}
};
stream.expect(Token::Keyword(Keyword::End))?;
Ok(Self::If(cond, then))
Ok(Self::If {
if_part: (if_cond, if_block),
elif: elif,
else_block,
})
} else if let Some(Token::Keyword(Keyword::Local | Keyword::Global)) = peeked {
let access_modifier = match stream.next() {
Some(Token::Keyword(Keyword::Local)) => AccessModifier::Local,

View File

@ -187,10 +187,21 @@ impl Statement {
}
constants
}
Statement::If(cond, then) => {
Statement::If {
if_part,
elif,
else_block,
} => {
let mut constants = HashSet::new();
constants.extend(cond.kind.find_constants(scope));
constants.extend(then.find_constants(scope, Vec::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
}
Statement::Expression(expr) => expr.kind.find_constants(scope),
@ -397,8 +408,12 @@ impl Statement {
},
)));
}
Statement::If(expr, block) => {
let (instr, regs) = expr.kind.compile(state, scope, Some(1));
Statement::If {
if_part,
elif,
else_block,
} => {
let (instr, regs) = if_part.0.kind.compile(state, scope, Some(1));
instructions.extend(instr);
let local = scope.register_counter.next();
@ -408,7 +423,7 @@ impl Statement {
0,
)));
let block_instructions = block.compile(state, scope);
let block_instructions = if_part.1.compile(state, scope);
instructions.push(PreInstr::Instr(Instruction::Jmp(
block_instructions.len() as i32
)));

View File

@ -15,6 +15,8 @@ pub enum Keyword {
Global,
Return,
If,
ElseIf,
Else,
Then,
True,
False,
@ -35,6 +37,8 @@ impl Keyword {
"global" => Keyword::Global,
"return" => Keyword::Return,
"if" => Keyword::If,
"elseif" => Keyword::ElseIf,
"else" => Keyword::Else,
"then" => Keyword::Then,
"true" => Keyword::True,
"false" => Keyword::False,
@ -58,6 +62,8 @@ impl ToString for Keyword {
Keyword::Global => "global",
Keyword::Return => "return",
Keyword::If => "if",
Keyword::ElseIf => "elif",
Keyword::Else => "else",
Keyword::Then => "then",
Keyword::True => "true",
Keyword::False => "false",