logic_eval_util/
symbol.rs

1use crate::Map;
2use any_intern::Interned;
3
4#[derive(Debug)]
5pub struct SymbolTable<'int, T> {
6    map: Map<Interned<'int, str>, Vec<Symbol<T>>>,
7}
8
9impl<'int, T> SymbolTable<'int, T> {
10    pub fn clear(&mut self) {
11        self.map.clear();
12    }
13
14    pub fn is_empty(&self) -> bool {
15        self.map.is_empty()
16    }
17
18    pub fn push(&mut self, name: Interned<'int, str>, symbol: T) {
19        if let Some(v) = self.map.get_mut(&name) {
20            v.push(Symbol::Data(symbol));
21        } else {
22            self.map.insert(name, vec![Symbol::Data(symbol)]);
23        }
24    }
25
26    pub fn pop(&mut self, name: Interned<'int, str>) -> Option<T> {
27        match self.map.get_mut(&name)?.pop()? {
28            Symbol::Data(v) => Some(v),
29            Symbol::Transparent | Symbol::Opaque => None,
30        }
31    }
32
33    pub fn push_transparent_block(&mut self) {
34        for v in self.map.values_mut() {
35            v.push(Symbol::Transparent);
36        }
37    }
38
39    pub fn push_opaque_block(&mut self) {
40        for v in self.map.values_mut() {
41            v.push(Symbol::Opaque);
42        }
43    }
44
45    pub fn pop_block(&mut self) {
46        for v in self.map.values_mut() {
47            while let Some(Symbol::Data(_)) = v.pop() {}
48        }
49        self.map.retain(|_, v| !v.is_empty());
50    }
51
52    pub fn get(&self, name: Interned<'int, str>) -> Option<&T> {
53        self.map.get(&name)?.iter().rev().find_map(|x| match x {
54            Symbol::Data(v) => Some(Some(v)),
55            Symbol::Transparent => None,  // Continue the iteration.
56            Symbol::Opaque => Some(None), // Stop the iteration.
57        })?
58    }
59
60    pub fn get_mut(&mut self, name: Interned<'int, str>) -> Option<&mut T> {
61        self.map
62            .get_mut(&name)?
63            .iter_mut()
64            .rev()
65            .find_map(|x| match x {
66                Symbol::Data(v) => Some(Some(v)),
67                Symbol::Transparent => None,  // Continue the iteration.
68                Symbol::Opaque => Some(None), // Stop the iteration.
69            })?
70    }
71}
72
73impl<T> Default for SymbolTable<'_, T> {
74    fn default() -> Self {
75        Self {
76            map: Map::default(),
77        }
78    }
79}
80
81#[derive(Debug)]
82enum Symbol<T> {
83    Data(T),
84    Transparent,
85    Opaque,
86}