perf: RC environment
This now means environments are genuinely shared instead of clones
This commit is contained in:
parent
18ea5f34e6
commit
e6b487a09a
1 changed files with 18 additions and 12 deletions
30
src/env/mod.rs
vendored
30
src/env/mod.rs
vendored
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue