From e17c48f2d93a74086e8ae7f50bbb5f2005e22a5a Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Mon, 19 May 2025 08:37:40 +0800 Subject: [PATCH] fix: builtins impl --- src/builtins/mod.rs | 8 +++++--- src/ty/internal/mod.rs | 39 +++++++++++++++++++++++++++------------ src/ty/public.rs | 9 ++++++++- src/vm/env.rs | 4 ++-- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index 939d8d2..ae91268 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -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)); } - let attrs: Rc<_> = AttrSet::from_inner(map).into(); - let mut builtins = Value::AttrSet(attrs); - builtins.push_attr(vm.new_sym("builtins"), Value::Builtins); + let attrs: Rc<_> = Rc::new_cyclic(|weak| { + map.insert(vm.new_sym("builtins"), Value::Builtins(weak.clone())); + AttrSet::from_inner(map) + }); + let builtins = Value::AttrSet(attrs); env.insert(vm.new_sym("builtins"), builtins); env diff --git a/src/ty/internal/mod.rs b/src/ty/internal/mod.rs index fc475f6..94634e9 100644 --- a/src/ty/internal/mod.rs +++ b/src/ty/internal/mod.rs @@ -2,7 +2,7 @@ use hashbrown::HashSet; use std::cell::OnceCell; use std::cell::RefCell; use std::hash::Hash; -use std::rc::Rc; +use std::rc::{Rc, Weak}; use derive_more::{IsVariant, Unwrap}; @@ -24,7 +24,7 @@ pub use func::*; pub use list::List; pub use primop::*; -#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)] +#[derive(Debug, IsVariant, Unwrap, Clone)] pub enum Value<'jit: 'vm, 'vm> { Const(Const), Thunk(Rc>), @@ -35,7 +35,7 @@ pub enum Value<'jit: 'vm, 'vm> { PrimOp(Rc>), PartialPrimOp(Rc>), Func(Rc>), - Builtins, + Builtins(Weak>), } impl Hash for Value<'_, '_> { @@ -52,7 +52,7 @@ impl Hash for Value<'_, '_> { PrimOp(x) => (x.as_ref() as *const self::PrimOp).hash(state), PartialPrimOp(x) => (x.as_ref() as *const self::PartialPrimOp).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), (AttrSet(a), AttrSet(b)) => a.eq_impl(b, vm), (List(a), List(b)) => a.eq(b), - (Builtins, AttrSet(attrs)) => attrs.has_attr(vm.new_sym("builtins")), - (AttrSet(attrs), Builtins) => 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")), + _ => 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, } } @@ -111,7 +124,7 @@ impl<'v, 'vm: 'v, 'jit: 'vm> Value<'jit, 'vm> { PrimOp(x) => R::PrimOp(x), PartialPrimOp(x) => R::PartialPrimOp(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)), PartialPrimOp(x) => M::PartialPrimOp(Rc::make_mut(x)), Func(x) => M::Func(x), - Builtins => unreachable!(), + Builtins(_) => unreachable!(), } } } @@ -151,7 +164,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> { PrimOp(_) => "lambda", PartialPrimOp(_) => "lambda", Func(_) => "lambda", - Builtins => "set", + Builtins(_) => "set", } } @@ -360,7 +373,8 @@ impl<'jit, 'vm> Value<'jit, 'vm> { self.typename() ))), }?; - if let Value::Builtins = val { + if let Value::Builtins(weak) = val { + *self = Value::AttrSet(weak.upgrade().unwrap()) } else { *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 { *self = val; } @@ -452,7 +467,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> { PrimOp(primop) => Value::PrimOp(primop.name), PartialPrimOp(primop) => Value::PartialPrimOp(primop.name), Func(_) => Value::Func, - Builtins => Value::Repeated, + Builtins(x) => x.upgrade().unwrap().to_public(vm, seen), } } } diff --git a/src/ty/public.rs b/src/ty/public.rs index 35846ff..323e5f5 100644 --- a/src/ty/public.rs +++ b/src/ty/public.rs @@ -76,9 +76,16 @@ impl Debug for AttrSet { impl Display for AttrSet { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + use Value::*; write!(f, "{{ ")?; 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, "}}") } diff --git a/src/vm/env.rs b/src/vm/env.rs index 8995f3a..b7b5c65 100644 --- a/src/vm/env.rs +++ b/src/vm/env.rs @@ -44,8 +44,8 @@ impl<'jit, 'vm> Env<'jit, 'vm> { .map(|(&k, v)| { ( k, - if let Value::Builtins = v { - Value::AttrSet(new.clone()) + if let Value::Builtins(weak) = v { + Value::AttrSet(weak.upgrade().unwrap()) } else { v.clone() },