python_ast/symbols/
mod.rs

1//! Implements a Python-compatilble symbol table for Rust.
2
3use std::collections::HashMap;
4use std::collections::VecDeque;
5use std::fmt;
6
7use crate::tree::{ClassDef, FunctionDef, Import, ImportFrom};
8
9//use log::{debug, info};
10
11//use crate::codegen::{CodeGen, PythonOptions, CodeGenContext};
12use crate::tree::ExprType;
13
14/// A stack of symbol tables of different scopes. Topmost is the current scope.
15#[derive(Clone, Debug)]
16pub struct SymbolTableScopes(VecDeque<SymbolTable>);
17
18impl SymbolTableScopes {
19    pub fn new() -> Self {
20        Self(VecDeque::new())
21    }
22
23    pub fn push(&mut self, table: SymbolTable) {
24        self.0.push_front(table);
25    }
26
27    pub fn pop(&mut self) -> Option<SymbolTable> {
28        self.0.pop_front()
29    }
30
31    pub fn new_scope(&mut self) {
32        self.0.push_front(SymbolTable::new());
33    }
34
35    pub fn insert(&mut self, key: String, value: SymbolTableNode) {
36        if let Some(table) = self.0.front_mut() {
37            table.insert(key, value);
38        }
39    }
40
41    pub fn get(&self, key: &str) -> Option<&SymbolTableNode> {
42        for table in self.0.iter() {
43            if let Some(value) = table.get(key) {
44                return Some(value);
45            }
46        }
47        None
48    }
49}
50
51impl Default for SymbolTableScopes {
52    fn default() -> Self {
53        Self::new()
54    }
55}
56
57impl Default for SymbolTable {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63#[derive(Clone, Debug)]
64pub enum SymbolTableNode {
65    Assign { position: usize, value: ExprType },
66    ClassDef(ClassDef),
67    FunctionDef(FunctionDef),
68    Import(Import),
69    ImportFrom(ImportFrom),
70    Alias(String),
71}
72
73#[derive(Clone, Debug)]
74pub struct SymbolTable {
75    pub symbols: HashMap<String, SymbolTableNode>,
76}
77
78impl SymbolTable {
79    pub fn new() -> Self {
80        Self {
81            symbols: HashMap::new(),
82        }
83    }
84
85    pub fn insert(&mut self, key: String, value: SymbolTableNode) {
86        self.symbols.insert(key, value);
87    }
88
89    pub fn get(&self, key: &str) -> Option<&SymbolTableNode> {
90        self.symbols.get(key)
91    }
92}
93
94impl fmt::Display for SymbolTable {
95    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96        let mut s = String::new();
97        for (key, value) in self.symbols.iter() {
98            s.push_str(&format!("{}: {:#?}\n", key, value));
99        }
100        write!(f, "{}", s)
101    }
102}