use crate::*;
pub type SymbolTableRef= Ref<SymbolTable>;
#[derive(Clone, Debug)]
pub struct SymbolTable {
pub symbols: HashMap<u64,ValRef>,
pub mutable_variables: HashMap<u64,ValRef>,
pub dictionary: Ref<Dictionary>,
pub reverse_lookup: HashMap<*const Ref<Value>, u64>,
}
impl SymbolTable {
pub fn new() -> SymbolTable {
Self {
symbols: HashMap::new(),
mutable_variables: HashMap::new(),
dictionary: Ref::new(HashMap::new()),
reverse_lookup: HashMap::new(),
}
}
pub fn get_symbol_name_by_id(&self, id: u64) -> Option<String> {
self.dictionary.borrow().get(&id).cloned()
}
pub fn get_mutable(&self, key: u64) -> Option<ValRef> {
self.mutable_variables.get(&key).cloned()
}
pub fn get(&self, key: u64) -> Option<ValRef> {
self.symbols.get(&key).cloned()
}
pub fn contains(&self, key: u64) -> bool {
self.symbols.contains_key(&key)
}
pub fn insert(&mut self, key: u64, value: Value, mutable: bool) -> ValRef {
let cell = Ref::new(value);
self.reverse_lookup.insert(&cell, key);
let old = self.symbols.insert(key,cell.clone());
if mutable {
self.mutable_variables.insert(key,cell.clone());
}
cell.clone()
}
}
#[cfg(feature = "pretty_print")]
impl PrettyPrint for SymbolTable {
fn pretty_print(&self) -> String {
let mut builder = Builder::default();
let dict_brrw = self.dictionary.borrow();
for (k,v) in &self.symbols {
let name = dict_brrw.get(k).unwrap_or(&"??".to_string()).clone();
let v_brrw = v.borrow();
builder.push_record(vec![format!("\n{} : {}\n{}\n",name, v_brrw.kind(), v_brrw.pretty_print())])
}
if self.symbols.is_empty() {
builder.push_record(vec!["".to_string()]);
}
let mut table = builder.build();
let table_style = Style::empty()
.top(' ')
.left(' ')
.right(' ')
.bottom(' ')
.vertical(' ')
.horizontal('ยท')
.intersection_bottom(' ')
.corner_top_left(' ')
.corner_top_right(' ')
.corner_bottom_left(' ')
.corner_bottom_right(' ');
table.with(table_style);
format!("{table}")
}
}