Initial commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
compile::{
|
||||
block::FunctionBlock, error::CompileError, function::FunctionSignature,
|
||||
syntax::FunctionBody, value::CompileConstant,
|
||||
},
|
||||
vm::{
|
||||
instruction::ConstantId,
|
||||
module::{Module, ModuleConstant},
|
||||
pool::Pool,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CompilationModule {
|
||||
constant_pool: Pool<CompileConstant, { ConstantId::BITS }>,
|
||||
pub(crate) local_functions: HashMap<u32, FunctionBlock>,
|
||||
local_function_index: u32,
|
||||
root: Option<u32>,
|
||||
}
|
||||
|
||||
impl CompilationModule {
|
||||
pub fn constant(&mut self, value: CompileConstant) -> Result<ConstantId, CompileError> {
|
||||
match self.constant_pool.key(value) {
|
||||
Some(key) => Ok(key),
|
||||
None => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_function(
|
||||
&mut self,
|
||||
signature: FunctionSignature,
|
||||
body: &FunctionBody,
|
||||
root: bool,
|
||||
) -> Result<u32, CompileError> {
|
||||
let index = self.local_function_index;
|
||||
if root && self.root.is_some() {
|
||||
todo!()
|
||||
}
|
||||
self.local_function_index += 1;
|
||||
let mut function = FunctionBlock::new(signature);
|
||||
function.compile_body(self, body)?;
|
||||
self.local_functions.insert(index, function);
|
||||
if root {
|
||||
self.root = Some(index);
|
||||
}
|
||||
Ok(index)
|
||||
}
|
||||
|
||||
pub fn compile_module(self) -> Result<Module, CompileError> {
|
||||
// Emit all function code first
|
||||
let mut function_offsets = HashMap::new();
|
||||
let mut instructions = vec![];
|
||||
let root = self.root.unwrap();
|
||||
for (index, function) in self.local_functions.into_iter() {
|
||||
function_offsets.insert(index, instructions.len());
|
||||
instructions.extend(function.instructions.into_iter().map(u32::from));
|
||||
}
|
||||
let entry = *function_offsets.get(&root).unwrap();
|
||||
let constants = self
|
||||
.constant_pool
|
||||
.into_iter()
|
||||
.map(|(value, key)| {
|
||||
(
|
||||
key,
|
||||
match value {
|
||||
CompileConstant::Integer(value) => ModuleConstant::Integer(value),
|
||||
CompileConstant::LocalFunction(index) => {
|
||||
let address = *function_offsets.get(&index).unwrap();
|
||||
ModuleConstant::LocalFunction(address)
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Module {
|
||||
constants,
|
||||
instructions,
|
||||
entry,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user