Skip to main content

hiko_syntax/
intern.rs

1use std::collections::HashMap;
2use std::fmt;
3
4#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
5pub struct Symbol(u32);
6
7impl fmt::Debug for Symbol {
8    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9        write!(f, "Symbol({})", self.0)
10    }
11}
12
13#[derive(Clone)]
14pub struct StringInterner {
15    map: HashMap<String, Symbol>,
16    strings: Vec<String>,
17}
18
19impl Default for StringInterner {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl StringInterner {
26    pub fn new() -> Self {
27        Self {
28            map: HashMap::new(),
29            strings: Vec::new(),
30        }
31    }
32
33    pub fn intern(&mut self, s: &str) -> Symbol {
34        if let Some(&sym) = self.map.get(s) {
35            return sym;
36        }
37        let sym = Symbol(self.strings.len() as u32);
38        self.strings.push(s.to_string());
39        self.map.insert(s.to_string(), sym);
40        sym
41    }
42
43    pub fn resolve(&self, sym: Symbol) -> &str {
44        &self.strings[sym.0 as usize]
45    }
46}