perf: RC environment

This now means environments are genuinely shared instead of clones
This commit is contained in:
Roman Godmaire 2024-05-04 19:03:04 -04:00
parent 18ea5f34e6
commit e6b487a09a

30
src/env/mod.rs vendored
View file

@ -1,44 +1,50 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use crate::node::Node;
mod core;
type RawEnvironment = HashMap<String, Node>;
#[derive(Debug, Clone)]
pub struct Environment(Rc<RawEnvironment>);
#[derive(Debug, Clone)]
pub struct Environment {
current: RefCell<RawEnvironment>,
outer: Option<Box<Environment>>,
pub struct RawEnvironment {
current: RefCell<HashMap<String, Node>>,
outer: Option<Environment>,
}
impl Environment {
pub fn new() -> Environment {
let current = RefCell::new(core::core());
Environment {
let env = RawEnvironment {
current,
outer: None,
}
};
Environment(Rc::new(env))
}
pub fn get(&self, ident: &str) -> Option<Node> {
if let Some(val) = self.current.borrow().get(ident) {
if let Some(val) = self.0.current.borrow().get(ident) {
return Some(val.clone());
}
self.outer.as_ref()?.get(ident)
self.0.outer.as_ref()?.get(ident)
}
pub fn wrap(&self, records: Vec<(String, Node)>) -> Environment {
Environment {
let env = RawEnvironment {
current: RefCell::new(records.into_iter().collect()),
outer: Some(Box::new(self.clone())),
}
outer: Some(self.clone()),
};
Environment(Rc::new(env))
}
fn set(&self, ident: String, val: Node) {
self.current.borrow_mut().insert(ident, val);
self.0.current.borrow_mut().insert(ident, val);
}
}