diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-28 21:10:48 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-28 21:10:48 +0100 |
| commit | fddd4555f7162fb64b1fa1b57282de63d0f4d452 (patch) | |
| tree | 633da5904617f5d7e1f7c6e9805540ce8ceb9938 | |
| parent | b7e480f93f8ea3feb9155df207bb308b11e79303 (diff) | |
| download | sylt-fddd4555f7162fb64b1fa1b57282de63d0f4d452.tar.gz | |
Access fields
| -rw-r--r-- | src/compiler.rs | 18 | ||||
| -rw-r--r-- | src/vm.rs | 11 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index 4dd3517..256ce49 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -650,8 +650,22 @@ impl Compiler { } else { block.add(Op::ReadLocal(var.slot), self.line()); } - if self.peek() == Token::LeftParen { - self.call(block); + loop { + match self.peek() { + Token::Dot => { + self.eat(); + if let Token::Identifier(field) = self.eat() { + block.add(Op::Get(String::from(field)), self.line()); + } else { + error!(self, "Expected fieldname after '.'"); + break; + } + } + Token::LeftParen => { + self.call(block); + } + _ => { break } + } } } else if let Some(blob) = self.find_blob(&name) { block.add(Op::Constant(Value::Blob(blob)), self.line()); @@ -122,6 +122,7 @@ pub enum Op { Pop, PopUpvalue, Constant(Value), + Get(String), Add, Sub, @@ -415,6 +416,16 @@ impl VM { self.stack.push(value); } + Op::Get(field) => { + let inst = self.stack.pop(); + if let Some(Value::BlobInstance(ty, values)) = inst { + let slot = self.blobs[ty].name_to_field.get(&field).unwrap().0; + self.stack.push(values[slot].clone()); + } else { + error!(self, ErrorKind::RuntimeTypeError(Op::Get(field.clone()), vec![inst.unwrap()])); + } + } + Op::Neg => { match self.stack.pop().unwrap() { Value::Float(a) => self.stack.push(Value::Float(-a)), |
