Skip to main content

logic_eval_util/
symbol.rs

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