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