aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.rs')
-rw-r--r--src/compiler.rs102
1 files changed, 72 insertions, 30 deletions
diff --git a/src/compiler.rs b/src/compiler.rs
index d18d9c6..eb6058a 100644
--- a/src/compiler.rs
+++ b/src/compiler.rs
@@ -390,7 +390,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; },
}
@@ -490,7 +490,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);
@@ -580,26 +580,66 @@ 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::Bang => {
+ 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());
+ }
+ }
+
+ _ => {
+ error!(self, "Invalid function call. Expected '!' or '('.");
}
}
@@ -719,18 +759,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));
@@ -839,7 +878,11 @@ impl Compiler {
error!(self, format!("Cannot assign to constant '{}'", var.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 {
@@ -1099,15 +1142,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;
+ }
}
}
}