Skip to content

Commit

Permalink
added partial local context
Browse files Browse the repository at this point in the history
  • Loading branch information
lexa-diky committed May 28, 2024
1 parent 94154c4 commit 09b1904
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 25 deletions.
74 changes: 64 additions & 10 deletions src/compiler/rst/compilation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ pub(crate) struct ConstantBinding {

#[derive(Clone)]
pub(crate) struct FunctionBinding {
pub(crate) identifier: u64,
pub(crate) name: String,
pub(crate) context: CompilationContext
}

#[derive(Clone)]
pub(crate) struct LocalCompilationContext {
constant_table: HashMap<String, ConstantBinding>,
function_table: HashMap<String, FunctionBinding>,
parents: Vec<u64>,
}

#[derive(Clone)]
Expand All @@ -22,6 +29,7 @@ pub(crate) struct CompilationContext {
parent: Option<Box<CompilationContext>>,
constant_table: HashMap<String, ConstantBinding>,
function_table: HashMap<String, FunctionBinding>,
local_contexts: HashMap<u64, LocalCompilationContext>,
}

impl CompilationContext {
Expand All @@ -31,31 +39,77 @@ impl CompilationContext {
parent: None,
constant_table: HashMap::new(),
function_table: HashMap::new(),
local_contexts: HashMap::new(),
};
}

pub(crate) fn branch(parent: CompilationContext) -> CompilationContext {
return CompilationContext {
self_path: parent.self_path.clone(),
parent: Some(Box::new(parent)),
// region constant
pub(crate) fn bind_local_constant(&mut self, context_id: u64, constant: ConstantBinding) {
if !self.local_contexts.contains_key(&context_id) {
self.local_contexts.insert(context_id, LocalCompilationContext::new());
}

let mut local_context: &mut LocalCompilationContext = self.local_contexts.get_mut(&context_id)
.expect("prechecked but value is still missing");

local_context.bind_constant(constant);
}
pub(crate) fn get_local_constant(&self, context_id: u64, name: &String) -> Option<&ConstantBinding> {
let local_context = self.local_contexts.get(&context_id)?;

let local_constant = local_context.get_constant(context_id, name);

if local_constant.is_none() {
for parent in &local_context.parents {
let parent_constant = self.get_local_constant(*parent, name);
if parent_constant.is_some() {
return parent_constant
}
}
} else {
return local_constant
}

return None;
}

// endregion

pub(crate) fn bind_function(&mut self, function: FunctionBinding) {
self.function_table.insert(function.name.clone(), function);
}

pub(crate) fn get_function(&self, name: &String) -> Option<&FunctionBinding> {
return self.function_table.get(name);
}
}

impl LocalCompilationContext {
fn new() -> LocalCompilationContext {
return LocalCompilationContext {
constant_table: HashMap::new(),
function_table: HashMap::new(),
parents: Vec::new(),
};
}

pub(crate) fn bind_constant(&mut self, constant: ConstantBinding) {
fn bind_constant(&mut self, constant: ConstantBinding) {
self.constant_table.insert(constant.name.clone(), constant);
}

pub(crate) fn get_constant(&self, name: &String) -> Option<&ConstantBinding> {
fn get_constant(&self, context_id: u64, name: &String) -> Option<&ConstantBinding> {
return self.constant_table.get(name);
}

pub(crate) fn bind_function(&mut self, function: FunctionBinding) {
fn bind_function(&mut self, function: FunctionBinding) {
self.function_table.insert(function.name.clone(), function);
}

pub(crate) fn get_function(&self, name: &String) -> Option<&FunctionBinding> {
fn get_function(&self, name: &String) -> Option<&FunctionBinding> {
return self.function_table.get(name);
}
}

fn attach_parent(&mut self, parent_id: u64) {
self.parents.push(parent_id);
}
}
37 changes: 22 additions & 15 deletions src/compiler/rst/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;
use crate::compiler::cst::{CstAtom, CstAtomVec, CstEmitStatement, CstFile, CstFunctionStatement};
use crate::compiler::rst::compilation_context::{CompilationContext, ConstantBinding, FunctionBinding};
use crate::compiler::rst::node::HexoFile;
use crate::compiler::util::ByteBuffer;
use crate::compiler::util::{ByteBuffer, next_identifier};
use crate::compiler::HexoCompiler;

#[derive(Debug)]
Expand All @@ -21,9 +21,10 @@ impl RstCompiler<'_> {
}

pub(crate) fn compile(&self, cst: &CstFile) -> Result<HexoFile, RstCompilerError> {
let context = Self::build_context(&cst.path, &cst.main)?;
let context_id = next_identifier();
let context = Self::build_context(context_id, &cst.path, &cst.main)?;

let bb = Self::build_bytes(&context, &cst.main.emits)?;
let bb = Self::build_bytes(context_id, &context, &cst.main.emits)?;

return Ok(HexoFile {
path: cst.path.clone(),
Expand All @@ -33,19 +34,21 @@ impl RstCompiler<'_> {
}

fn build_bytes(
context_id: u64,
context: &CompilationContext,
emits: &Vec<CstEmitStatement>,
) -> Result<ByteBuffer, RstCompilerError> {
let mut byte_buffer = ByteBuffer::new();

for emit in emits {
Self::build_bytes_into(context, &emit.atoms, &mut byte_buffer)?
Self::build_bytes_into(context_id, context, &emit.atoms, &mut byte_buffer)?
}

return Ok(byte_buffer);
}

fn build_bytes_into(
context_id: u64,
context: &CompilationContext,
atoms: &CstAtomVec,
buffer: &mut ByteBuffer,
Expand All @@ -55,7 +58,7 @@ impl RstCompiler<'_> {
CstAtom::Hex(byte) => buffer.push_byte(*byte),
CstAtom::String(string) => buffer.push_string(string.clone()),
CstAtom::Number(number) => buffer.push_u32_shrunk(*number),
CstAtom::Constant { name } => Self::build_constant_into(context, &name, buffer)?,
CstAtom::Constant { name } => Self::build_constant_into(context_id, context, &name, buffer)?,
CstAtom::Function { .. } => {}
}
}
Expand All @@ -64,12 +67,13 @@ impl RstCompiler<'_> {
}

fn build_constant_into(
context_id: u64,
context: &CompilationContext,
name: &String,
buffer: &mut ByteBuffer,
) -> Result<(), RstCompilerError> {
let constant_binding = context
.get_constant(name)
.get_local_constant(context_id, name)
.ok_or(RstCompilerError::UnresolvedConstant { name: name.clone() })?;

buffer.push_byte_buffer(&constant_binding.byte_buffer);
Expand All @@ -78,30 +82,36 @@ impl RstCompiler<'_> {
}

fn build_context(
context_id: u64,
file_path: &PathBuf,
cst: &CstFunctionStatement,
) -> Result<CompilationContext, RstCompilerError> {
let mut root_context = CompilationContext::new(file_path);

Self::build_context_into(&cst, &mut root_context)?;
Self::build_context_into(context_id, &cst, &mut root_context)?;

return Ok(root_context);
}

fn build_context_into(cst: &&CstFunctionStatement, mut root_context: &mut CompilationContext) -> Result<(), RstCompilerError> {
Self::build_context_constants_into(&cst, &mut root_context)?;
fn build_context_into(
context_id: u64,
cst: &&CstFunctionStatement,
mut root_context: &mut CompilationContext,
) -> Result<(), RstCompilerError> {
Self::build_context_constants_into(context_id, &cst, &mut root_context)?;
Self::build_context_functions_into(&cst, &mut root_context)?;
Ok(())
}

fn build_context_constants_into(
context_id: u64,
cst: &&CstFunctionStatement,
root_context: &mut CompilationContext,
) -> Result<(), RstCompilerError> {
for constant in &cst.constants {
let mut buff = ByteBuffer::new();
Self::build_bytes_into(&root_context, &constant.atoms, &mut buff)?;
root_context.bind_constant(ConstantBinding {
Self::build_bytes_into(context_id, &root_context, &constant.atoms, &mut buff)?;
root_context.bind_local_constant(context_id, ConstantBinding {
name: constant.name.clone(),
byte_buffer: buff,
})
Expand All @@ -115,13 +125,10 @@ impl RstCompiler<'_> {
root_context: &mut CompilationContext,
) -> Result<(), RstCompilerError> {
for function in &cst.functions {
let mut sub_context = CompilationContext::branch(root_context.clone());
Self::build_context_into(&function, &mut sub_context)?;

root_context.bind_function(
FunctionBinding {
identifier: next_identifier(),
name: function.name.clone(),
context: sub_context,
})
}

Expand Down
10 changes: 10 additions & 0 deletions src/compiler/util/id_generator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use std::collections::HashMap;

static mut COUNTER: u64 = 0;

pub(crate) fn next_identifier() -> u64 {
unsafe {
COUNTER = COUNTER + 1;
COUNTER
}
}
2 changes: 2 additions & 0 deletions src/compiler/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod byte_buffer;
pub(crate) mod encoding;
mod id_generator;

pub(crate) use byte_buffer::ByteBuffer;
pub(crate) use id_generator::next_identifier;

0 comments on commit 09b1904

Please sign in to comment.