mech_core/program/
symbol_table.rs

1use crate::*;
2
3// Symbol Table 
4// ----------------------------------------------------------------------------
5
6pub type SymbolTableRef= Ref<SymbolTable>;
7
8#[derive(Clone, Debug)]
9pub struct SymbolTable {
10  pub symbols: HashMap<u64,ValRef>,
11  pub mutable_variables: HashMap<u64,ValRef>,
12  pub dictionary: Ref<Dictionary>,
13  pub reverse_lookup: HashMap<*const Ref<Value>, u64>,
14}
15
16impl SymbolTable {
17
18  pub fn new() -> SymbolTable {
19    Self {
20      symbols: HashMap::new(),
21      mutable_variables: HashMap::new(),
22      dictionary: Ref::new(HashMap::new()),
23      reverse_lookup: HashMap::new(),
24    }
25  }
26
27  pub fn get_symbol_name_by_id(&self, id: u64) -> Option<String> {
28    self.dictionary.borrow().get(&id).cloned()
29  }
30
31  pub fn get_mutable(&self, key: u64) -> Option<ValRef> {
32    self.mutable_variables.get(&key).cloned()
33  }
34
35  pub fn get(&self, key: u64) -> Option<ValRef> {
36    self.symbols.get(&key).cloned()
37  }
38
39  pub fn contains(&self, key: u64) -> bool {
40    self.symbols.contains_key(&key)
41  }
42
43  pub fn insert(&mut self, key: u64, value: Value, mutable: bool) -> ValRef {
44    let cell = Ref::new(value);
45    self.reverse_lookup.insert(&cell, key);
46    let old = self.symbols.insert(key,cell.clone());
47    if mutable {
48      self.mutable_variables.insert(key,cell.clone());
49    }
50    cell.clone()
51  }
52
53}
54
55#[cfg(feature = "pretty_print")]
56impl PrettyPrint for SymbolTable {
57  fn pretty_print(&self) -> String {
58    let mut builder = Builder::default();
59    let dict_brrw = self.dictionary.borrow();
60    for (k,v) in &self.symbols {
61      let name = dict_brrw.get(k).unwrap_or(&"??".to_string()).clone();
62      let v_brrw = v.borrow();
63      builder.push_record(vec![format!("\n{} : {}\n{}\n",name, v_brrw.kind(), v_brrw.pretty_print())])
64    }
65    if self.symbols.is_empty() {
66      builder.push_record(vec!["".to_string()]);
67    }
68    let mut table = builder.build();
69    let table_style = Style::empty()
70    .top(' ')
71    .left(' ')
72    .right(' ')
73    .bottom(' ')
74    .vertical(' ')
75    .horizontal('ยท')
76    .intersection_bottom(' ')
77    .corner_top_left(' ')
78    .corner_top_right(' ')
79    .corner_bottom_left(' ')
80    .corner_bottom_right(' ');
81    table.with(table_style);
82    format!("{table}")
83  }
84}