Skip to content

Commit

Permalink
push value bye !
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenthz committed Dec 18, 2023
1 parent 21fd402 commit f820d63
Show file tree
Hide file tree
Showing 18 changed files with 407 additions and 267 deletions.
4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ description = "a multi language high level dynamic platform to execute in a safe
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["lang-lispy", "lang-rusty", "backend-bignum"]
default = ["lang-lispy", "lang-rusty"]
lang-lispy = ["werbolg-lang-lispy"]
lang-rusty = ["werbolg-lang-rusty"]
backend-smallnum = ["werbolg-core/backend-smallnum"]
backend-bignum = ["werbolg-core/backend-bignum"]

[profile.release]
panic = 'abort'
Expand Down
92 changes: 59 additions & 33 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
mod lang;
mod value;

use hashbrown::HashMap;
use value::Value;
use werbolg_compile::{code_dump, compile, symbols::IdVec, Environment};
use werbolg_core::{Ident, NifId, Number};
use werbolg_exec::{ExecutionEnviron, ExecutionError, ExecutionMachine, NIFCall, Value, NIF};
use werbolg_core::{ConstrId, Ident, Literal, NifId, ValueFun};

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (ubuntu-latest)

unused imports: `ConstrId`, `ValueFun`

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

unused imports: `ConstrId`, `ValueFun`

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (macos-latest)

unused imports: `ConstrId`, `ValueFun`

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macos-latest)

unused imports: `ConstrId`, `ValueFun`

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (windows-latest)

unused imports: `ConstrId`, `ValueFun`

Check warning on line 7 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (windows-latest)

unused imports: `ConstrId`, `ValueFun`
use werbolg_exec::{
ExecutionEnviron, ExecutionError, ExecutionMachine, ExecutionParams, NIFCall, Valuable, NIF,
};
use werbolg_lang_common::FileUnit;

fn nif_plus(args: &[Value]) -> Result<Value, ExecutionError> {
let n1 = args[0].number()?;
let n2 = args[1].number()?;
let n1 = args[0].int()?;
let n2 = args[1].int()?;

let ret = Number::new(n1.as_ref() + n2.as_ref());
let ret = Value::Integral(n1 + n2);

Ok(Value::Number(ret))
Ok(ret)
}

fn nif_sub(args: &[Value]) -> Result<Value, ExecutionError> {
let n1 = args[0].number()?;
let n2 = args[1].number()?;
let n1 = args[0].int()?;
let n2 = args[1].int()?;

let ret = Number::new(n1.as_ref() - n2.as_ref());
let ret = Value::Integral(n1 - n2);

Ok(Value::Number(ret))
Ok(ret)
}

fn nif_mul(args: &[Value]) -> Result<Value, ExecutionError> {
let n1 = args[0].number()?;
let n2 = args[1].number()?;
let n1 = args[0].int()?;
let n2 = args[1].int()?;

let ret = Number::new(n1.as_ref() * n2.as_ref());
let ret = Value::Integral(n1 * n2);

Ok(Value::Number(ret))
Ok(ret)
}

fn nif_eq(args: &[Value]) -> Result<Value, ExecutionError> {
let n1 = args[0].number()?;
let n2 = args[1].number()?;
let n1 = args[0].int()?;
let n2 = args[1].int()?;

let ret = n1.0 == n2.0;
let ret = n1 == n2;

Ok(Value::Bool(ret))
}
Expand All @@ -46,24 +50,43 @@ fn nif_hashtable(_args: &[Value]) -> Result<Value, ExecutionError> {
let mut h = HashMap::<u32, u64>::new();
h.insert(10, 20);
h.insert(20, 40);
Ok(Value::make_opaque(h))
Ok(Value::HashMap(h))
}

