1use indexmap::IndexMap;
13use std::cell::RefCell;
14use std::fmt;
15use std::sync::{Arc, Weak};
16
17use super::value::Value;
18
19pub type Env<'a> = Arc<Environment<'a>>;
20
21pub type WeakEnv<'a> = Weak<Environment<'a>>;
25
26pub struct Environment<'a> {
27 vars: RefCell<IndexMap<String, Value<'a>>>,
28 parent: Option<Env<'a>>,
29}
30
31impl<'a> Environment<'a> {
32 pub fn root() -> Env<'a> {
33 Arc::new(Environment {
34 vars: RefCell::new(IndexMap::new()),
35 parent: None,
36 })
37 }
38
39 pub fn child(parent: &Env<'a>) -> Env<'a> {
40 Arc::new(Environment {
41 vars: RefCell::new(IndexMap::new()),
42 parent: Some(parent.clone()),
43 })
44 }
45
46 pub fn get(&self, name: &str) -> Option<Value<'a>> {
48 if let Some(v) = self.vars.borrow().get(name) {
49 return Some(v.clone());
50 }
51 self.parent.as_ref().and_then(|p| p.get(name))
52 }
53
54 pub fn defined_here(&self, name: &str) -> bool {
55 self.vars.borrow().contains_key(name)
56 }
57
58 pub fn defined_in_ancestors(&self, name: &str) -> bool {
59 match &self.parent {
60 Some(p) => p.defined_here(name) || p.defined_in_ancestors(name),
61 None => false,
62 }
63 }
64
65 pub fn insert(&self, name: &str, v: Value<'a>) {
67 self.vars.borrow_mut().insert(name.to_string(), v);
68 }
69}
70
71impl fmt::Debug for Environment<'_> {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "<env: {} vars>", self.vars.borrow().len())
74 }
75}