Skip to main content

rexlang_engine/
env.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4use rexlang_ast::expr::Symbol;
5
6use crate::value::Pointer;
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct Env(Arc<EnvFrame>);
10
11#[derive(Default, Debug, PartialEq)]
12struct EnvFrame {
13    parent: Option<Env>,
14    bindings: HashMap<Symbol, Pointer>,
15}
16
17impl Env {
18    pub fn new() -> Self {
19        Env(Arc::new(EnvFrame::default()))
20    }
21
22    pub fn extend(&self, name: Symbol, value: Pointer) -> Self {
23        let mut bindings = HashMap::new();
24        bindings.insert(name, value);
25        Env(Arc::new(EnvFrame {
26            parent: Some(self.clone()),
27            bindings,
28        }))
29    }
30
31    pub fn extend_many(&self, bindings: HashMap<Symbol, Pointer>) -> Self {
32        Env(Arc::new(EnvFrame {
33            parent: Some(self.clone()),
34            bindings,
35        }))
36    }
37
38    pub fn get(&self, name: &Symbol) -> Option<Pointer> {
39        let mut current: Option<&Env> = Some(self);
40        while let Some(env) = current {
41            if let Some(v) = env.0.bindings.get(name) {
42                return Some(*v);
43            }
44            current = env.0.parent.as_ref();
45        }
46        None
47    }
48
49    pub(crate) fn parent(&self) -> Option<&Env> {
50        self.0.parent.as_ref()
51    }
52
53    pub(crate) fn bindings(&self) -> &HashMap<Symbol, Pointer> {
54        &self.0.bindings
55    }
56}
57
58impl Default for Env {
59    fn default() -> Self {
60        Self::new()
61    }
62}