diff --git a/crates/saft-bytecode/src/compiled_item.rs b/crates/saft-bytecode/src/compiled_item.rs new file mode 100644 index 0000000..b099a10 --- /dev/null +++ b/crates/saft-bytecode/src/compiled_item.rs @@ -0,0 +1,6 @@ +use crate::constant::ConstantRef; + +#[derive(Clone, Debug)] +pub(crate) enum CompiledItem { + Function(ConstantRef), +} diff --git a/crates/saft-bytecode/src/compiler.rs b/crates/saft-bytecode/src/compiler.rs index 25d37e4..e39cbe3 100644 --- a/crates/saft-bytecode/src/compiler.rs +++ b/crates/saft-bytecode/src/compiler.rs @@ -6,7 +6,8 @@ use saft_ir as ir; use crate::{ chunk::Chunk, - constant::Constant, + compiled_item::CompiledItem, + constant::{Constant, ConstantRef}, op::Op, value::{Function, NativeFunction, SaftFunction}, }; @@ -72,6 +73,7 @@ pub struct Compiler { stack_i: usize, scopes: Vec, ref_offsets: HashMap, + compiled_items: Vec, pub constants: Vec, } @@ -82,30 +84,51 @@ impl Compiler { stack_i: 0, scopes: vec![Scope::new(0)], ref_offsets: HashMap::new(), + compiled_items: Vec::new(), constants: vec![], } } fn compile_items( &mut self, - items: &[Option>>], - ) -> Result<(), Error> { - for item in items.iter().skip(self.constants.len()) { - let item = item.as_ref().expect("Should not be none"); + items: &[&Spanned>], + ) -> Result, Error> { + let mut new_compiled_items = items + .iter() + .skip(self.constants.len()) + .map(|item| self.compile_item(item)) + .try_collect::>()?; + self.compiled_items.append(&mut new_compiled_items); + + Ok(None) + } - let constant = match &item.v { - ir::Item::Function(fun) => Constant::Function(Function::SaftFunction( + fn compile_item( + &mut self, + item: &Spanned>, + ) -> Result { + let compiled_item = match &item.v { + ir::Item::Function(fun) => { + let constant = Constant::Function(Function::SaftFunction( self.compile_fn(item.s.spanned(fun))?, - )), - ir::Item::Builtin(native) => { - Constant::Function(Function::NativeFunction(native.clone())) - } - }; + )); + let ref_ = self.add_constant(constant); + CompiledItem::Function(ref_) + } + ir::Item::Builtin(builtin) => { + let constant = Constant::Function(Function::NativeFunction(builtin.clone())); + let ref_ = self.add_constant(constant); + CompiledItem::Function(ref_) + } + }; - self.constants.push(constant); - } + Ok(compiled_item) + } - Ok(()) + fn add_constant(&mut self, constant: Constant) -> ConstantRef { + let i = self.constants.len(); + self.constants.push(constant); + ConstantRef(i) } pub fn compile_module( @@ -115,7 +138,12 @@ impl Compiler { ) -> Result { let mut chunk = Chunk::new(); - self.compile_items(items)?; + self.compile_items( + &items + .iter() + .map(|opt| opt.as_ref().unwrap()) + .collect::>(), + )?; for stmt in &module.stmts { self.compile_stmt_(stmt, &mut chunk)? diff --git a/crates/saft-bytecode/src/constant.rs b/crates/saft-bytecode/src/constant.rs index b9ce7ed..13feafe 100644 --- a/crates/saft-bytecode/src/constant.rs +++ b/crates/saft-bytecode/src/constant.rs @@ -1,5 +1,8 @@ use crate::value::Function; +#[derive(Debug, Clone)] +pub struct ConstantRef(pub usize); + #[derive(Clone, Debug)] pub enum Constant { Function(Function), diff --git a/crates/saft-bytecode/src/lib.rs b/crates/saft-bytecode/src/lib.rs index a4cd7e8..38c6c85 100644 --- a/crates/saft-bytecode/src/lib.rs +++ b/crates/saft-bytecode/src/lib.rs @@ -1,6 +1,6 @@ #![feature(box_patterns, iterator_try_collect)] - pub mod chunk; +pub mod compiled_item; pub mod compiler; pub mod constant; pub mod natives;