scurry/interpreter/
env.rs

1use super::object::*;
2use crate::ast::Visibility;
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::rc::Rc;
6
7#[derive(Debug)]
8pub struct Env {
9    env: HashMap<String, Object>,
10    outer: Option<Rc<RefCell<Env>>>,
11}
12
13impl Env {
14    pub fn new() -> Self {
15        Self {
16            env: HashMap::new(),
17            outer: None,
18        }
19    }
20
21    pub fn new_enclosed(outer: Rc<RefCell<Env>>) -> Self {
22        let mut env = Env::new();
23        env.outer = Some(outer);
24        env
25    }
26
27    pub fn get(&self, name: &str) -> Option<Object> {
28        match self.env.get(name) {
29            Some(value) => Some(value.clone()),
30            None => match self.outer {
31                Some(ref outer) => outer.borrow().get(name),
32                None => None,
33            },
34        }
35    }
36
37    pub fn set(&mut self, name: String, val: Object) {
38        self.env.insert(name, val);
39    }
40
41    pub fn symbols(&self) -> HashMap<String, Object> {
42        let mut symbols = HashMap::new();
43        for (name, object) in self.env.clone() {
44            match object {
45                Object::Function { ref visibility, .. } => {
46                    if visibility == &Some(Visibility::Public) {
47                        symbols.insert(name, object);
48                    }
49                }
50                Object::Component(Component { ref visibility, .. }) => {
51                    if visibility == &Visibility::Public {
52                        symbols.insert(name, object);
53                    }
54                }
55                _ => {}
56            };
57        }
58        symbols
59    }
60}
61
62impl PartialEq for Env {
63    fn eq(&self, _other: &Self) -> bool {
64        true
65    }
66}
67
68impl Default for Env {
69    fn default() -> Self {
70        Self::new()
71    }
72}