aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.rs18
-rw-r--r--src/vm.rs11
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());
diff --git a/src/vm.rs b/src/vm.rs
index df970db..028f2cd 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -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)),