@@ -61,7 +61,7 @@ impl SymbolTable {
61
61
}
62
62
}
63
63
64
- #[ derive( Clone , PartialEq ) ]
64
+ #[ derive( Clone , Copy , PartialEq ) ]
65
65
pub enum SymbolTableType {
66
66
Module ,
67
67
Class ,
@@ -179,24 +179,24 @@ fn analyze_symbol_table(symbol_table: &mut SymbolTable) -> SymbolTableResult {
179
179
/// build symbol table structure. It will mark variables
180
180
/// as local variables for example.
181
181
#[ derive( Default ) ]
182
- struct SymbolTableAnalyzer {
183
- tables : Vec < SymbolTable > ,
182
+ struct SymbolTableAnalyzer < ' a > {
183
+ tables : Vec < ( & ' a mut IndexMap < String , Symbol > , SymbolTableType ) > ,
184
184
}
185
185
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 ;
191
190
191
+ self . tables . push ( ( symbols, symbol_table. typ ) ) ;
192
192
// Analyze sub scopes:
193
- for sub_table in & mut symbol_table . sub_tables {
193
+ for sub_table in sub_tables {
194
194
self . analyze_symbol_table ( sub_table) ?;
195
195
}
196
- self . tables . pop ( ) ;
196
+ let ( symbols , _ ) = self . tables . pop ( ) . unwrap ( ) ;
197
197
198
198
// Analyze symbols:
199
- for symbol in symbol_table . symbols . values_mut ( ) {
199
+ for symbol in symbols. values_mut ( ) {
200
200
self . analyze_symbol ( symbol) ?;
201
201
}
202
202
@@ -207,11 +207,11 @@ impl SymbolTableAnalyzer {
207
207
match symbol. scope {
208
208
SymbolScope :: Nonlocal => {
209
209
// 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 ( ) ;
211
211
// symbol.table.borrow().parent.clone();
212
212
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 ) {
215
215
return Err ( SymbolTableError {
216
216
error : format ! ( "no binding for nonlocal '{}' found" , symbol. name) ,
217
217
location : Default :: default ( ) ,
@@ -242,8 +242,8 @@ impl SymbolTableAnalyzer {
242
242
// Interesting stuff about the __class__ variable:
243
243
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
244
244
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 )
247
247
} ) ;
248
248
249
249
if found_in_outer_scope {
0 commit comments