Skip to main content

object/
environment.rs

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        return Environment {
17            outer: Some(Rc::clone(outer)),
18            ..Default::default()
19        };
20    }
21
22    pub fn get(&self, name: &str) -> Option<Rc<Object>> {
23        match self.store.get(name) {
24            Some(obj) => Some(Rc::clone(obj)),
25            None => {
26                if let Some(outer) = &self.outer {
27                    return outer.borrow().get(name);
28                } else {
29                    return None;
30                }
31            }
32        }
33    }
34
35    pub fn set(&mut self, name: String, val: Rc<Object>) {
36        self.store.insert(name, val);
37    }
38
39    pub fn visible_names(&self) -> Vec<String> {
40        let mut names = self
41            .outer
42            .as_ref()
43            .map(|outer| outer.borrow().visible_names())
44            .unwrap_or_default();
45        names.extend(self.store.keys().cloned());
46        names
47    }
48}