feat: bumpalo

This commit is contained in:
2025-05-23 12:09:53 +08:00
parent 53cbb37b00
commit a47a08b051
12 changed files with 130 additions and 127 deletions

View File

@@ -1,53 +1,58 @@
use std::fmt::Debug;
use std::{hash::Hash, rc::Rc};
use std::hash::Hash;
use hashbrown::HashMap;
use hashbrown::{DefaultHashBuilder, HashMap};
use bumpalo::Bump;
use crate::ty::internal::Value;
type Map<'bump, K, V> = HashMap<K, V, DefaultHashBuilder, &'bump Bump>;
#[derive(Clone)]
pub struct Env<K: Hash + Eq + Clone, V: Clone> {
let_: Rc<LetEnv<K, V>>,
with: Rc<With<K, V>>,
pub struct Env<'bump, K: Hash + Eq + Clone, V: Clone> {
let_: &'bump LetEnv<'bump, K, V>,
with: &'bump With<'bump, K, V>,
last: Option<&'bump Env<'bump, K, V>>,
}
#[derive(Clone)]
pub struct LetEnv<K: Hash + Eq + Clone, V: Clone> {
map: LetNode<K, V>,
last: Option<Rc<LetEnv<K, V>>>,
pub struct LetEnv<'bump, K: Hash + Eq + Clone, V: Clone> {
map: LetNode<'bump, K, V>,
last: Option<&'bump LetEnv<'bump, K, V>>,
}
impl<K: Debug + Hash + Eq + Clone, V: Debug + Clone> Debug for Env<K, V> {
impl<K: Debug + Hash + Eq + Clone, V: Debug + Clone> Debug for Env<'_, K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Env")
.field("let_", &self.let_)
.field("with", &self.with)
.field("last", &self.last)
.finish()
}
}
impl<K: Debug + Hash + Eq + Clone, V: Debug + Clone> Debug for LetEnv<K, V> {
impl<K: Debug + Hash + Eq + Clone, V: Debug + Clone> Debug for LetEnv<'_, K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Env")
f.debug_struct("LetEnv")
.field("map", &self.map)
.field("last", &self.last)
.finish()
}
}
pub type VmEnv<'jit, 'vm> = Env<usize, Value<'jit, 'vm>>;
pub type VmEnv<'jit, 'vm> = Env<'vm, usize, Value<'jit, 'vm>>;
#[derive(Debug, Default, Clone)]
pub struct With<K: Hash + Eq, V> {
map: Option<Rc<HashMap<K, V>>>,
last: Option<Rc<With<K, V>>>,
pub struct With<'bump, K: Hash + Eq, V> {
map: Option<&'bump Map<'bump, K, V>>,
last: Option<&'bump With<'bump, K, V>>,
}
#[derive(Debug, Clone)]
enum LetNode<K: Hash + Eq, V> {
Let(Rc<HashMap<K, V>>),
enum LetNode<'bump, K: Hash + Eq + Clone, V: Clone> {
Let(&'bump Map<'bump, K, V>),
SingleArg(K, V),
MultiArg(Rc<HashMap<K, V>>),
MultiArg(&'bump Map<'bump, K, V>),
}
#[derive(Debug, Clone, Copy)]
@@ -57,15 +62,15 @@ pub enum Type {
With,
}
impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
pub fn new(map: Rc<HashMap<K, V>>) -> Self {
impl<'bump, K: Hash + Eq + Clone, V: Clone> Env<'bump, K, V> {
pub fn new(map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> Self {
Self {
let_: LetEnv::new(map).into(),
with: With {
let_: &*bump.alloc(LetEnv::new(map)),
with: &*bump.alloc(With {
map: None,
last: None,
}
.into(),
}),
last: None
}
}
@@ -76,29 +81,37 @@ impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
self.with.lookup(symbol)
}
pub fn enter_arg(self: &mut Rc<Self>, ident: K, val: V) {
Rc::make_mut(self).let_.enter_arg(ident, val);
pub fn enter_arg(&'bump self, ident: K, val: V, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Env {
let_: self.let_.enter_arg(ident, val, bump),
with: self.with,
last: Some(self)
})
}
pub fn enter_let(self: &mut Rc<Self>, map: Rc<HashMap<K, V>>) {
Rc::make_mut(self).let_.enter_let(map);
pub fn enter_let(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Env {
let_: self.let_.enter_let(map, bump),
with: self.with,
last: Some(self)
})
}
pub fn enter_with(self: &mut Rc<Self>, map: Rc<HashMap<K, V>>) {
Rc::make_mut(self).with.enter(map);
pub fn enter_with(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Env {
let_: self.let_,
with: self.with.enter(map, bump),
last: Some(self)
})
}
pub fn leave_let(self: &mut Rc<Self>) {
Rc::make_mut(self).let_.leave();
}
pub fn leave_with(self: &mut Rc<Self>) {
Rc::make_mut(self).with.leave();
pub fn leave(&self) -> &Self {
self.last.unwrap()
}
}
impl<K: Hash + Eq + Clone, V: Clone> LetEnv<K, V> {
pub fn new(map: Rc<HashMap<K, V>>) -> Self {
impl<'bump, K: Hash + Eq + Clone, V: Clone> LetEnv<'bump, K, V> {
pub fn new(map: &'bump HashMap<K, V, DefaultHashBuilder, &Bump>) -> Self {
Self {
map: LetNode::Let(map),
last: None,
@@ -122,45 +135,33 @@ impl<K: Hash + Eq + Clone, V: Clone> LetEnv<K, V> {
self.last.as_ref().and_then(|env| env.lookup(symbol))
}
pub fn enter_arg(self: &mut Rc<Self>, ident: K, val: V) {
let cloned = self.clone();
let mutref = Rc::make_mut(self);
mutref.last = Some(cloned);
mutref.map = LetNode::SingleArg(ident, val);
pub fn enter_arg(&'bump self, ident: K, val: V, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self {
map: LetNode::SingleArg(ident, val),
last: Some(self)
})
}
pub fn enter_let(self: &mut Rc<Self>, map: Rc<HashMap<K, V>>) {
let cloned = self.clone();
let mutref = Rc::make_mut(self);
mutref.last = Some(cloned);
mutref.map = LetNode::Let(map);
}
pub fn leave(self: &mut Rc<Self>) {
let refmut = Rc::make_mut(self);
let last = refmut.last.take().unwrap();
*self = last;
pub fn enter_let(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self {
map: LetNode::Let(map),
last: Some(self)
})
}
}
impl<K: Hash + Eq + Clone, V: Clone> With<K, V> {
pub fn lookup(&self, symbol: &K) -> Option<&V> {
impl<'bump, K: Hash + Eq + Clone, V: Clone> With<'bump, K, V> {
pub fn lookup(&'bump self, symbol: &K) -> Option<&'bump V> {
if let Some(val) = self.map.as_ref()?.get(symbol) {
return Some(val);
}
self.last.as_ref().and_then(|env| env.lookup(symbol))
}
pub fn enter(self: &mut Rc<Self>, map: Rc<HashMap<K, V>>) {
let cloned = self.clone();
let mutref = Rc::make_mut(self);
mutref.last = Some(cloned);
mutref.map = Some(map);
}
pub fn leave(self: &mut Rc<Self>) {
let refmut = Rc::make_mut(self);
let last = refmut.last.take().unwrap();
*self = last;
pub fn enter(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self {
map: Some(map),
last: Some(self)
})
}
}