Skip to content

Commit

Permalink
document and clean compile
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenthz committed Dec 19, 2023
1 parent bf696ab commit 7b0783b
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ mod value;

use hashbrown::HashMap;
use value::{Value, HASHMAP_KIND};
use werbolg_compile::{code_dump, compile, symbols::IdVec, CompilationError, Environment};
use werbolg_core::{Ident, Literal, NifId};
use werbolg_compile::{code_dump, compile, CompilationError, Environment};
use werbolg_core::{idvec::IdVec, Ident, Literal, NifId};
use werbolg_exec::{
ExecutionEnviron, ExecutionError, ExecutionMachine, ExecutionParams, NIFCall, Valuable, NIF,
};
Expand Down
3 changes: 3 additions & 0 deletions werbolg-compile/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::instructions::Instruction;
use super::symbols::{IdVec, IdVecAfter};
use werbolg_core::id::IdF;

/// Instruction Address
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct InstructionAddress(u32);

Expand All @@ -12,6 +13,7 @@ impl Default for InstructionAddress {
}

impl InstructionAddress {
/// Increment the instruction address to the next instruction
pub fn next(self) -> Self {
InstructionAddress::add(self, 1)
}
Expand Down Expand Up @@ -72,6 +74,7 @@ pub struct Code {
/// placeholder instruction
pub struct CodeRef(InstructionAddress);

/// A displacement type between instruction. i.e. the number of element between 2 different InstructionAddress
#[derive(Debug, Copy, Clone)]
pub struct InstructionDiff(u32);

Expand Down
20 changes: 20 additions & 0 deletions werbolg-compile/src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,57 @@ use super::instructions::*;
use alloc::vec::Vec;
use werbolg_core::{ConstrId, Ident};

/// Local stack size (in unit of values)
#[derive(Copy, Clone, Debug)]
pub struct LocalStackSize(pub u32);

/// Function definition
///
/// For anonymous function the name is None
#[derive(Clone, Debug)]
pub struct FunDef {
/// name of the function. anonymous function has no name
pub name: Option<Ident>,
/// Arity of the function.
pub arity: CallArity,
/// The local stack size needed for this function
pub stack_size: LocalStackSize,
/// The address of the first instruction (entry point) for this function
pub code_pos: InstructionAddress,
}

/// Structure definition
#[derive(Clone, Debug)]
pub struct StructDef {
/// name of this structure
pub name: Ident,
/// name of the fields
pub fields: Vec<Ident>,
}

/// Enumeration definition
#[derive(Clone, Debug)]
pub struct EnumDef {
/// name of this enumeration
pub name: Ident,
/// The variants for this enumeration
pub variants: Vec<Variant>,
}

/// Constructor definition (enumeration or struct)
#[derive(Clone, Debug)]
pub enum ConstrDef {
/// Struct variant of a constructor
Struct(StructDef),
/// Enumeration variant of a constructor
Enum(EnumDef),
}

/// Enumeration Variant type
#[derive(Clone, Debug)]
pub struct Variant {
/// Name of this variant
pub name: Ident,
/// Constructor Id for the content
pub constr: ConstrId,
}
8 changes: 8 additions & 0 deletions werbolg-compile/src/environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ use super::symbols::IdVec;
use crate::symbols::SymbolsTableData;
use werbolg_core::{FunId, GlobalId, Ident, NifId, ValueFun};

/// Environment of the compilation
pub struct Environment {
/// All the global values defined
pub global: IdVec<GlobalId, ValueFun>,
/// ?
pub symbols: SymbolsTableData<NifId, (Ident, GlobalId)>,
/// the index of global
pub global_index: u32,
}

impl Environment {
/// Create a new empty environment
pub fn new() -> Self {
Self {
symbols: SymbolsTableData::new(),
Expand All @@ -17,6 +22,7 @@ impl Environment {
}
}

/// Add ident and return the associated NifId
pub fn add(&mut self, ident: Ident) -> NifId {
let global_id = self.global.next_id();
let nif = self.symbols.add(ident.clone(), (ident, global_id)).unwrap();
Expand All @@ -25,11 +31,13 @@ impl Environment {
nif
}

/// Add global
pub fn add_global(&mut self, fun: FunId) -> GlobalId {
let global_id = self.global.push(ValueFun::Fun(fun));
self.global_index += 1;
global_id
}

/// Finalize the environment - TODO
pub fn finalize(self) -> () {}
}
19 changes: 18 additions & 1 deletion werbolg-compile/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Compile werbolg-core AST to an easy to execute set of instructions
#![no_std]
#![deny(missing_docs)]

extern crate alloc;

Expand All @@ -9,7 +11,7 @@ mod defs;
mod environ;
mod instructions;
mod params;
pub mod symbols;
mod symbols;

pub use code::{InstructionAddress, InstructionDiff};
pub use instructions::{CallArity, Instruction, LocalBindIndex, ParamBindIndex, StructFieldIndex};
Expand All @@ -27,19 +29,33 @@ use symbols::{IdVec, IdVecAfter, SymbolsTable, SymbolsTableData};
use alloc::format;
use core::fmt::Write;

/// Compilation error
#[derive(Debug)]
pub enum CompilationError {
/// Duplicate symbol during compilation (e.g. 2 functions with the name)
DuplicateSymbol(Ident),
/// Cannot find the symbol during compilation
MissingSymbol(Span, Ident),
/// Number of parameters for a functions is above the limit we chose
FunctionParamsMoreThanLimit(usize),
/// Core's Literal is not supported by this compiler
LiteralNotSupported(Literal),
}

/// A compiled unit
///
/// The L type parameter is the compilation-level literal type that the user wants
/// to compile to.
pub struct CompilationUnit<L> {
/// Table of literal indexed by their LitId
pub lits: IdVec<LitId, L>,
/// Table of constructor (structure / enum) indexed by their ConstrId
pub constrs: SymbolsTableData<ConstrId, ConstrDef>,
/// Symbol table of function { Ident => FunId }
pub funs_tbl: SymbolsTable<FunId>,
/// Table of function indexed by their FunId
pub funs: IdVec<FunId, FunDef>,
/// A sequence of instructions of all the code, indexed by InstructionAddress
pub code: IdVec<InstructionAddress, Instruction>,
}

Expand Down Expand Up @@ -103,6 +119,7 @@ pub fn compile<'a, L: Clone + Eq + core::hash::Hash>(
})
}

/// Dump the instructions to a buffer
pub fn code_dump<W: Write>(
writer: &mut W,
code: &IdVec<InstructionAddress, Instruction>,
Expand Down
1 change: 1 addition & 0 deletions werbolg-compile/src/params.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::CompilationError;
use werbolg_core::Literal;

/// User driven compilation parameters
pub struct CompilationParams<L: Clone + Eq + core::hash::Hash> {
/// Map a werbolg-literal into a L type that will be used during execution
pub literal_mapper: fn(Literal) -> Result<L, CompilationError>,
Expand Down
2 changes: 1 addition & 1 deletion werbolg-exec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
extern crate alloc;

use ir::{ConstrId, GlobalId, NifId};
use werbolg_compile::symbols::IdVec;
use werbolg_compile::{
CallArity, LocalBindIndex, LocalStackSize, ParamBindIndex, StructFieldIndex,
};
use werbolg_compile::{CompilationUnit, InstructionAddress, InstructionDiff};
use werbolg_core as ir;
use werbolg_core::idvec::IdVec;

mod exec;
mod valuable;
Expand Down

0 comments on commit 7b0783b

Please sign in to comment.