nessa/structures/
variable_map.rs

1use rustc_hash::{FxHashMap, FxHashSet};
2
3use crate::types::Type;
4
5pub struct VariableMap {
6    vars: Vec<FxHashMap<String, (usize, Type)>>
7}
8
9impl Default for VariableMap {
10    fn default() -> Self {
11        Self::new()
12    }
13}
14
15impl VariableMap {
16    pub fn new() -> Self {
17        VariableMap { vars: vec!(FxHashMap::default()) }
18    }
19
20    pub fn add_context(&mut self) {
21        self.vars.push(FxHashMap::default());
22    } 
23
24    pub fn remove_context(&mut self) {
25        self.vars.pop().unwrap();
26    }
27
28    pub fn define_var(&mut self, name: String, idx: usize, t: Type) {
29        self.vars.last_mut().unwrap().entry(name).or_insert((idx, t));
30    }
31
32    pub fn is_var_defined(&mut self, name: &String) -> bool {
33        for ctx in self.vars.iter().rev() {
34            if ctx.contains_key(name) {
35                return true;
36            }
37        }
38
39        false
40    }
41
42    pub fn is_var_defined_in_last_ctx(&mut self, name: &String) -> bool {
43        self.vars.last().unwrap().contains_key(name)
44    }
45
46    pub fn get_var(&mut self, name: &String) -> Option<&(usize, Type)> {
47        for ctx in self.vars.iter().rev() {
48            if let Some(v) = ctx.get(name) {
49                return Some(v);
50            }
51        }
52
53        None
54    }
55
56    pub fn for_each_last_ctx<T: FnMut(usize)>(&self, f: T) {
57        self.vars.last().unwrap().values().map(|(i, _)| *i).for_each(f);
58    }
59
60    pub fn var_names(&self) -> FxHashSet<&String> {
61        self.vars.iter().rev().flat_map(|i| i.keys()).collect()
62    }
63}