From 92075e6bc23d63d62e2d0caf83acbf81ad0ccd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Thu, 28 Jan 2021 20:16:08 +0100 Subject: Pass blobs all the way --- src/compiler.rs | 52 ++++++++++++++++++++++++++++++++++++---------------- src/lib.rs | 3 +-- src/vm.rs | 13 ++++++++++--- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 9fb7e8c..2302e76 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -49,6 +49,13 @@ nextable_enum!(Prec { Factor, }); + +#[derive(Debug, Clone)] +pub struct Prog { + pub blocks: Vec>>, + pub blobs: Vec>, +} + #[derive(Debug, Clone)] pub enum Type { Void, @@ -167,11 +174,10 @@ impl Frame { } #[derive(Debug, Clone)] -struct Blob { +pub struct Blob { name: String, - name_to_field: HashMap, - field: Vec, + name_to_field: HashMap, } impl Blob { @@ -179,19 +185,17 @@ impl Blob { Self { name: String::from(name), name_to_field: HashMap::new(), - field: Vec::new(), } } - pub fn add_field(&mut self, name: &str, ty: Type) -> Result { - let slot = self.field.len(); + pub fn add_field(&mut self, name: &str, ty: Type) -> Result<(), ()> { let entry = self.name_to_field.entry(String::from(name)); if matches!(entry, Entry::Occupied(_)) { - return Err(()); + Err(()) + } else { + entry.or_insert(ty); + Ok(()) } - entry.or_insert(slot); - self.field.push(ty); - Ok(slot) } } @@ -508,6 +512,12 @@ impl Compiler { return Self::find_and_capture_variable(name, self.frames.iter_mut().rev()); } + fn find_blob(&self, name: &str) -> Option { + self.blobs.iter().enumerate() + .find(|(_, x)| x.name == name) + .map(|(i, _)| i) + } + fn call(&mut self, block: &mut Block) { expect!(self, Token::LeftParen, "Expected '(' at start of function call."); @@ -634,6 +644,11 @@ impl Compiler { if self.peek() == Token::LeftParen { self.call(block); } + } else if let Some(blob) = self.find_blob(&name) { + // block.add(Op::Blob(blob)); + if self.peek() == Token::LeftParen { + self.call(block); + } } else { error!(self, format!("Using undefined variable {}.", name)); } @@ -857,9 +872,9 @@ impl Compiler { } } - expect!(self, Token::RightBrace, "Expected '}' 'blob' body. AKA '}'."); + expect!(self, Token::RightBrace, "Expected '}' after 'blob' body. AKA '}'."); - println!("Blob: {:?}", blob); + self.blobs.push(blob); } fn statement(&mut self, block: &mut Block) { @@ -895,7 +910,7 @@ impl Compiler { self.assign(&name, block); } - (Token::Blob, Token::Identifier(name), ..) => { + (Token::Blob, Token::Identifier(_), ..) => { self.blob_statement(block); } @@ -932,7 +947,8 @@ impl Compiler { } - pub fn compile(&mut self, name: &str, file: &Path) -> Result>>, Vec> { + pub fn compile(&mut self, name: &str, file: &Path) -> Result> { + println!("=== START COMPILATION ==="); self.stack_mut().push(Variable { name: String::from("/main/"), typ: Type::Void, @@ -956,14 +972,18 @@ impl Compiler { self.blocks.insert(0, Rc::new(RefCell::new(block))); + println!("=== END COMPILATION ==="); if self.errors.is_empty() { - Ok(self.blocks.clone()) + Ok(Prog { + blocks: self.blocks.clone(), + blobs: Vec::new(), + }) } else { Err(self.errors.clone()) } } } -pub fn compile(name: &str, file: &Path, tokens: TokenStream) -> Result>>, Vec> { +pub fn compile(name: &str, file: &Path, tokens: TokenStream) -> Result> { Compiler::new(file, tokens).compile(name, file) } diff --git a/src/lib.rs b/src/lib.rs index e83d11f..8cf9b36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ use std::path::Path; -use std::rc::Rc; pub mod compiler; pub mod tokenizer; @@ -23,7 +22,7 @@ pub fn run(tokens: TokenStream, path: &Path, print: bool) -> Result<(), Vec { let mut vm = vm::VM::new().print_blocks(print).print_ops(print); vm.typecheck(&blocks)?; - if let Err(e) = vm.run(Rc::clone(&blocks[0])) { + if let Err(e) = vm.run(&blocks) { Err(vec![e]) } else { Ok(()) diff --git a/src/vm.rs b/src/vm.rs index 5f7e0e3..cb30704 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -8,6 +8,7 @@ use std::cell::RefCell; use crate::compiler::Type; use crate::error::{Error, ErrorKind}; +use crate::compiler::{Prog, Blob}; macro_rules! error { ( $thing:expr, $kind:expr) => { @@ -276,6 +277,9 @@ pub struct VM { stack: Vec, frames: Vec, + + blobs: Vec>, + print_blocks: bool, print_ops: bool, } @@ -291,6 +295,7 @@ impl VM { upvalues: HashMap::new(), stack: Vec::new(), frames: Vec::new(), + blobs: Vec::new(), print_blocks: false, print_ops: false, } @@ -620,7 +625,9 @@ impl VM { self.frame().block.borrow().ops[self.frame().ip]); } - pub fn run(&mut self, block: Rc>) -> Result<(), Error>{ + pub fn run(&mut self, prog: &Prog) -> Result<(), Error>{ + let block = Rc::clone(&prog.blocks[0]); + self.blobs = prog.blobs.clone(); self.stack.clear(); self.frames.clear(); @@ -834,10 +841,10 @@ impl VM { errors } - pub fn typecheck(&mut self, blocks: &Vec>>) -> Result<(), Vec> { + pub fn typecheck(&mut self, prog: &Prog) -> Result<(), Vec> { let mut errors = Vec::new(); - for block in blocks.iter() { + for block in prog.blocks.iter() { errors.append(&mut self.typecheck_block(Rc::clone(block))); } -- cgit v1.2.1