feat: gc-arena (WIP, does not compile)
This commit is contained in:
128
src/env.rs
128
src/env.rs
@@ -1,121 +1,103 @@
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use hashbrown::{DefaultHashBuilder, HashMap};
|
||||
use gc_arena::{Collect, Gc, Mutation};
|
||||
|
||||
use crate::ty::internal::Value;
|
||||
use crate::ty::common::Map;
|
||||
|
||||
type Map<'bump, K, V> = HashMap<K, V, DefaultHashBuilder, &'bump Bump>;
|
||||
|
||||
#[derive(Clone)]
|
||||
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(Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct Env<'gc, K: Hash + Eq + Collect, V: Collect> {
|
||||
let_: Gc<'gc, LetEnv<'gc, K, V>>,
|
||||
with: Gc<'gc, With<'gc, K, V>>,
|
||||
last: Option<Gc<'gc, Env<'gc, K, V>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LetEnv<'bump, K: Hash + Eq + Clone, V: Clone> {
|
||||
map: LetNode<'bump, K, V>,
|
||||
last: Option<&'bump LetEnv<'bump, K, V>>,
|
||||
#[derive(Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct LetEnv<'gc, K: Hash + Eq + Collect, V: Collect> {
|
||||
map: LetNode<'gc, K, V>,
|
||||
last: Option<Gc<'gc, LetEnv<'gc, 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()
|
||||
}
|
||||
pub type VmEnv<'gc> = Env<'gc, usize, Value<'gc>>;
|
||||
|
||||
#[derive(Default, Clone, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct With<'gc, K: Hash + Eq + Collect, V: Collect> {
|
||||
map: Option<Gc<'gc, Map<K, V>>>,
|
||||
last: Option<Gc<'gc, With<'gc, 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("LetEnv")
|
||||
.field("map", &self.map)
|
||||
.field("last", &self.last)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub type VmEnv<'jit, 'vm> = Env<'vm, usize, Value<'jit, 'vm>>;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
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<'bump, K: Hash + Eq + Clone, V: Clone> {
|
||||
Let(&'bump Map<'bump, K, V>),
|
||||
#[derive(Collect)]
|
||||
#[collect(no_drop)]
|
||||
enum LetNode<'gc, K: Hash + Eq + Collect, V: Collect> {
|
||||
Let(Gc<'gc, Map<K, V>>),
|
||||
SingleArg(K, V),
|
||||
MultiArg(&'bump Map<'bump, K, V>),
|
||||
MultiArg(Gc<'gc, Map<K, V>>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Type {
|
||||
Arg,
|
||||
Let,
|
||||
With,
|
||||
}
|
||||
|
||||
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_: &*bump.alloc(LetEnv::new(map)),
|
||||
with: &*bump.alloc(With {
|
||||
impl<'gc, K: Hash + Eq + Clone + Collect, V: Clone + Collect> Env<'gc, K, V> {
|
||||
pub fn new(map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self {
|
||||
let_: LetEnv::new(map, mc),
|
||||
with: Gc::new(mc, With {
|
||||
map: None,
|
||||
last: None,
|
||||
}),
|
||||
last: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lookup(&self, symbol: &K) -> Option<&V> {
|
||||
pub fn lookup(&'gc self, symbol: &K) -> Option<&'gc V> {
|
||||
if let Some(val) = self.let_.lookup(symbol) {
|
||||
return Some(val);
|
||||
}
|
||||
self.with.lookup(symbol)
|
||||
}
|
||||
|
||||
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),
|
||||
pub fn enter_arg(self: Gc<'gc, Self>, ident: K, val: V, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Env {
|
||||
let_: self.let_.enter_arg(ident, val, mc),
|
||||
with: self.with,
|
||||
last: Some(self),
|
||||
})
|
||||
}
|
||||
|
||||
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),
|
||||
pub fn enter_let(self: Gc<'gc, Self>, map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self {
|
||||
let_: self.let_.enter_let(map, mc),
|
||||
with: self.with,
|
||||
last: Some(self),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn enter_with(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
|
||||
&*bump.alloc(Env {
|
||||
pub fn enter_with(self: Gc<'gc, Self>, map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Env {
|
||||
let_: self.let_,
|
||||
with: self.with.enter(map, bump),
|
||||
with: self.with.enter(map, mc),
|
||||
last: Some(self),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn leave(&self) -> &Self {
|
||||
pub fn leave(&self) -> Gc<'gc, Self> {
|
||||
self.last.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'bump, K: Hash + Eq + Clone, V: Clone> LetEnv<'bump, K, V> {
|
||||
pub fn new(map: &'bump HashMap<K, V, DefaultHashBuilder, &Bump>) -> Self {
|
||||
Self {
|
||||
impl<'gc, K: Hash + Eq + Clone + Collect, V: Clone + Collect> LetEnv<'gc, K, V> {
|
||||
pub fn new(map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc,Self {
|
||||
map: LetNode::Let(map),
|
||||
last: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lookup(&self, symbol: &K) -> Option<&V> {
|
||||
@@ -135,31 +117,31 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> LetEnv<'bump, K, V> {
|
||||
self.last.as_ref().and_then(|env| env.lookup(symbol))
|
||||
}
|
||||
|
||||
pub fn enter_arg(&'bump self, ident: K, val: V, bump: &'bump Bump) -> &'bump Self {
|
||||
&*bump.alloc(Self {
|
||||
pub fn enter_arg(self: Gc<'gc, Self>, ident: K, val: V, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self {
|
||||
map: LetNode::SingleArg(ident, val),
|
||||
last: Some(self),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn enter_let(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
|
||||
&*bump.alloc(Self {
|
||||
pub fn enter_let(self: Gc<'gc, Self>, map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self {
|
||||
map: LetNode::Let(map),
|
||||
last: Some(self),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'bump, K: Hash + Eq + Clone, V: Clone> With<'bump, K, V> {
|
||||
pub fn lookup(&'bump self, symbol: &K) -> Option<&'bump V> {
|
||||
impl<'gc, K: Hash + Eq + Clone + Collect, V: Clone + Collect> With<'gc, K, V> {
|
||||
pub fn lookup(&'gc self, symbol: &K) -> Option<&'gc 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(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
|
||||
&*bump.alloc(Self {
|
||||
pub fn enter(self: Gc<'gc, Self>, map: Gc<'gc, Map<K, V>>, mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self {
|
||||
map: Some(map),
|
||||
last: Some(self),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user