Add while-loop
This commit is contained in:
parent
4c9b9085fd
commit
42164ef6fe
@ -1,59 +1,8 @@
|
|||||||
global b = 5
|
|
||||||
|
|
||||||
function add(x)
|
local i = 0
|
||||||
return function (y)
|
print("before")
|
||||||
x = x + 1
|
while i < 10 do
|
||||||
b = b + 1
|
i = i + 1
|
||||||
return x + y, 1, 2, b
|
print(i)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
print("after")
|
||||||
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
|
|
||||||
print("second")
|
|
||||||
else
|
|
||||||
print("third")
|
|
||||||
end
|
|
||||||
print("after")
|
|
||||||
15
src/ast.rs
15
src/ast.rs
@ -271,6 +271,8 @@ pub enum Statement {
|
|||||||
Node<Expression>,
|
Node<Expression>,
|
||||||
Block,
|
Block,
|
||||||
),
|
),
|
||||||
|
While(Node<Expression>, Block),
|
||||||
|
Repeat(Block, Node<Expression>),
|
||||||
Break,
|
Break,
|
||||||
Label(Node<String>),
|
Label(Node<String>),
|
||||||
GoTo(Node<String>),
|
GoTo(Node<String>),
|
||||||
@ -400,6 +402,19 @@ impl Parse for Statement {
|
|||||||
step,
|
step,
|
||||||
block,
|
block,
|
||||||
))
|
))
|
||||||
|
} else if let Some(Token::Keyword(Keyword::While)) = stream.peek() {
|
||||||
|
stream.next();
|
||||||
|
let expr = stream.parse()?;
|
||||||
|
stream.expect(Token::Keyword(Keyword::Do))?;
|
||||||
|
let block = stream.parse()?;
|
||||||
|
stream.expect(Token::Keyword(Keyword::End))?;
|
||||||
|
Ok(Statement::While(expr, block))
|
||||||
|
} else if let Some(Token::Keyword(Keyword::Repeat)) = stream.peek() {
|
||||||
|
stream.next();
|
||||||
|
let block = stream.parse()?;
|
||||||
|
stream.expect(Token::Keyword(Keyword::Until))?;
|
||||||
|
let expr = stream.parse()?;
|
||||||
|
Ok(Statement::Repeat(block, expr))
|
||||||
} else if let Ok(expr) = stream.parse() {
|
} else if let Ok(expr) = stream.parse() {
|
||||||
Ok(Self::Expression(expr))
|
Ok(Self::Expression(expr))
|
||||||
} else if let Some(Token::Keyword(Keyword::Break)) = stream.peek() {
|
} else if let Some(Token::Keyword(Keyword::Break)) = stream.peek() {
|
||||||
|
|||||||
@ -207,6 +207,18 @@ impl Statement {
|
|||||||
constants.extend(block.find_constants(scope, Vec::new()));
|
constants.extend(block.find_constants(scope, Vec::new()));
|
||||||
constants
|
constants
|
||||||
}
|
}
|
||||||
|
Statement::While(node, block) => {
|
||||||
|
let mut constants = HashSet::new();
|
||||||
|
constants.extend(node.kind.find_constants(scope));
|
||||||
|
constants.extend(block.find_constants(scope, Vec::new()));
|
||||||
|
constants
|
||||||
|
}
|
||||||
|
Statement::Repeat(block, node) => {
|
||||||
|
let mut constants = HashSet::new();
|
||||||
|
constants.extend(node.kind.find_constants(scope));
|
||||||
|
constants.extend(block.find_constants(scope, Vec::new()));
|
||||||
|
constants
|
||||||
|
}
|
||||||
Statement::Break => HashSet::new(),
|
Statement::Break => HashSet::new(),
|
||||||
Statement::Label(_) => HashSet::new(),
|
Statement::Label(_) => HashSet::new(),
|
||||||
Statement::GoTo(_) => HashSet::new(),
|
Statement::GoTo(_) => HashSet::new(),
|
||||||
@ -469,6 +481,27 @@ impl Statement {
|
|||||||
)));
|
)));
|
||||||
instructions.push(PreInstr::Instr(Instruction::Jmp(-(instr_len + 4))));
|
instructions.push(PreInstr::Instr(Instruction::Jmp(-(instr_len + 4))));
|
||||||
}
|
}
|
||||||
|
Statement::While(expr, block) => {
|
||||||
|
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,
|
||||||
|
)));
|
||||||
|
|
||||||
|
let block_instructions = block.compile(state, scope);
|
||||||
|
let block_instr_len = block_instructions.len() as i32;
|
||||||
|
|
||||||
|
instructions.push(PreInstr::Instr(Instruction::Jmp(block_instr_len + 1)));
|
||||||
|
instructions.extend(block_instructions);
|
||||||
|
|
||||||
|
instructions.push(PreInstr::Instr(Instruction::Jmp(
|
||||||
|
-(block_instr_len + expr_instr_len + 2),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Statement::Repeat(block, expr) => todo!(),
|
||||||
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())),
|
||||||
|
|||||||
@ -23,6 +23,9 @@ pub enum Keyword {
|
|||||||
Nil,
|
Nil,
|
||||||
Not,
|
Not,
|
||||||
For,
|
For,
|
||||||
|
While,
|
||||||
|
Repeat,
|
||||||
|
Until,
|
||||||
Do,
|
Do,
|
||||||
Break,
|
Break,
|
||||||
GoTo,
|
GoTo,
|
||||||
@ -48,6 +51,9 @@ impl Keyword {
|
|||||||
"do" => Keyword::Do,
|
"do" => Keyword::Do,
|
||||||
"break" => Keyword::Break,
|
"break" => Keyword::Break,
|
||||||
"goto" => Keyword::GoTo,
|
"goto" => Keyword::GoTo,
|
||||||
|
"while" => Keyword::While,
|
||||||
|
"repeat" => Keyword::Repeat,
|
||||||
|
"until" => Keyword::Until,
|
||||||
_ => None?,
|
_ => None?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -70,6 +76,9 @@ impl ToString for Keyword {
|
|||||||
Keyword::Nil => "nil",
|
Keyword::Nil => "nil",
|
||||||
Keyword::Not => "not",
|
Keyword::Not => "not",
|
||||||
Keyword::For => "for",
|
Keyword::For => "for",
|
||||||
|
Keyword::While => "while",
|
||||||
|
Keyword::Repeat => "repeat",
|
||||||
|
Keyword::Until => "until",
|
||||||
Keyword::Do => "do",
|
Keyword::Do => "do",
|
||||||
Keyword::Break => "break",
|
Keyword::Break => "break",
|
||||||
Keyword::GoTo => "goto",
|
Keyword::GoTo => "goto",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user