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::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
use crate::node::Node; use crate::node::Node;
mod core; mod core;
type RawEnvironment = HashMap<String, Node>; #[derive(Debug, Clone)]
pub struct Environment(Rc<RawEnvironment>);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Environment { pub struct RawEnvironment {
current: RefCell<RawEnvironment>, current: RefCell<HashMap<String, Node>>,
outer: Option<Box<Environment>>, outer: Option<Environment>,
} }
impl Environment { impl Environment {
pub fn new() -> Environment { pub fn new() -> Environment {
let current = RefCell::new(core::core()); let current = RefCell::new(core::core());
Environment { let env = RawEnvironment {
current, current,
outer: None, outer: None,
} };
Environment(Rc::new(env))
} }
pub fn get(&self, ident: &str) -> Option<Node> { 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()); 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 { pub fn wrap(&self, records: Vec<(String, Node)>) -> Environment {
Environment { let env = RawEnvironment {
current: RefCell::new(records.into_iter().collect()), 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) { fn set(&self, ident: String, val: Node) {
self.current.borrow_mut().insert(ident, val); self.0.current.borrow_mut().insert(ident, val);
} }
} }