From c574e4f707b1a2e638407bb60bf51355371874d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 9 Feb 2021 00:01:29 +0100 Subject: refactor function parsing --- src/compiler.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 7f0d32d..1d41c32 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -600,6 +600,9 @@ impl Compiler { } } } + if self.panic { + break; + } } add_op(self, block, Op::Call(arity)); @@ -718,18 +721,17 @@ impl Compiler { break; } } - Token::LeftParen => { - self.call(block); + _ => { + if !parse_branch!(self, block, self.call(block)) { + break + } } - _ => { break } } } } else if let Some(blob) = self.find_blob(&name) { let string = self.add_constant(Value::Blob(blob)); add_op(self, block, Op::Constant(string)); - if self.peek() == Token::LeftParen { - self.call(block); - } + parse_branch!(self, block, self.call(block)); } else if let Some(slot) = self.find_extern_function(&name) { let string = self.add_constant(Value::ExternFunction(slot)); add_op(self, block, Op::Constant(string)); @@ -1059,15 +1061,14 @@ impl Compiler { add_op(self, block, Op::Set(field)); return; } - Token::LeftParen => { - self.call(block); - } Token::Newline => { return; } _ => { - error!(self, "Unexpected token when parsing blob-field."); - return; + if !parse_branch!(self, block, self.call(block)) { + error!(self, "Unexpected token when parsing blob-field."); + return; + } } } } -- cgit v1.2.1 From aeab306921dfe9af4b444a77bd46d1700e43dd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 9 Feb 2021 00:30:30 +0100 Subject: fancy call syntax --- src/compiler.rs | 75 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 18 deletions(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 1d41c32..58e5f23 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -579,29 +579,68 @@ impl Compiler { } fn call(&mut self, block: &mut Block) { - expect!(self, Token::LeftParen, "Expected '(' at start of function call."); - let mut arity = 0; - loop { - match self.peek() { - Token::EOF => { - error!(self, "Unexpected EOF in function call."); - break; - } - Token::RightParen => { - self.eat(); - break; + match self.peek() { + Token::LeftParen => { + self.eat(); + loop { + match self.peek() { + Token::EOF => { + error!(self, "Unexpected EOF in function call."); + break; + } + Token::RightParen => { + self.eat(); + break; + } + _ => { + self.expression(block); + arity += 1; + if !matches!(self.peek(), Token::RightParen) { + expect!(self, Token::Comma, "Expected ',' after argument."); + } + } + } + if self.panic { + break; + } } - _ => { - self.expression(block); - arity += 1; - if !matches!(self.peek(), Token::RightParen) { - expect!(self, Token::Comma, "Expected ',' after argument."); + }, + + Token::Not => { + // I suspect this will be wierd with the boolean NOT + // operator... + self.eat(); + loop { + match self.peek() { + Token::EOF => { + error!(self, "Unexpected EOF in function call."); + break; + } + Token::Newline => { + break; + } + _ => { + if !parse_branch!(self, block, self.expression(block)) { + break; + } + arity += 1; + if matches!(self.peek(), Token::Comma) { + self.eat(); + } + } } + if self.panic { + break; + } + } + if !self.panic { + println!("LINE {} -- ", self.line()); } } - if self.panic { - break; + + _ => { + error!(self, "Not a valid function call, expected a '!' or a '('."); } } -- cgit v1.2.1 From 8283faff92557387ab057bbc6f4f0c33e96dbcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 9 Feb 2021 17:58:59 +0100 Subject: Not -> Bang --- src/compiler.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 58e5f23..34af10b 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -389,7 +389,7 @@ impl Compiler { Token::Bool(_) => self.value(block), Token::String(_) => self.value(block), - Token::Not => self.unary(block), + Token::Bang => self.unary(block), _ => { return false; }, } @@ -607,9 +607,7 @@ impl Compiler { } }, - Token::Not => { - // I suspect this will be wierd with the boolean NOT - // operator... + Token::Bang => { self.eat(); loop { match self.peek() { -- cgit v1.2.1 From d3daee70dc8f84a94f06d5f2e25fd11695be716c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 9 Feb 2021 18:00:11 +0100 Subject: better "invalid function call" error --- src/compiler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 34af10b..db79d65 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -638,7 +638,7 @@ impl Compiler { } _ => { - error!(self, "Not a valid function call, expected a '!' or a '('."); + error!(self, "Invalid function call. Expected '!' or '('."); } } -- cgit v1.2.1 From 1f79e974677b48d9cd9d69941de8c2fea3e583c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 9 Feb 2021 18:39:10 +0100 Subject: not -> bang fixup --- src/compiler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index db79d65..35fedf3 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -489,7 +489,7 @@ impl Compiler { fn unary(&mut self, block: &mut Block) { let op = match self.eat() { Token::Minus => Op::Neg, - Token::Not => Op::Not, + Token::Bang => Op::Not, _ => { error!(self, "Invalid unary operator"); Op::Neg }, }; self.parse_precedence(block, Prec::Factor); -- cgit v1.2.1 From cd1e464c11fb84ef8319e52019c23c0a91d5e3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Wed, 10 Feb 2021 22:12:31 +0100 Subject: fix the assignment --- src/compiler.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 7f0d32d..a7fc30b 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -799,7 +799,11 @@ impl Compiler { if let Some(var) = self.find_variable(&name) { if let Some(op) = op { - add_op(self, block, Op::Copy); + if var.upvalue { + add_op(self, block, Op::ReadUpvalue(var.slot)); + } else { + add_op(self, block, Op::ReadLocal(var.slot)); + } self.expression(block); add_op(self, block, op); } else { -- cgit v1.2.1 From 651865f41eea7a64093724ad664646eb76100ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Wed, 10 Feb 2021 23:01:35 +0100 Subject: add constants --- src/compiler.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs index 7f0d32d..d18d9c6 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -126,6 +126,7 @@ struct Variable { active: bool, upvalue: bool, captured: bool, + mutable: bool, } struct Frame { @@ -759,6 +760,32 @@ impl Compiler { scope, active: false, upvalue: false, + mutable: true, + }); + Ok(slot) + } + + fn define_constant(&mut self, name: &str, typ: Type, _block: &mut Block) -> Result { + if let Some(var) = self.find_variable(&name) { + if var.scope == self.frame().scope { + error!(self, format!("Multiple definitions of {} in this block.", name)); + return Err(()); + } + } + + let slot = self.stack().len(); + let scope = self.frame().scope; + self.stack_mut().push(Variable { + name: String::from(name), + captured: false, + outer_upvalue: false, + outer_slot: 0, + slot, + typ, + scope, + active: false, + upvalue: false, + mutable: false, }); Ok(slot) } @@ -774,6 +801,15 @@ impl Compiler { } } + fn constant_statement(&mut self, name: &str, typ: Type, block: &mut Block) { + let slot = self.define_constant(name, typ.clone(), block); + self.expression(block); + + if let Ok(slot) = slot { + self.stack_mut()[slot].active = true; + } + } + fn assign(&mut self, block: &mut Block) { let name = match self.eat() { Token::Identifier(name) => name, @@ -798,6 +834,10 @@ impl Compiler { }; if let Some(var) = self.find_variable(&name) { + if !var.mutable { + // TODO(ed): Maybe a better error than "SyntaxError". + error!(self, format!("Cannot assign to constant '{}'", var.name)); + } if let Some(op) = op { add_op(self, block, Op::Copy); self.expression(block); @@ -1123,6 +1163,12 @@ impl Compiler { self.definition_statement(&name, Type::Unknown, block); } + (Token::Identifier(name), Token::ColonColon, ..) => { + self.eat(); + self.eat(); + self.constant_statement(&name, Type::Unknown, block); + } + (Token::Blob, Token::Identifier(_), ..) => { self.blob_statement(block); } @@ -1177,6 +1223,7 @@ impl Compiler { active: false, captured: false, upvalue: false, + mutable: true, }); let mut block = Block::new(name, file, 0); -- cgit v1.2.1