1
0
Fork 0
This repository has been archived on 2025-03-30. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
compiler-course/src/compiler/symtab.rs

97 lines
2.8 KiB
Rust
Raw Normal View History

2025-02-04 16:09:05 +02:00
use crate::compiler::variable::{Type, Value};
use std::collections::HashMap;
#[derive(Default)]
2025-02-04 16:09:05 +02:00
pub struct SymTab<'source, T> {
tables: Vec<HashMap<&'source str, T>>,
}
2025-02-04 16:09:05 +02:00
impl<'source, T> SymTab<'source, T> {
pub fn get(&mut self, symbol: &str) -> &mut T {
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 push_level(&mut self) {
self.tables.push(HashMap::new());
}
pub fn remove_level(&mut self) {
self.tables.pop();
}
2025-02-04 16:09:05 +02:00
pub fn insert(&mut self, name: &'source str, val: T) {
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)
}
}
}
2025-02-04 16:09:05 +02:00
impl<'source, T> SymTab<'source, T> {
pub fn new() -> SymTab<'source, T> {
SymTab {
tables: vec![HashMap::new()],
}
}
}
2025-02-04 16:09:05 +02:00
impl<'source> SymTab<'source, Type> {
pub fn new_type_table() -> SymTab<'source, Type> {
use Type::*;
let globals = HashMap::from([
("+", Func(vec![Int, Int], Box::new(Int))),
("*", Func(vec![Int, Int], Box::new(Int))),
("-", Func(vec![Int, Int], Box::new(Int))),
("/", Func(vec![Int, Int], Box::new(Int))),
("%", Func(vec![Int, Int], Box::new(Int))),
("<", Func(vec![Int, Int], Box::new(Bool))),
("<=", Func(vec![Int, Int], Box::new(Bool))),
(">", Func(vec![Int, Int], Box::new(Bool))),
(">=", Func(vec![Int, Int], Box::new(Bool))),
2025-02-05 18:15:37 +02:00
("unary_not", Func(vec![Bool], Box::new(Bool))),
("unary_-", Func(vec![Int], Box::new(Int))),
("or", Func(vec![Bool, Bool], Box::new(Bool))),
("and", Func(vec![Bool, Bool], Box::new(Bool))),
2025-02-04 16:09:05 +02:00
]);
SymTab {
tables: vec![globals],
}
}
}
impl<'source> SymTab<'source, Value> {
pub fn new_val_table() -> SymTab<'source, Value> {
use Value::*;
let globals = HashMap::from([
("+", Func(Value::add)),
("*", Func(Value::mul)),
("-", Func(Value::sub)),
("/", Func(Value::div)),
("%", Func(Value::rem)),
("==", Func(Value::eq)),
("!=", Func(Value::neq)),
("<", Func(Value::lt)),
("<=", Func(Value::le)),
(">", Func(Value::gt)),
(">=", Func(Value::ge)),
2025-02-05 18:15:37 +02:00
("unary_not", Func(Value::not)),
("unary_-", Func(Value::neg)),
2025-02-04 16:09:05 +02:00
]);
SymTab {
tables: vec![globals],
}
}
}