feat: better builtins implementaion

get rid of circular references
This commit is contained in:
2025-05-17 18:31:36 +08:00
parent 8480e0891b
commit ff9afd0cc1
19 changed files with 191 additions and 244 deletions

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use std::rc::Rc;
use itertools::Itertools;
use rpds::HashTrieMap;
use derive_more::Constructor;
use itertools::Itertools;
use crate::bytecode::Func as BFunc;
use crate::error::Result;
@@ -40,13 +40,14 @@ impl From<ir::Param> for Param {
}
}
pub type JITFunc<'vm> = unsafe extern "C" fn(vm: *mut VM<'_>, *mut Env<'vm>, *mut Value<'vm>) -> Value<'vm>;
pub type JITFunc<'vm> =
unsafe extern "C" fn(vm: *mut VM<'_>, *mut Env<'vm>, *mut Value<'vm>) -> Value<'vm>;
#[derive(Debug, Clone, Constructor)]
pub struct Func<'vm> {
pub func: &'vm BFunc,
pub env: Rc<Env<'vm>>,
pub compiled: Option<JITFunc<'vm>>
pub compiled: Option<JITFunc<'vm>>,
}
impl<'vm> Func<'vm> {
@@ -56,14 +57,14 @@ impl<'vm> Func<'vm> {
let env = Rc::new(self.env.as_ref().clone());
match self.func.param.clone() {
Ident(ident) => env.enter(HashTrieMap::new().insert(ident.into(), arg)),
Ident(ident) => env.enter([(ident.into(), arg)].into_iter()),
Formals {
formals,
ellipsis,
alias,
} => {
let arg = arg.unwrap_attr_set();
let mut new = HashTrieMap::new();
let mut new = Vec::with_capacity(formals.len() + alias.iter().len());
if !ellipsis
&& arg
.as_inner()
@@ -78,14 +79,16 @@ impl<'vm> Func<'vm> {
let formal = formal.clone().into();
let arg = arg
.select(formal)
.or_else(|| default.map(|idx| Value::Thunk(Thunk::new(vm.get_thunk(idx)).into())))
.or_else(|| {
default.map(|idx| Value::Thunk(Thunk::new(vm.get_thunk(idx)).into()))
})
.unwrap();
new.insert_mut(formal, arg);
new.push((formal, arg));
}
if let Some(alias) = alias {
new.insert_mut(alias.clone().into(), Value::AttrSet(arg));
new.push((alias.clone().into(), Value::AttrSet(arg)));
}
env.enter(new);
env.enter(new.into_iter());
}
}