Skip to content

Commit cad53c2

Browse files
committed
Don't clone SymbolTables when analyzing
1 parent b797b51 commit cad53c2

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

compiler/src/symboltable.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl SymbolTable {
6161
}
6262
}
6363

64-
#[derive(Clone, PartialEq)]
64+
#[derive(Clone, Copy, PartialEq)]
6565
pub enum SymbolTableType {
6666
Module,
6767
Class,
@@ -179,24 +179,24 @@ fn analyze_symbol_table(symbol_table: &mut SymbolTable) -> SymbolTableResult {
179179
/// build symbol table structure. It will mark variables
180180
/// as local variables for example.
181181
#[derive(Default)]
182-
struct SymbolTableAnalyzer {
183-
tables: Vec<SymbolTable>,
182+
struct SymbolTableAnalyzer<'a> {
183+
tables: Vec<(&'a mut IndexMap<String, Symbol>, SymbolTableType)>,
184184
}
185185

186-
impl SymbolTableAnalyzer {
187-
fn analyze_symbol_table(&mut self, symbol_table: &mut SymbolTable) -> SymbolTableResult {
188-
// Store a copy to determine the parent.
189-
// TODO: this should be improved to resolve this clone action.
190-
self.tables.push(symbol_table.clone());
186+
impl<'a> SymbolTableAnalyzer<'a> {
187+
fn analyze_symbol_table(&mut self, symbol_table: &'a mut SymbolTable) -> SymbolTableResult {
188+
let symbols = &mut symbol_table.symbols;
189+
let sub_tables = &mut symbol_table.sub_tables;
191190

191+
self.tables.push((symbols, symbol_table.typ));
192192
// Analyze sub scopes:
193-
for sub_table in &mut symbol_table.sub_tables {
193+
for sub_table in sub_tables {
194194
self.analyze_symbol_table(sub_table)?;
195195
}
196-
self.tables.pop();
196+
let (symbols, _) = self.tables.pop().unwrap();
197197

198198
// Analyze symbols:
199-
for symbol in symbol_table.symbols.values_mut() {
199+
for symbol in symbols.values_mut() {
200200
self.analyze_symbol(symbol)?;
201201
}
202202

@@ -207,11 +207,11 @@ impl SymbolTableAnalyzer {
207207
match symbol.scope {
208208
SymbolScope::Nonlocal => {
209209
// check if name is defined in parent table!
210-
let parent_symbol_table: Option<&SymbolTable> = self.tables.last();
210+
let parent_symbol_table = self.tables.last();
211211
// symbol.table.borrow().parent.clone();
212212

213-
if let Some(table) = parent_symbol_table {
214-
if !table.symbols.contains_key(&symbol.name) {
213+
if let Some((symbols, _)) = parent_symbol_table {
214+
if !symbols.contains_key(&symbol.name) {
215215
return Err(SymbolTableError {
216216
error: format!("no binding for nonlocal '{}' found", symbol.name),
217217
location: Default::default(),
@@ -242,8 +242,8 @@ impl SymbolTableAnalyzer {
242242
// Interesting stuff about the __class__ variable:
243243
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
244244
let found_in_outer_scope = symbol.name == "__class__"
245-
|| self.tables.iter().skip(1).any(|t| {
246-
t.typ != SymbolTableType::Class && t.symbols.contains_key(&symbol.name)
245+
|| self.tables.iter().skip(1).any(|(symbols, typ)| {
246+
*typ != SymbolTableType::Class && symbols.contains_key(&symbol.name)
247247
});
248248

249249
if found_in_outer_scope {

0 commit comments

Comments
 (0)