fix: PartialFunc

This commit is contained in:
2025-06-22 01:19:16 +08:00
parent 75e8705098
commit 20b5516101
13 changed files with 207 additions and 219 deletions

View File

@@ -1,14 +1,13 @@
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::fmt::Debug;
use std::rc::Rc;
use ecow::EcoString;
use hashbrown::HashMap;
use crate::error::Result;
use crate::stack::Stack;
use crate::ty::internal::Value;
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Env {
cache: Vec<HashMap<usize, Value>>,
with: Vec<Rc<HashMap<EcoString, Value>>>,
@@ -16,28 +15,6 @@ pub struct Env {
pub args_len: usize,
}
#[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,
}
#[derive(Default, Clone)]
pub struct With {
map: Option<Rc<HashMap<EcoString, Value>>>,
last: Option<Rc<With>>,
}
#[derive(Clone, Copy)]
pub enum Type {
Arg,
Let,
With,
}
impl Env {
pub fn new() -> Self {
Self {
@@ -48,20 +25,38 @@ impl Env {
}
}
pub fn enter_cache_level<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> (T, HashMap<usize, Value>) {
pub fn with_new_cache<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> (T, HashMap<usize, Value>) {
self.cache.push(HashMap::new());
let ret = f(self);
(ret, self.cache.pop().unwrap())
}
pub fn pop_cache_level(&mut self) -> HashMap<usize, Value> {
self.cache.pop().unwrap()
pub fn with_cache<T>(
&mut self,
cache: HashMap<usize, Value>,
f: impl FnOnce(&mut Self) -> T,
) -> (T, HashMap<usize, Value>) {
self.cache.push(cache);
let ret = f(self);
(ret, self.cache.pop().unwrap())
}
pub fn insert_cache(&mut self, idx: usize, val: Value) {
self.cache.last_mut().unwrap().insert(idx, val);
}
pub fn insert_cache_lazy(
&mut self,
idx: usize,
f: impl FnOnce(&mut Self) -> Result<Value>,
) -> Result<()> {
if self.cache.last().unwrap().get(&idx).is_none() {
let val = f(self)?;
self.cache.last_mut().unwrap().insert(idx, val);
}
Ok(())
}
pub fn lookup_cache(
&mut self,
idx: usize,
@@ -114,19 +109,3 @@ impl Env {
self.with.push(map)
}
}
impl With {
pub fn lookup(&self, symbol: &EcoString) -> Option<Value> {
if let Some(val) = self.map.as_ref()?.get(symbol) {
return Some(val.clone());
}
self.last.as_ref().and_then(|env| env.lookup(symbol))
}
pub fn enter(self: Rc<Self>, map: Rc<HashMap<EcoString, Value>>) -> Rc<Self> {
Rc::new(Self {
map: Some(map),
last: Some(self),
})
}
}