feat(gc): WIP

This commit is contained in:
2025-06-02 12:00:38 +08:00
parent 20b2b6f1ef
commit d3442e87e7
7 changed files with 72 additions and 77 deletions

View File

@@ -11,6 +11,7 @@ pub struct Env<'gc, K: Hash + Eq + Collect<'gc>, V: Collect<'gc>> {
let_: Gc<'gc, LetEnv<'gc, V>>,
with: Gc<'gc, With<'gc, K, V>>,
args: Vec<V>,
gc_alloced: Vec<Gc<'gc, V>>,
last: Option<Gc<'gc, Env<'gc, K, V>>>,
}
@@ -59,16 +60,17 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc,
},
),
args: Vec::new(),
gc_alloced: Vec::new(),
last: None,
},
)
}
pub fn lookup_arg(&self, level: usize) -> V {
self.args[self.args.len() - level - 1].clone()
pub fn lookup_arg(&self, level: usize) -> &V {
&self.args[self.args.len() - level - 1]
}
pub fn lookup_let(&self, level: usize, idx: usize) -> V {
pub fn lookup_let(&self, level: usize, idx: usize) -> &V {
self.let_.lookup(level, idx)
}
@@ -90,6 +92,7 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc,
let_: self.let_,
with: self.with,
last: Some(self),
gc_alloced: Vec::new(),
args
},
)
@@ -107,6 +110,7 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc,
let_: self.let_.enter_let(map, mc),
with: self.with,
args: self.args.clone(),
gc_alloced: Vec::new(),
last: Some(self),
},
)
@@ -124,11 +128,19 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc,
let_: self.let_,
with: self.with.enter(map, mc),
args: self.args.clone(),
gc_alloced: Vec::new(),
last: Some(self),
},
)
}
#[inline]
pub fn alloc_gc(&mut self, val: V, mc: &Mutation<'gc>) -> &'gc V {
let gc = Gc::new(mc, val);
self.gc_alloced.push(gc);
gc.as_ref()
}
pub fn leave(&self) -> Gc<'gc, Self> {
self.last.unwrap()
}
@@ -145,13 +157,13 @@ impl<'gc, V: Clone + Collect<'gc>> LetEnv<'gc, V> {
)
}
pub fn lookup(&self, level: usize, idx: usize) -> V {
pub fn lookup(&self, level: usize, idx: usize) -> &V {
let mut cur = self;
for _ in 0..level {
let last = cur.last.unwrap();
cur = last.as_ref();
}
cur.map[idx].clone()
&cur.map[idx]
}
pub fn enter_let(