1use crate::Object;
2use std::cell::RefCell;
3use std::collections::HashMap;
4use std::rc::Rc;
5
6pub type Env = Rc<RefCell<Environment>>;
7
8#[derive(Debug, Default, Eq, Clone, PartialEq)]
9pub struct Environment {
10 store: HashMap<String, Rc<Object>>,
11 outer: Option<Env>,
12}
13
14impl Environment {
15 pub fn new_enclosed_environment(outer: &Env) -> Self {
16 let mut env: Environment = Default::default();
17 env.outer = Some(Rc::clone(outer));
18 return env;
19 }
20
21 pub fn get(&self, name: &str) -> Option<Rc<Object>> {
22 match self.store.get(name) {
23 Some(obj) => Some(Rc::clone(obj)),
24 None => {
25 if let Some(outer) = &self.outer {
26 return outer.borrow().get(name);
27 } else {
28 return None;
29 }
30 }
31 }
32 }
33
34 pub fn set(&mut self, name: String, val: Rc<Object>) {
35 self.store.insert(name, val);
36 }
37
38 pub fn visible_names(&self) -> Vec<String> {
39 let mut names = self
40 .outer
41 .as_ref()
42 .map(|outer| outer.borrow().visible_names())
43 .unwrap_or_default();
44 names.extend(self.store.keys().cloned());
45 names
46 }
47}