From 0ee58ee676945f9a652690f490936080ab5a0623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sat, 30 Jan 2021 09:57:50 +0100 Subject: fix closures in closure bug --- src/compiler.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 347abe6..92bf3fc 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -472,6 +472,9 @@ impl Compiler { let mut return_type = Type::Void; let mut function_block = Block::new(&name, &self.current_file, self.line()); + let block_id = self.blocks.len(); + self.blocks.push(Rc::new(RefCell::new(Block::new(&name, &self.current_file, self.line())))); + let _ret = push_frame!(self, function_block, { loop { match self.peek() { @@ -538,8 +541,8 @@ impl Compiler { let func = Op::Constant(Value::Function(Vec::new(), Rc::clone(&function_block))); + self.blocks[block_id] = function_block; block.add(func, self.line()); - self.blocks.push(function_block); } fn variable_expression(&mut self, block: &mut Block) { -- cgit v1.2.1 From d2fd074370d829d3d1dfbc6279f1fcbde769eeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sat, 30 Jan 2021 23:17:49 +0100 Subject: Add in the yield keyword --- src/compiler.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 92bf3fc..b7fdce1 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -473,7 +473,8 @@ impl Compiler { let mut function_block = Block::new(&name, &self.current_file, self.line()); let block_id = self.blocks.len(); - self.blocks.push(Rc::new(RefCell::new(Block::new(&name, &self.current_file, self.line())))); + let new_block = Block::new(&name, &self.current_file, self.line()); + self.blocks.push(Rc::new(RefCell::new(new_block))); let _ret = push_frame!(self, function_block, { loop { @@ -888,6 +889,11 @@ impl Compiler { } } + (Token::Yield, ..) => { + self.eat(); + block.add(Op::Yield, self.line()); + } + (Token::Identifier(name), Token::ColonEqual, ..) => { self.eat(); self.eat(); -- cgit v1.2.1 From afc4a3fe1618239017e15cabc664dd70abc1d75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sun, 31 Jan 2021 22:28:48 +0100 Subject: add assignment ops --- src/compiler.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 16 deletions(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index b7fdce1..69bf6eb 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -621,9 +621,38 @@ impl Compiler { } } - fn assign(&mut self, name: &str, block: &mut Block) { + fn assign(&mut self, block: &mut Block) { + let name = match self.eat() { + Token::Identifier(name) => name, + _ => { + error!(self, format!("Expected identifier in assignment")); + return; + } + }; + + let op = match self.eat() { + Token::Equal => None, + + Token::PlusEqual => Some(Op::Add), + Token::MinusEqual => Some(Op::Sub), + Token::StarEqual => Some(Op::Mul), + Token::SlashEqual => Some(Op::Div), + + _ => { + error!(self, format!("Expected '=' in assignment")); + return; + } + }; + if let Some(var) = self.find_variable(&name) { - self.expression(block); + if let Some(op) = op { + block.add(Op::Copy, self.line()); + self.expression(block); + block.add(op, self.line()); + } else { + self.expression(block); + } + if var.upvalue { block.add(Op::AssignUpvalue(var.slot), self.line()); } else { @@ -832,14 +861,31 @@ impl Compiler { return Err(()); }; - if self.peek() == Token::Equal { - self.eat(); - self.expression(block); - block.add(Op::Set(field), self.line()); - return Ok(()); - } else { - block.add(Op::Get(field), self.line()); - } + let op = match self.peek() { + Token::Equal => { + self.eat(); + self.expression(block); + block.add(Op::Set(field), self.line()); + return Ok(()); + } + + Token::PlusEqual => Op::Add, + Token::MinusEqual => Op::Sub, + Token::StarEqual => Op::Mul, + Token::SlashEqual => Op::Div, + + _ => { + block.add(Op::Get(field), self.line()); + continue; + } + }; + block.add(Op::Copy, self.line()); + block.add(Op::Get(field.clone()), self.line()); + self.eat(); + self.expression(block); + block.add(op, self.line()); + block.add(Op::Set(field), self.line()); + return Ok(()); } Token::LeftParen => { self.call(block); @@ -867,6 +913,16 @@ impl Compiler { block.add(Op::Print, self.line()); } + (Token::Identifier(_), Token::Equal, ..) | + (Token::Identifier(_), Token::PlusEqual, ..) | + (Token::Identifier(_), Token::MinusEqual, ..) | + (Token::Identifier(_), Token::SlashEqual, ..) | + (Token::Identifier(_), Token::StarEqual, ..) + + => { + self.assign(block); + } + (Token::Identifier(_), Token::Dot, ..) => { let block_length = block.ops.len(); let token_length = self.curr; @@ -900,12 +956,6 @@ impl Compiler { self.definition_statement(&name, Type::UnknownType, block); } - (Token::Identifier(name), Token::Equal, ..) => { - self.eat(); - self.eat(); - self.assign(&name, block); - } - (Token::Blob, Token::Identifier(_), ..) => { self.blob_statement(block); } -- cgit v1.2.1