diff options
| -rw-r--r-- | src/compiler.rs | 56 | ||||
| -rw-r--r-- | src/tokenizer.rs | 2 | ||||
| -rw-r--r-- | src/vm.rs | 2 | ||||
| -rw-r--r-- | tests/simple.tdy | 38 |
4 files changed, 62 insertions, 36 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index c542412..4bb2469 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -338,6 +338,7 @@ impl Compiler { while !matches!(self.peek(), Token::RightBrace | Token::EOF) { self.statement(block); + expect!(self, Token::Newline, "Expect newline after expression."); } self.level -= 1; @@ -380,12 +381,10 @@ impl Compiler { block.add(Op::Pop, self.line()); } - fn for(&mut self, block: &mut Block) { + fn for_loop(&mut self, block: &mut Block) { expect!(self, Token::For, "Expected 'for' at start of for-loop."); - self.level += 1; - let h = self.stack.len(); - + // Definition match self.peek_four() { (Token::Identifier(name), Token::Identifier(typ), Token::ColonEqual, _) => { self.eat(); @@ -403,21 +402,47 @@ impl Compiler { self.eat(); self.define_variable(&name, Type::UnkownType, block); } + + _ => { error!(self, "Expected definition at start of for-loop."); } } + expect!(self, Token::Comma, "Expect ',' between initalizer and loop expression."); + + let cond = block.curr(); + self.expression(block); + let cond_out = block.add(Op::Illegal, self.line()); + let cond_cont = block.add(Op::Illegal, self.line()); + expect!(self, Token::Comma, "Expect ',' between initalizer and loop expression."); + + let inc = block.curr(); + self.statement(block); + block.add(Op::Jmp(cond), self.line()); + + // patch_jmp!(Op::Jmp, cond_cont => block.curr()); + block.patch(Op::Jmp(block.curr()), cond_cont); + self.scope(block); + block.add(Op::Jmp(inc), self.line()); + + block.patch(Op::JmpFalse(block.curr()), cond_out); } fn statement(&mut self, block: &mut Block) { self.clear_panic(); + macro_rules! tokens { + ($( $token:pat ),*) => { + ($( $token , )* ..) + }; + } + match self.peek_four() { - (Token::Print, _, _, _) => { + tokens!(Token::Print) => { self.eat(); self.expression(block); block.add(Op::Print, self.line()); }, - (Token::Identifier(name), Token::Identifier(typ), Token::ColonEqual, _) => { + tokens!(Token::Identifier(name), Token::Identifier(typ), Token::ColonEqual) => { self.eat(); self.eat(); self.eat(); @@ -428,43 +453,43 @@ impl Compiler { } } - (Token::Identifier(name), Token::ColonEqual, _, _) => { + tokens!(Token::Identifier(name), Token::ColonEqual) => { self.eat(); self.eat(); self.define_variable(&name, Type::UnkownType, block); } - (Token::Identifier(name), Token::Equal, _, _) => { + tokens!(Token::Identifier(name), Token::Equal) => { self.eat(); self.eat(); self.assign(&name, block); } - (Token::If, _, _, _) => { + tokens!(Token::If) => { self.if_statment(block); } - (Token::For, _, _, _) => { - self.for(block); + tokens!(Token::For) => { + self.for_loop(block); } - (Token::Unreachable, _, _, _) => { + tokens!(Token::Unreachable) => { self.eat(); block.add(Op::Unreachable, self.line()); } - (Token::LeftBrace, _, _, _) => { + tokens!(Token::LeftBrace) => { self.scope(block); } - (Token::Newline, _, _, _) => {} + tokens!(Token::Newline) => {} _ => { self.expression(block); block.add(Op::Pop, self.line()); } } - expect!(self, Token::Newline, "Expect newline after expression."); + } pub fn compile(&mut self, name: &str, file: &Path) -> Result<Block, Vec<Error>> { @@ -472,6 +497,7 @@ impl Compiler { while self.peek() != Token::EOF { self.statement(&mut block); + expect!(self, Token::Newline, "Expect newline after expression."); } block.add(Op::Return, self.line()); diff --git a/src/tokenizer.rs b/src/tokenizer.rs index e52410c..62397c5 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -103,6 +103,8 @@ pub enum Token { #[token("!")] Not, + #[token(",")] + Comma, #[token(".")] Dot, #[token("->")] @@ -153,7 +153,7 @@ impl VM { } pub fn run(&mut self) -> Result<(), Error>{ - const PRINT_WHILE_RUNNING: bool = false; + const PRINT_WHILE_RUNNING: bool = true; const PRINT_BLOCK: bool = true; if PRINT_BLOCK { diff --git a/tests/simple.tdy b/tests/simple.tdy index d07aad7..2f0f606 100644 --- a/tests/simple.tdy +++ b/tests/simple.tdy @@ -13,28 +13,26 @@ // print d // print c - -for a := 0, a >= 0, a = a - 1 { - if a == 2 { - continue - } +for a := 0, a < 10, print a { print a + a = a + 1 } -for a := 0, a >= 0, a = a - 1 { - if a == 2 { - continue - } - print a -} - -a = 0 - -fiv a in something { -} - -something.each((x) -> { +// 1, 2, 3, 4 -} -// 1, 2, 3, 4 +// +// === main === +// | Constant(Int(0)) +// | ReadLocal(0) +// | Constant(Int(10)) +// | Less +// | JmpFalse(12) +// | Jmp(11) +// | Jmp(1) +// | ReadLocal(0) +// | Constant(Int(1)) +// | Add +// | Assign(0) +// | Jmp(7) +// | Return |
