logic_eval_util/
symbol.rs1use 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, Symbol::Opaque => Some(None), })?
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, Symbol::Opaque => Some(None), })?
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}