diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-01 20:57:55 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-01 21:38:34 +0100 |
| commit | e86852857bc6f6ca1e1cd81db494071c5d9e3ff1 (patch) | |
| tree | 71f111699dd0d7526dbe5ee334c477db6e0362e0 /src/compiler.rs | |
| parent | e9ce94d72e1e8e51b7843b414504a07e132813e1 (diff) | |
| parent | fd4868df1fd24c05bce5c92cf8289fa755f25875 (diff) | |
| download | sylt-e86852857bc6f6ca1e1cd81db494071c5d9e3ff1.tar.gz | |
Merge branch 'main' into vectors
Diffstat (limited to 'src/compiler.rs')
| -rw-r--r-- | src/compiler.rs | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index 6c01ea3..9a1d1e5 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -674,9 +674,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 { @@ -901,14 +930,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); @@ -936,6 +982,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; @@ -958,16 +1014,15 @@ impl Compiler { } } - (Token::Identifier(name), Token::ColonEqual, ..) => { + (Token::Yield, ..) => { self.eat(); - self.eat(); - self.definition_statement(&name, Type::UnknownType, block); + block.add(Op::Yield, self.line()); } - (Token::Identifier(name), Token::Equal, ..) => { + (Token::Identifier(name), Token::ColonEqual, ..) => { self.eat(); self.eat(); - self.assign(&name, block); + self.definition_statement(&name, Type::UnknownType, block); } (Token::Blob, Token::Identifier(_), ..) => { |
