1
0
Fork 0

Refactor symbol table to be non-horrible :D

This commit is contained in:
Vili Sinervä 2025-02-04 00:34:56 +02:00
parent 38dd3f523b
commit 1ec86d4845
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 34 additions and 29 deletions

View file

@ -3,23 +3,21 @@ use std::collections::HashMap;
#[derive(Default)]
pub struct SymTab<'source> {
pub locals: HashMap<&'source str, Value>,
pub parent: Option<Box<SymTab<'source>>>,
tables: Vec<HashMap<&'source str, Value>>,
}
impl<'source> SymTab<'source> {
pub fn get(&mut self, symbol: &str) -> &mut Value {
if let Some(val) = self.locals.get_mut(symbol) {
val
} else if let Some(parent) = &mut self.parent {
parent.get(symbol)
} else {
panic!("No symbol {} found!", symbol);
for i in (0..self.tables.len()).rev() {
if self.tables[i].contains_key(symbol) {
return self.tables[i].get_mut(symbol).unwrap();
}
}
panic!("No symbol {} found!", symbol);
}
pub fn new_global() -> SymTab<'source> {
let locals = HashMap::from([
pub fn new() -> SymTab<'source> {
let globals = HashMap::from([
("+", Value::Func(Value::add)),
("*", Value::Func(Value::mul)),
("-", Value::Func(Value::sub)),
@ -36,8 +34,27 @@ impl<'source> SymTab<'source> {
]);
SymTab {
locals,
parent: None,
tables: vec![globals],
}
}
pub fn push_level(&mut self) {
self.tables.push(HashMap::new());
}
pub fn remove_level(&mut self) {
self.tables.pop();
}
pub fn insert(&mut self, name: &'source str, val: Value) {
if self
.tables
.last_mut()
.expect("Symbols table should never be empty!")
.insert(name, val)
.is_some()
{
panic!("Variable {} already defined in this scope!", name)
}
}
}