diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-15 19:18:25 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-15 19:18:25 +0100 |
| commit | f098c32e89626f75d83118d4d95d209299d28587 (patch) | |
| tree | 3519fb04a89d7e7587732d8dd5bf79bf48262a23 | |
| parent | 519a9e5360f2cf0438dd09cfa3070bb9c8819f40 (diff) | |
| download | sylt-f098c32e89626f75d83118d4d95d209299d28587.tar.gz | |
change how blobs are stored
| -rw-r--r-- | src/compiler.rs | 33 | ||||
| -rw-r--r-- | src/lib.rs | 38 | ||||
| -rw-r--r-- | src/vm.rs | 28 |
3 files changed, 56 insertions, 43 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index e8607f7..9a29d6d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -228,11 +228,13 @@ pub(crate) struct Compiler { errors: Vec<Error>, blocks: Vec<Rc<RefCell<Block>>>, - blobs: Vec<Blob>, + blob_id: usize, functions: HashMap<String, (usize, RustFunction)>, constants: Vec<Value>, strings: Vec<String>, + + } macro_rules! push_frame { @@ -290,7 +292,7 @@ impl Compiler { errors: vec![], blocks: Vec::new(), - blobs: Vec::new(), + blob_id: 0, functions: HashMap::new(), @@ -309,6 +311,12 @@ impl Compiler { }).unwrap() } + fn new_blob_id(&mut self) -> usize { + let id = self.blob_id; + self.blob_id += 1; + id + } + fn add_constant(&mut self, value: Value) -> usize { self.constants.push(value); self.constants.len() - 1 @@ -612,9 +620,10 @@ impl Compiler { } fn find_blob(&self, name: &str) -> Option<usize> { - self.blobs.iter().enumerate() - .find(|(_, x)| x.name == name) - .map(|(i, _)| i) + self.constants.iter().enumerate().find_map(|(i, x)| match x { + Value::Blob(b) if b.name == name => Some(i), + _ => None, + }) } fn call(&mut self, block: &mut Block) { @@ -805,8 +814,7 @@ impl Compiler { } } } else if let Some(blob) = self.find_blob(&name) { - let string = self.add_constant(Value::Blob(blob)); - add_op(self, block, Op::Constant(string)); + add_op(self, block, Op::Constant(blob)); 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)); @@ -1085,7 +1093,11 @@ impl Compiler { "float" => Ok(Type::Float), "bool" => Ok(Type::Bool), "str" => Ok(Type::String), - x => self.find_blob(x).map(|blob| Type::Instance(blob)).ok_or(()), + x => { + let blob = self.find_blob(x) + .unwrap_or_else(|| { error!(self, "Unkown blob."); 0 } ); + Ok(Type::from(&self.constants[blob])) + } } } _ => Err(()), @@ -1103,7 +1115,7 @@ impl Compiler { expect!(self, Token::LeftBrace, "Expected 'blob' body. AKA '{'."); - let mut blob = Blob::new(&name); + let mut blob = Blob::new(self.new_blob_id(), &name); loop { if matches!(self.peek(), Token::EOF | Token::RightBrace) { break; } if matches!(self.peek(), Token::Newline) { self.eat(); continue; } @@ -1131,7 +1143,7 @@ impl Compiler { expect!(self, Token::RightBrace, "Expected '}' after 'blob' body. AKA '}'."); - self.blobs.push(blob); + self.constants.push(Value::Blob(Rc::new(blob))); } fn blob_field(&mut self, block: &mut Block) { @@ -1341,7 +1353,6 @@ impl Compiler { if self.errors.is_empty() { Ok(Prog { blocks: self.blocks.clone(), - blobs: self.blobs.iter().map(|x| Rc::new(x.clone())).collect(), functions: functions.iter().map(|(_, f)| *f).collect(), constants: self.constants.clone(), strings: self.strings.clone(), @@ -84,16 +84,16 @@ pub enum Type { String, Tuple(Vec<Type>), Function(Vec<Type>, Box<Type>), - Blob(usize), - Instance(usize), + Blob(Rc<Blob>), + Instance(Rc<Blob>), } impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { match (self, other) { (Type::Void, Type::Void) => true, - (Type::Instance(a), Type::Instance(b)) => a == b, - (Type::Blob(a), Type::Blob(b)) => a == b, + (Type::Instance(a), Type::Instance(b)) => *a == *b, + (Type::Blob(a), Type::Blob(b)) => *a == *b, (Type::Int, Type::Int) => true, (Type::Float, Type::Float) => true, (Type::Bool, Type::Bool) => true, @@ -111,8 +111,8 @@ impl PartialEq for Type { impl From<&Value> for Type { fn from(value: &Value) -> Type { match value { - Value::Instance(i, _) => Type::Instance(*i), - Value::Blob(i) => Type::Blob(*i), + Value::Instance(b, _) => Type::Instance(Rc::clone(b)), + Value::Blob(b) => Type::Blob(Rc::clone(b)), Value::Tuple(v) => { Type::Tuple(v.iter().map(|x| Type::from(x)).collect()) } @@ -136,8 +136,11 @@ impl From<&Type> for Value { fn from(ty: &Type) -> Self { match ty { Type::Void => Value::Nil, - Type::Blob(i) => Value::Blob(*i), - Type::Instance(i) => Value::Instance(*i, Rc::new(RefCell::new(Vec::new()))), + Type::Blob(b) => Value::Blob(Rc::clone(b)), + Type::Instance(b) => { + Value::Instance(Rc::clone(b), + Rc::new(RefCell::new(Vec::new()))) + } Type::Tuple(fields) => { Value::Tuple(Rc::new(fields.iter().map(Value::from).collect())) } @@ -163,8 +166,8 @@ impl From<Type> for Value { #[derive(Clone)] pub enum Value { Ty(Type), - Blob(usize), - Instance(usize, Rc<RefCell<Vec<Value>>>), + Blob(Rc<Blob>), + Instance(Rc<Blob>, Rc<RefCell<Vec<Value>>>), Tuple(Rc<Vec<Value>>), Float(f64), Int(i64), @@ -180,8 +183,8 @@ impl Debug for Value { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Value::Ty(ty) => write!(fmt, "(type {:?})", ty), - Value::Blob(i) => write!(fmt, "(blob {})", i), - Value::Instance(i, v) => write!(fmt, "(inst {} {:?})", i, v), + Value::Blob(b) => write!(fmt, "(blob {})", b.name), + Value::Instance(b, v) => write!(fmt, "(inst {} {:?})", b.name, v), Value::Float(f) => write!(fmt, "(float {})", f), Value::Int(i) => write!(fmt, "(int {})", i), Value::Bool(b) => write!(fmt, "(bool {})", b), @@ -257,14 +260,22 @@ impl UpValue { #[derive(Debug, Clone)] pub struct Blob { + pub id: usize, pub name: String, /// Maps field names to their slot and type. pub fields: HashMap<String, (usize, Type)>, } +impl PartialEq for Blob { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + impl Blob { - fn new(name: &str) -> Self { + fn new(id: usize, name: &str) -> Self { Self { + id: id, name: String::from(name), fields: HashMap::new(), } @@ -713,7 +724,6 @@ impl Block { #[derive(Clone)] pub struct Prog { pub blocks: Vec<Rc<RefCell<Block>>>, - pub blobs: Vec<Rc<Blob>>, pub functions: Vec<RustFunction>, pub constants: Vec<Value>, pub strings: Vec<String>, @@ -6,7 +6,7 @@ use std::rc::Rc; use owo_colors::OwoColorize; -use crate::{Blob, Block, Op, Prog, UpValue, Value, op}; +use crate::{Block, Op, Prog, UpValue, Value, op}; use crate::error::{Error, ErrorKind}; use crate::RustFunction; use crate::Type; @@ -57,7 +57,6 @@ pub struct VM { stack: Vec<Value>, frames: Vec<Frame>, - blobs: Vec<Rc<Blob>>, constants: Vec<Value>, strings: Vec<String>, @@ -87,7 +86,6 @@ impl VM { stack: Vec::new(), frames: Vec::new(), - blobs: Vec::new(), constants: Vec::new(), strings: Vec::new(), @@ -284,7 +282,7 @@ impl VM { let inst = self.pop(); let field = self.string(field); if let Value::Instance(ty, values) = inst { - let slot = self.blobs[ty].fields.get(field).unwrap().0; + let slot = ty.fields.get(field).unwrap().0; self.push(values.borrow()[slot].clone()); } else { error!(self, ErrorKind::RuntimeTypeError(op, vec![inst])); @@ -295,7 +293,7 @@ impl VM { let (inst, value) = self.poppop(); let field = self.string(field); if let Value::Instance(ty, values) = inst { - let slot = self.blobs[ty].fields.get(field).unwrap().0; + let slot = ty.fields.get(field).unwrap().0; values.borrow_mut()[slot] = value; } else { error!(self, ErrorKind::RuntimeTypeError(op, vec![inst])); @@ -393,16 +391,14 @@ 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]; - + Value::Blob(blob) => { let mut values = Vec::with_capacity(blob.fields.len()); for _ in 0..values.capacity() { values.push(Value::Nil); } self.pop(); - self.push(Value::Instance(blob_id, Rc::new(RefCell::new(values)))); + self.push(Value::Instance(blob, Rc::new(RefCell::new(values)))); } Value::Function(_, block) => { let inner = block.borrow(); @@ -483,7 +479,6 @@ impl VM { // Initalizes the VM for running. Run cannot be called before this. pub(crate) fn init(&mut self, prog: &Prog) { let block = Rc::clone(&prog.blocks[0]); - self.blobs = prog.blobs.clone(); self.constants = prog.constants.clone(); self.strings = prog.strings.clone(); @@ -570,7 +565,7 @@ impl VM { let inst = self.pop(); let field = self.string(field); if let Value::Instance(ty, _) = inst { - let value = Value::from(&self.blobs[ty].fields.get(field).unwrap().1); + let value = Value::from(ty.fields.get(field).unwrap().1.clone()); self.push(value); } else { self.push(Value::Nil); @@ -583,9 +578,9 @@ impl VM { let field = self.string(field); if let Value::Instance(ty, _) = inst { - let ty = &self.blobs[ty].fields.get(field).unwrap().1; + let ty = &ty.fields.get(field).unwrap().1; if ty != &Type::from(&value) { - error!(self, ErrorKind::RuntimeTypeError(op, vec![inst])); + error!(self, ErrorKind::RuntimeTypeError(op, vec![Value::from(ty)])); } } else { error!(self, ErrorKind::RuntimeTypeError(op, vec![inst])); @@ -646,9 +641,7 @@ 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]; - + Value::Blob(blob) => { let mut values = Vec::with_capacity(blob.fields.len()); for _ in 0..values.capacity() { values.push(Value::Nil); @@ -659,7 +652,7 @@ impl VM { } self.pop(); - self.push(Value::Instance(blob_id, Rc::new(RefCell::new(values)))); + self.push(Value::Instance(blob, Rc::new(RefCell::new(values)))); } Value::Function(_, block) => { let inner = block.borrow(); @@ -771,7 +764,6 @@ impl VM { pub(crate) fn typecheck(&mut self, prog: &Prog) -> Result<(), Vec<Error>> { let mut errors = Vec::new(); - self.blobs = prog.blobs.clone(); self.constants = prog.constants.clone(); self.strings = prog.strings.clone(); self.runtime = false; |
