Skip to main content

logic_eval_util/
symbol.rs

1use crate::Map;
2use std::{borrow::Borrow, hash::Hash};
3
4#[derive(Debug)]
5pub struct SymbolTable<K, V> {
6    map: Map<K, Vec<Symbol<V>>>,
7}
8
9impl<K, V> SymbolTable<K, V> {
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_transparent_block(&mut self) {
19        for v in self.map.values_mut() {
20            v.push(Symbol::Transparent);
21        }
22    }
23
24    pub fn push_opaque_block(&mut self) {
25        for v in self.map.values_mut() {
26            v.push(Symbol::Opaque);
27        }
28    }
29
30    pub fn pop_block(&mut self) {
31        for v in self.map.values_mut() {
32            while let Some(Symbol::Data(_)) = v.pop() {}
33        }
34        self.map.retain(|_, v| !v.is_empty());
35    }
36}
37
38impl<K: Hash + Eq, V> SymbolTable<K, V> {
39    pub fn push(&mut self, name: K, symbol: V) {
40        if let Some(v) = self.map.get_mut(&name) {
41            v.push(Symbol::Data(symbol));
42        } else {
43            self.map.insert(name, vec![Symbol::Data(symbol)]);
44        }
45    }
46
47    pub fn pop<Q>(&mut self, name: &Q) -> Option<V>
48    where
49        K: Borrow<Q>,
50        Q: Hash + Eq + ?Sized,
51    {
52        match self.map.get_mut(name)?.pop()? {
53            Symbol::Data(v) => Some(v),
54            Symbol::Transparent | Symbol::Opaque => None,
55        }
56    }
57
58    pub fn get<Q>(&self, name: &Q) -> Option<&V>
59    where
60        K: Borrow<Q>,
61        Q: Hash + Eq + ?Sized,
62    {
63        self.map.get(name)?.iter().rev().find_map(|x| match x {
64            Symbol::Data(v) => Some(Some(v)),
65            Symbol::Transparent => None,  // Continue the iteration.
66            Symbol::Opaque => Some(None), // Stop the iteration.
67        })?
68    }
69
70    pub fn get_mut<Q>(&mut self, name: &Q) -> Option<&mut V>
71    where
72        K: Borrow<Q>,
73        Q: Hash + Eq + ?Sized,
74    {
75        self.map
76            .get_mut(name)?
77            .iter_mut()
78            .rev()
79            .find_map(|x| match x {
80                Symbol::Data(v) => Some(Some(v)),
81                Symbol::Transparent => None,  // Continue the iteration.
82                Symbol::Opaque => Some(None), // Stop the iteration.
83            })?
84    }
85}
86
87impl<K, V> Default for SymbolTable<K, V> {
88    fn default() -> Self {
89        Self {
90            map: Map::default(),
91        }
92    }
93}
94
95#[derive(Debug)]
96enum Symbol<T> {
97    Data(T),
98    Transparent,
99    Opaque,
100}