feat: at least it compiles, right?

This commit is contained in:
2025-06-12 20:12:31 +08:00
parent 7293cb9f75
commit 49255948ff
22 changed files with 383 additions and 251 deletions

View File

@@ -1,33 +1,34 @@
use std::hash::Hash;
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use ecow::EcoString;
use hashbrown::HashMap;
use crate::ty::internal::Value;
use crate::stack::Stack;
use crate::ty::internal::{EnvRef, Value};
pub struct Env<K: Hash + Eq, V> {
let_: Rc<LetEnv<V>>,
with: Rc<With<K, V>>,
args: Rc<Vec<V>>,
#[derive(Clone)]
pub struct VmEnv {
let_: Rc<RefCell<Stack<Vec<Value>, 1000>>>,
with: Rc<With>,
args: Rc<RefCell<Stack<Value, 1000>>>,
new: bool,
pub id: usize,
}
pub struct LetEnv<V> {
map: Vec<V>,
last: Option<Rc<LetEnv<V>>>,
#[derive(Clone)]
pub struct VmEnvWeak {
let_: Weak<RefCell<Stack<Vec<Value>, 1000>>>,
with: Weak<With>,
args: Weak<RefCell<Stack<Value, 1000>>>,
new: bool,
pub id: usize,
}
pub type VmEnv = Env<EcoString, Value>;
#[derive(Default, Clone)]
pub struct With<K: Hash + Eq, V> {
map: Option<Rc<HashMap<K, V>>>,
last: Option<Rc<With<K, V>>>,
}
enum LetNode<K: Hash + Eq, V> {
Let(Rc<HashMap<K, V>>),
MultiArg(Rc<HashMap<K, V>>),
pub struct With {
map: Option<Rc<HashMap<EcoString, Value>>>,
last: Option<Rc<With>>,
}
#[derive(Clone, Copy)]
@@ -37,27 +38,30 @@ pub enum Type {
With,
}
impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
pub fn new(map: Vec<V>) -> Self {
impl VmEnv {
pub fn new() -> Self {
Self {
let_: LetEnv::new(map),
let_: Rc::default(),
with: With {
map: None,
last: None,
}.into(),
args: Vec::new().into(),
}
.into(),
args: Rc::default(),
new: false,
id: 0,
}
}
pub fn lookup_arg(&self, level: usize) -> &V {
&self.args[self.args.len() - level - 1]
pub fn lookup_let(&self, level: usize, idx: usize) -> Value {
self.let_.borrow()[level][idx].clone()
}
pub fn lookup_let(&self, level: usize, idx: usize) -> &V {
self.let_.lookup(level, idx)
pub fn lookup_arg(&self, level: usize) -> Value {
self.args.borrow()[level].clone()
}
pub fn lookup_with(&self, symbol: &K) -> Option<&V> {
pub fn lookup_with(&self, symbol: &EcoString) -> Option<Value> {
self.with.lookup(symbol)
}
@@ -65,69 +69,103 @@ impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
self.with.map.is_some()
}
#[must_use]
pub fn enter_arg(&self, val: V) -> Self {
let mut args = self.args.clone();
Rc::make_mut(&mut args).push(val);
Self {
let_: self.let_.clone(),
with: self.with.clone(),
args,
pub fn enter_let(&mut self, mut map: Vec<Value>) {
if Rc::strong_count(&self.let_) > 1 {
self.let_ = Rc::new_cyclic(|weak| {
let weak = VmEnvWeak {
let_: weak.clone(),
with: Rc::downgrade(&self.with),
args: Rc::downgrade(&self.args),
new: self.new,
id: self.id,
};
map.iter_mut().for_each(|val| {
if let Value::Thunk(thunk) = val {
thunk.capture(EnvRef::Weak(weak.clone()));
}
});
let new = self.let_.as_ref().clone();
new.borrow_mut().push(map).unwrap();
new
})
} else {
let weak = self.downgrade();
map.iter_mut().for_each(|val| {
if let Value::Thunk(thunk) = val {
thunk.capture(EnvRef::Weak(weak.clone()));
}
});
let _ = self.let_.borrow_mut().push(map);
}
}
#[must_use]
pub fn enter_let(&self, map: Vec<V>) -> Self {
Self {
let_: self.let_.clone().enter_let(map),
with: self.with.clone(),
args: self.args.clone(),
pub fn enter_arg(&mut self, val: Value) {
if Rc::strong_count(&self.args) > 1 {
self.args = Rc::new(self.args.as_ref().clone());
}
self.args.borrow_mut().push(val).unwrap()
}
pub fn pop_let(&mut self) {
if Rc::strong_count(&self.let_) > 1 {
self.let_ = Rc::new(self.let_.as_ref().clone());
}
self.let_.borrow_mut().pop();
}
pub fn pop_arg(&mut self) {
if Rc::strong_count(&self.args) > 1 {
self.args = Rc::new(self.args.as_ref().clone());
}
self.args.borrow_mut().pop();
}
#[must_use]
pub fn enter_with(&self, map: Rc<HashMap<K, V>>) -> Self {
pub fn enter_with(&self, map: Rc<HashMap<EcoString, Value>>) -> Self {
Self {
let_: self.let_.clone(),
with: self.with.clone().enter(map),
args: self.args.clone(),
new: self.new,
id: self.id + 1,
}
}
pub fn downgrade(&self) -> VmEnvWeak {
VmEnvWeak {
let_: Rc::downgrade(&self.let_),
with: Rc::downgrade(&self.with),
args: Rc::downgrade(&self.args),
id: self.id,
new: self.new,
}
}
}
impl<V: Clone> LetEnv<V> {
pub fn new(map: Vec<V>) -> Rc<Self> {
Rc::new(Self { map, last: None })
}
pub fn lookup(&self, level: usize, idx: usize) -> &V {
let mut cur = self;
for _ in 0..level {
cur = cur.last.as_ref().unwrap();
}
&cur.map[idx]
}
pub fn enter_let(self: Rc<Self>, map: Vec<V>) -> Rc<Self> {
Rc::new(Self {
map,
last: Some(self),
})
}
}
impl<K: Hash + Eq + Clone, V: Clone> With<K, V> {
pub fn lookup(&self, symbol: &K) -> Option<&V> {
impl With {
pub fn lookup(&self, symbol: &EcoString) -> Option<Value> {
if let Some(val) = self.map.as_ref()?.get(symbol) {
return Some(val);
return Some(val.clone());
}
self.last.as_ref().and_then(|env| env.lookup(symbol))
}
pub fn enter(self: Rc<Self>, map: Rc<HashMap<K, V>>) -> Rc<Self> {
pub fn enter(self: Rc<Self>, map: Rc<HashMap<EcoString, Value>>) -> Rc<Self> {
Rc::new(Self {
map: Some(map),
last: Some(self),
})
}
}
impl VmEnvWeak {
pub fn upgrade(&self) -> VmEnv {
VmEnv {
let_: self.let_.upgrade().unwrap(),
with: self.with.upgrade().unwrap(),
args: self.args.upgrade().unwrap(),
id: self.id,
new: self.new,
}
}
}