fn nif_hashtable_get(args: &[Value]) -> Result<Value, ExecutionError> {
let h: &HashMap<u32, u64> = args[0].opaque()?;
let index_bignum = args[1].number()?;
let Value::HashMap(h) = &args[0] else {
return Err(ExecutionError::ValueKindUnexpected {
value_expected: Value::Integral(0).descriptor(),
value_got: Value::Integral(0).descriptor(),
});
};
let index_bignum = args[1].int()?;
let index: u32 = index_bignum
.try_into()
.map_err(|()| ExecutionError::UserPanic {
message: String::from("cannot convert number to u64"),
.map_err(|_| ExecutionError::UserPanic {
message: String::from("cannot convert Integral to u32"),
})?;

match h.get(&index) {
None => Ok(Value::Unit),
Some(value) => Ok(Value::Number(Number::from_u64(*value))),
Some(value) => Ok(Value::Integral(*value)),
}
}

fn literal_to_value(lit: &Literal) -> Value {
match lit {
Literal::Bool(b) => Value::Bool(true),

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (ubuntu-latest)

unused variable: `b`

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

unused variable: `b`

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (macos-latest)

unused variable: `b`

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macos-latest)

unused variable: `b`

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check (windows-latest)

unused variable: `b`

Check warning on line 78 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite (windows-latest)

unused variable: `b`
Literal::String(_) => Value::Unit,
Literal::Number(_) => Value::Integral(0),
Literal::Decimal(_) => Value::Unit,
Literal::Bytes(_) => Value::Unit,
}
}

fn literal_mapper(lit: Literal) -> Literal {
lit
}

fn get_content(args: &[String]) -> Result<(FileUnit, lang::Lang), ()> {
let path = std::path::PathBuf::from(&args[1]);

Expand Down Expand Up @@ -112,21 +135,21 @@ fn main() -> Result<(), ()> {

let module = lang::parse(lang, &fileunit).expect("no parse error");

pub struct Env<'m, T> {
pub struct Env<'m, L, T, V> {
environment: Environment,
nifs: IdVec<NifId, NIF<'m, T>>,
nifs: IdVec<NifId, NIF<'m, L, T, V>>,
nifs_binds: werbolg_interpret::Bindings<NifId>,
}

impl<'m, T> Env<'m, T> {
impl<'m, L, T, V: Valuable> Env<'m, L, T, V> {
pub fn new() -> Self {
Self {
environment: Environment::new(),
nifs: IdVec::new(),
nifs_binds: werbolg_interpret::Bindings::new(),
}
}
pub fn add_native_call(&mut self, ident: &'static str, f: NIFCall<'m, T>) {
pub fn add_native_call(&mut self, ident: &'static str, f: NIFCall<'m, L, T, V>) {
let id = self.environment.add(werbolg_core::Ident::from(ident));
let id2 = self.nifs.push(NIF {
name: ident,
Expand All @@ -140,21 +163,21 @@ fn main() -> Result<(), ()> {
pub fn add_native_mut_fun(
&mut self,
ident: &'static str,
f: fn(&mut ExecutionMachine<'m, T>, &[Value]) -> Result<Value, ExecutionError>,
f: fn(&mut ExecutionMachine<'m, L, T, V>, &[V]) -> Result<V, ExecutionError>,
) {
self.add_native_call(ident, NIFCall::Mut(f))
}

pub fn add_native_pure_fun(
&mut self,
ident: &'static str,
f: fn(&[Value]) -> Result<Value, ExecutionError>,
f: fn(&[V]) -> Result<V, ExecutionError>,
) {
self.add_native_call(ident, NIFCall::Pure(f))
}

pub fn finalize(self) -> ExecutionEnviron<'m, T> {
let globals = self.environment.global.remap(|f| Value::Fun(f));
pub fn finalize(self) -> ExecutionEnviron<'m, L, T, V> {
let globals = self.environment.global.remap(|f| V::make_fun(f));

werbolg_exec::ExecutionEnviron {
nifs: self.nifs,
Expand All @@ -172,7 +195,9 @@ fn main() -> Result<(), ()> {
env.add_native_pure_fun("table_get", nif_hashtable_get);
//environment.add(ident);

let exec_module = compile(module, &mut env.environment).expect("no compilation error");
let compilation_params = werbolg_compile::CompilationParams { literal_mapper };
let exec_module =
compile(&compilation_params, module, &mut env.environment).expect("no compilation error");

//exec_module.print();
code_dump(&exec_module.code, &exec_module.funs);
Expand All @@ -185,7 +210,8 @@ fn main() -> Result<(), ()> {
.get(&Ident::from("main"))
.expect("existing function as entry point");

let mut em = ExecutionMachine::new(&exec_module, ee, ());
let execution_params = ExecutionParams { literal_to_value };
let mut em = ExecutionMachine::new(&exec_module, ee, execution_params, ());

//let val = werbolg_exec::exec(&mut em, Ident::from("main"), &[]).expect("no execution error");

Expand Down
83 changes: 83 additions & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use hashbrown::HashMap;
use werbolg_core::{ConstrId, ValueFun};
use werbolg_exec::{ExecutionError, Valuable, ValueKind};

#[derive(Clone, Debug)]
pub enum Value {
Unit,
// Simple values
Bool(bool),
Integral(u64),
Binary(Box<[u8]>),

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (ubuntu-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (macos-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macos-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (windows-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed

Check warning on line 11 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (windows-latest)

variants `Binary`, `List`, `Struct`, and `Enum` are never constructed
HashMap(HashMap<u32, u64>),
// Composite
List(Box<[Value]>),
Struct(ConstrId, Box<[Value]>),
Enum(u32, Box<[Value]>),
// Functions
Fun(ValueFun),
}

impl Value {
fn desc(&self) -> ValueKind {
match self {
Value::Unit => b" unit",
Value::Bool(_) => b" bool",
Value::HashMap(_) => b" hashmap",
Value::Integral(_) => b" int",
Value::Binary(_) => b" binary",
Value::List(_) => b" list",
Value::Struct(_, _) => b" struct",
Value::Enum(_, _) => b" enum",
Value::Fun(_) => b" fun",
}
}
}

impl Valuable for Value {
fn descriptor(&self) -> werbolg_exec::ValueKind {
self.desc()
}

fn conditional(&self) -> Option<bool> {
match self {
Value::Bool(b) => Some(*b),
_ => None,
}
}

fn fun(&self) -> Option<ValueFun> {
match self {
Self::Fun(valuefun) => Some(*valuefun),
_ => None,
}
}

fn structure(&self) -> Option<(ConstrId, &[Self])> {
todo!()
}

fn index(&self, index: usize) -> Option<&Self> {

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (ubuntu-latest)

unused variable: `index`

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

unused variable: `index`

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (macos-latest)

unused variable: `index`

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macos-latest)

unused variable: `index`

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Check (windows-latest)

unused variable: `index`

Check warning on line 60 in src/value.rs

View workflow job for this annotation

GitHub Actions / Test Suite (windows-latest)

unused variable: `index`
todo!()
}

fn make_fun(fun: ValueFun) -> Self {
Value::Fun(fun)
}

fn make_dummy() -> Self {
Value::Unit
}
}

impl Value {
pub fn int(&self) -> Result<u64, ExecutionError> {
match self {
Value::Integral(o) => Ok(*o),
_ => Err(ExecutionError::ValueKindUnexpected {
value_expected: Value::Integral(0).descriptor(),
value_got: self.descriptor(),
}),
}
}
}
26 changes: 15 additions & 11 deletions werbolg-compile/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ use super::defs::*;
use super::instructions::*;
use super::symbols::*;
use super::CompilationError;
use super::CompilationParams;
use werbolg_core as ir;
use werbolg_core::{ConstrId, FunId, GlobalId, Ident, LitId, Literal, NifId, Span};
use werbolg_core::{ConstrId, FunId, GlobalId, Ident, LitId, NifId, Span};

pub(crate) struct RewriteState {
pub(crate) struct RewriteState<'a, L: Clone + Eq + core::hash::Hash> {
pub(crate) params: &'a CompilationParams<L>,
pub(crate) funs_tbl: SymbolsTable<FunId>,
pub(crate) funs_vec: IdVec<FunId, FunDef>,
pub(crate) constrs: SymbolsTableData<ConstrId, ConstrDef>,
pub(crate) lits: UniqueTableBuilder<LitId, Literal>,
pub(crate) lits: UniqueTableBuilder<LitId, L>,
pub(crate) main_code: Code,
pub(crate) lambdas: IdVecAfter<FunId, FunDef>,
pub(crate) lambdas_code: Code,
Expand Down Expand Up @@ -83,13 +85,15 @@ pub enum CodeState {
InLambda,
}

impl RewriteState {
impl<'a, L: Clone + Eq + core::hash::Hash> RewriteState<'a, L> {
pub fn new(
params: &'a CompilationParams<L>,
funs_tbl: SymbolsTable<FunId>,
lambdas: IdVecAfter<FunId, FunDef>,
bindings: BindingsStack<BindingType>,
) -> Self {
Self {
params,
funs_tbl,
funs_vec: IdVec::new(),
main_code: Code::new(),
Expand Down Expand Up @@ -156,8 +160,8 @@ pub(crate) fn alloc_struct(
.ok_or_else(|| CompilationError::DuplicateSymbol(name))
}

pub(crate) fn rewrite_fun(
state: &mut RewriteState,
pub(crate) fn rewrite_fun<'a, L: Clone + Eq + core::hash::Hash>(
state: &mut RewriteState<'a, L>,
fundef: ir::FunDef,
) -> Result<FunDef, CompilationError> {
let ir::FunDef { name, vars, body } = fundef;
Expand Down Expand Up @@ -191,14 +195,14 @@ pub(crate) fn rewrite_fun(
})
}

fn rewrite_expr2(
state: &mut RewriteState,
fn rewrite_expr2<'a, L: Clone + Eq + core::hash::Hash>(
state: &mut RewriteState<'a, L>,
local: &mut LocalBindings,
expr: ir::Expr,
) -> Result<(), CompilationError> {
match expr {
ir::Expr::Literal(_span, lit) => {
let lit_id = state.lits.add(lit);
let lit_id = state.lits.add((state.params.literal_mapper)(lit));
state.write_code().push(Instruction::PushLiteral(lit_id));
Ok(())
}
Expand Down Expand Up @@ -304,8 +308,8 @@ fn rewrite_expr2(
}
}

fn fetch_ident(
state: &RewriteState,
fn fetch_ident<'a, L: Clone + Eq + core::hash::Hash>(
state: &RewriteState<'a, L>,
local: &LocalBindings,
span: Span,
ident: Ident,
Expand Down
Loading

0 comments on commit f820d63

Please sign in to comment.