From b7e480f93f8ea3feb9155df207bb308b11e79303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Thu, 28 Jan 2021 20:54:24 +0100 Subject: Creating blobs --- src/vm.rs | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/vm.rs') diff --git a/src/vm.rs b/src/vm.rs index cb30704..df970db 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -21,6 +21,8 @@ macro_rules! error { #[derive(Clone)] pub enum Value { + Blob(usize), + BlobInstance(usize, Vec), Float(f64), Int(i64), Bool(bool), @@ -75,6 +77,8 @@ impl UpValue { impl Debug for Value { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Value::Blob(i) => write!(fmt, "(blob {})", i), + Value::BlobInstance(i, v) => write!(fmt, "(inst {} {:?})", i, v), Value::Float(f) => write!(fmt, "(float {})", f), Value::Int(i) => write!(fmt, "(int {})", i), Value::Bool(b) => write!(fmt, "(bool {})", b), @@ -98,6 +102,8 @@ impl Value { fn as_type(&self) -> Type { match self { + Value::BlobInstance(i, _) => Type::BlobInstance(*i), + Value::Blob(i) => Type::Blob(*i), Value::Float(_) => Type::Float, Value::Int(_) => Type::Int, Value::Bool(_) => Type::Bool, @@ -557,7 +563,22 @@ impl VM { Op::Call(num_args) => { let new_base = self.stack.len() - 1 - num_args; - match &self.stack[new_base] { + match self.stack[new_base].clone() { + Value::Blob(blob_id) => { + let blob = &self.blobs[blob_id]; + + let mut values = Vec::with_capacity(blob.name_to_field.len()); + for _ in 0..values.capacity() { + values.push(Value::Nil); + } + + for (slot, ty) in blob.name_to_field.values() { + values[*slot] = ty.as_value(); + } + + self.stack.pop(); + self.stack.push(Value::BlobInstance(blob_id, values)); + } Value::Function(_, block) => { let inner = block.borrow(); let args = inner.args(); @@ -751,6 +772,21 @@ impl VM { Op::Call(num_args) => { let new_base = self.stack.len() - 1 - num_args; match self.stack[new_base].clone() { + Value::Blob(blob_id) => { + let blob = &self.blobs[blob_id]; + + let mut values = Vec::with_capacity(blob.name_to_field.len()); + for _ in 0..values.capacity() { + values.push(Value::Nil); + } + + for (slot, ty) in blob.name_to_field.values() { + values[*slot] = ty.as_value(); + } + + self.stack.pop(); + self.stack.push(Value::BlobInstance(blob_id, values)); + } Value::Function(_, block) => { let inner = block.borrow(); let args = inner.args(); @@ -844,6 +880,7 @@ impl VM { pub fn typecheck(&mut self, prog: &Prog) -> Result<(), Vec> { let mut errors = Vec::new(); + self.blobs = prog.blobs.clone(); for block in prog.blocks.iter() { errors.append(&mut self.typecheck_block(Rc::clone(block))); } -- cgit v1.2.1