fix: builtins impl

This commit is contained in:
2025-05-19 08:37:40 +08:00
parent 4124156d52
commit e17c48f2d9
4 changed files with 42 additions and 18 deletions

View File

@@ -52,9 +52,11 @@ pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> Env<'jit, 'vm> {
); );
map.insert(vm.new_sym(primop.name), Value::PrimOp(primop)); map.insert(vm.new_sym(primop.name), Value::PrimOp(primop));
} }
let attrs: Rc<_> = AttrSet::from_inner(map).into(); let attrs: Rc<_> = Rc::new_cyclic(|weak| {
let mut builtins = Value::AttrSet(attrs); map.insert(vm.new_sym("builtins"), Value::Builtins(weak.clone()));
builtins.push_attr(vm.new_sym("builtins"), Value::Builtins); AttrSet::from_inner(map)
});
let builtins = Value::AttrSet(attrs);
env.insert(vm.new_sym("builtins"), builtins); env.insert(vm.new_sym("builtins"), builtins);
env env

View File

@@ -2,7 +2,7 @@ use hashbrown::HashSet;
use std::cell::OnceCell; use std::cell::OnceCell;
use std::cell::RefCell; use std::cell::RefCell;
use std::hash::Hash; use std::hash::Hash;
use std::rc::Rc; use std::rc::{Rc, Weak};
use derive_more::{IsVariant, Unwrap}; use derive_more::{IsVariant, Unwrap};
@@ -24,7 +24,7 @@ pub use func::*;
pub use list::List; pub use list::List;
pub use primop::*; pub use primop::*;
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)] #[derive(Debug, IsVariant, Unwrap, Clone)]
pub enum Value<'jit: 'vm, 'vm> { pub enum Value<'jit: 'vm, 'vm> {
Const(Const), Const(Const),
Thunk(Rc<Thunk<'jit, 'vm>>), Thunk(Rc<Thunk<'jit, 'vm>>),
@@ -35,7 +35,7 @@ pub enum Value<'jit: 'vm, 'vm> {
PrimOp(Rc<PrimOp<'jit, 'vm>>), PrimOp(Rc<PrimOp<'jit, 'vm>>),
PartialPrimOp(Rc<PartialPrimOp<'jit, 'vm>>), PartialPrimOp(Rc<PartialPrimOp<'jit, 'vm>>),
Func(Rc<Func<'jit, 'vm>>), Func(Rc<Func<'jit, 'vm>>),
Builtins, Builtins(Weak<AttrSet<'jit, 'vm>>),
} }
impl Hash for Value<'_, '_> { impl Hash for Value<'_, '_> {
@@ -52,7 +52,7 @@ impl Hash for Value<'_, '_> {
PrimOp(x) => (x.as_ref() as *const self::PrimOp).hash(state), PrimOp(x) => (x.as_ref() as *const self::PrimOp).hash(state),
PartialPrimOp(x) => (x.as_ref() as *const self::PartialPrimOp).hash(state), PartialPrimOp(x) => (x.as_ref() as *const self::PartialPrimOp).hash(state),
Func(x) => (x.as_ref() as *const self::Func).hash(state), Func(x) => (x.as_ref() as *const self::Func).hash(state),
Builtins => (), Builtins(x) => (x.as_ptr()).hash(state),
} }
} }
} }
@@ -64,8 +64,21 @@ impl<'jit: 'vm, 'vm> Value<'jit, 'vm> {
(Const(a), Const(b)) => a.eq(b), (Const(a), Const(b)) => a.eq(b),
(AttrSet(a), AttrSet(b)) => a.eq_impl(b, vm), (AttrSet(a), AttrSet(b)) => a.eq_impl(b, vm),
(List(a), List(b)) => a.eq(b), (List(a), List(b)) => a.eq(b),
(Builtins, AttrSet(attrs)) => attrs.has_attr(vm.new_sym("builtins")), (Builtins(_), AttrSet(attrs)) => attrs.has_attr(vm.new_sym("builtins")),
(AttrSet(attrs), Builtins) => attrs.has_attr(vm.new_sym("builtins")), (AttrSet(attrs), Builtins(_)) => attrs.has_attr(vm.new_sym("builtins")),
_ => false,
}
}
}
impl<'jit: 'vm, 'vm> PartialEq for Value<'jit, 'vm> {
fn eq(&self, other: &Self) -> bool {
use Value::*;
match (self, other) {
(Const(a), Const(b)) => a.eq(b),
(AttrSet(a), AttrSet(b)) => (a.as_ref() as *const self::AttrSet).eq(&(b.as_ref() as *const _)),
(List(a), List(b)) => (a.as_ref() as *const self::List).eq(&(b.as_ref() as *const _)),
(Builtins(a), Builtins(b)) => a.ptr_eq(b),
_ => false, _ => false,
} }
} }
@@ -111,7 +124,7 @@ impl<'v, 'vm: 'v, 'jit: 'vm> Value<'jit, 'vm> {
PrimOp(x) => R::PrimOp(x), PrimOp(x) => R::PrimOp(x),
PartialPrimOp(x) => R::PartialPrimOp(x), PartialPrimOp(x) => R::PartialPrimOp(x),
Func(x) => R::Func(x), Func(x) => R::Func(x),
Builtins => unreachable!(), Builtins(_) => unreachable!(),
} }
} }
@@ -128,7 +141,7 @@ impl<'v, 'vm: 'v, 'jit: 'vm> Value<'jit, 'vm> {
PrimOp(x) => M::PrimOp(Rc::make_mut(x)), PrimOp(x) => M::PrimOp(Rc::make_mut(x)),
PartialPrimOp(x) => M::PartialPrimOp(Rc::make_mut(x)), PartialPrimOp(x) => M::PartialPrimOp(Rc::make_mut(x)),
Func(x) => M::Func(x), Func(x) => M::Func(x),
Builtins => unreachable!(), Builtins(_) => unreachable!(),
} }
} }
} }
@@ -151,7 +164,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
PrimOp(_) => "lambda", PrimOp(_) => "lambda",
PartialPrimOp(_) => "lambda", PartialPrimOp(_) => "lambda",
Func(_) => "lambda", Func(_) => "lambda",
Builtins => "set", Builtins(_) => "set",
} }
} }
@@ -360,7 +373,8 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
self.typename() self.typename()
))), ))),
}?; }?;
if let Value::Builtins = val { if let Value::Builtins(weak) = val {
*self = Value::AttrSet(weak.upgrade().unwrap())
} else { } else {
*self = val; *self = val;
} }
@@ -378,7 +392,8 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
))); )));
} }
}; };
if let Value::Builtins = val { if let Value::Builtins(weak) = val {
*self = Value::AttrSet(weak.upgrade().unwrap())
} else { } else {
*self = val; *self = val;
} }
@@ -452,7 +467,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
PrimOp(primop) => Value::PrimOp(primop.name), PrimOp(primop) => Value::PrimOp(primop.name),
PartialPrimOp(primop) => Value::PartialPrimOp(primop.name), PartialPrimOp(primop) => Value::PartialPrimOp(primop.name),
Func(_) => Value::Func, Func(_) => Value::Func,
Builtins => Value::Repeated, Builtins(x) => x.upgrade().unwrap().to_public(vm, seen),
} }
} }
} }

View File

@@ -76,9 +76,16 @@ impl Debug for AttrSet {
impl Display for AttrSet { impl Display for AttrSet {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
use Value::*;
write!(f, "{{ ")?; write!(f, "{{ ")?;
for (k, v) in self.data.iter() { for (k, v) in self.data.iter() {
write!(f, "{k} = {v}; ")?; write!(f, "{k} = ")?;
match v {
AttrSet(_) => write!(f, "{{ ... }}"),
List(_) => write!(f, "[ ... ]"),
v => write!(f, "{v}")
}?;
write!(f, "; ")?;
} }
write!(f, "}}") write!(f, "}}")
} }

View File

@@ -44,8 +44,8 @@ impl<'jit, 'vm> Env<'jit, 'vm> {
.map(|(&k, v)| { .map(|(&k, v)| {
( (
k, k,
if let Value::Builtins = v { if let Value::Builtins(weak) = v {
Value::AttrSet(new.clone()) Value::AttrSet(weak.upgrade().unwrap())
} else { } else {
v.clone() v.clone()
}, },