@@ -11,6 +11,7 @@ use crate::error::{CompileError, CompileErrorType};
11
11
use indexmap:: map:: IndexMap ;
12
12
use rustpython_parser:: ast;
13
13
use rustpython_parser:: location:: Location ;
14
+ use std:: fmt;
14
15
15
16
pub fn make_symbol_table ( program : & ast:: Program ) -> Result < SymbolTable , SymbolTableError > {
16
17
let mut builder: SymbolTableBuilder = Default :: default ( ) ;
@@ -29,11 +30,17 @@ pub fn statements_to_symbol_table(
29
30
}
30
31
31
32
/// Captures all symbols in the current scope, and has a list of subscopes in this scope.
32
- #[ derive( Clone , Default ) ]
33
+ #[ derive( Clone ) ]
33
34
pub struct SymbolTable {
34
35
/// The name of this symbol table. Often the name of the class or function.
35
36
pub name : String ,
36
37
38
+ /// The type of symbol table
39
+ pub typ : SymbolTableType ,
40
+
41
+ /// The line number in the sourcecode where this symboltable begins.
42
+ pub line_number : usize ,
43
+
37
44
/// A set of symbols present on this scope level.
38
45
pub symbols : IndexMap < String , Symbol > ,
39
46
@@ -43,15 +50,34 @@ pub struct SymbolTable {
43
50
}
44
51
45
52
impl SymbolTable {
46
- fn new ( name : String ) -> Self {
53
+ fn new ( name : String , typ : SymbolTableType , line_number : usize ) -> Self {
47
54
SymbolTable {
48
55
name,
56
+ typ,
57
+ line_number,
49
58
symbols : Default :: default ( ) ,
50
59
sub_tables : vec ! [ ] ,
51
60
}
52
61
}
53
62
}
54
63
64
+ #[ derive( Clone ) ]
65
+ pub enum SymbolTableType {
66
+ Module ,
67
+ Class ,
68
+ Function ,
69
+ }
70
+
71
+ impl fmt:: Display for SymbolTableType {
72
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
73
+ match self {
74
+ SymbolTableType :: Module => write ! ( f, "module" ) ,
75
+ SymbolTableType :: Class => write ! ( f, "class" ) ,
76
+ SymbolTableType :: Function => write ! ( f, "function" ) ,
77
+ }
78
+ }
79
+ }
80
+
55
81
/// Indicator for a single symbol what the scope of this symbol is.
56
82
/// The scope can be unknown, which is unfortunate, but not impossible.
57
83
#[ derive( Debug , Clone ) ]
@@ -263,7 +289,7 @@ enum ExpressionContext {
263
289
264
290
impl SymbolTableBuilder {
265
291
fn prepare ( & mut self ) {
266
- self . enter_block ( "top" )
292
+ self . enter_scope ( "top" , SymbolTableType :: Module , 0 )
267
293
}
268
294
269
295
fn finish ( & mut self ) -> Result < SymbolTable , SymbolTableError > {
@@ -273,14 +299,13 @@ impl SymbolTableBuilder {
273
299
Ok ( symbol_table)
274
300
}
275
301
276
- fn enter_block ( & mut self , name : & str ) {
277
- // let parent = Some(self.tables.last().unwrap().clone());
278
- let table = SymbolTable :: new ( name. to_string ( ) ) ;
302
+ fn enter_scope ( & mut self , name : & str , typ : SymbolTableType , line_number : usize ) {
303
+ let table = SymbolTable :: new ( name. to_string ( ) , typ, line_number) ;
279
304
self . tables . push ( table) ;
280
305
}
281
306
282
- fn leave_block ( & mut self ) {
283
- // Pop symbol table and add to sub table of parent table.
307
+ /// Pop symbol table and add to sub table of parent table.
308
+ fn leave_scope ( & mut self ) {
284
309
let table = self . tables . pop ( ) . unwrap ( ) ;
285
310
self . tables . last_mut ( ) . unwrap ( ) . sub_tables . push ( table) ;
286
311
}
@@ -348,9 +373,9 @@ impl SymbolTableBuilder {
348
373
if let Some ( expression) = returns {
349
374
self . scan_expression ( expression, & ExpressionContext :: Load ) ?;
350
375
}
351
- self . enter_function ( name, args) ?;
376
+ self . enter_function ( name, args, statement . location . row ( ) ) ?;
352
377
self . scan_statements ( body) ?;
353
- self . leave_block ( ) ;
378
+ self . leave_scope ( ) ;
354
379
}
355
380
ClassDef {
356
381
name,
@@ -360,9 +385,9 @@ impl SymbolTableBuilder {
360
385
decorator_list,
361
386
} => {
362
387
self . register_name ( name, SymbolUsage :: Assigned ) ?;
363
- self . enter_block ( name) ;
388
+ self . enter_scope ( name, SymbolTableType :: Class , statement . location . row ( ) ) ;
364
389
self . scan_statements ( body) ?;
365
- self . leave_block ( ) ;
390
+ self . leave_scope ( ) ;
366
391
self . scan_expressions ( bases, & ExpressionContext :: Load ) ?;
367
392
for keyword in keywords {
368
393
self . scan_expression ( & keyword. value , & ExpressionContext :: Load ) ?;
@@ -612,9 +637,9 @@ impl SymbolTableBuilder {
612
637
}
613
638
}
614
639
Lambda { args, body } => {
615
- self . enter_function ( "lambda" , args) ?;
640
+ self . enter_function ( "lambda" , args, expression . location . row ( ) ) ?;
616
641
self . scan_expression ( body, & ExpressionContext :: Load ) ?;
617
- self . leave_block ( ) ;
642
+ self . leave_scope ( ) ;
618
643
}
619
644
IfExpression { test, body, orelse } => {
620
645
self . scan_expression ( test, & ExpressionContext :: Load ) ?;
@@ -625,7 +650,12 @@ impl SymbolTableBuilder {
625
650
Ok ( ( ) )
626
651
}
627
652
628
- fn enter_function ( & mut self , name : & str , args : & ast:: Parameters ) -> SymbolTableResult {
653
+ fn enter_function (
654
+ & mut self ,
655
+ name : & str ,
656
+ args : & ast:: Parameters ,
657
+ line_number : usize ,
658
+ ) -> SymbolTableResult {
629
659
// Evaluate eventual default parameters:
630
660
self . scan_expressions ( & args. defaults , & ExpressionContext :: Load ) ?;
631
661
for kw_default in & args. kw_defaults {
@@ -644,7 +674,7 @@ impl SymbolTableBuilder {
644
674
self . scan_parameter_annotation ( name) ?;
645
675
}
646
676
647
- self . enter_block ( name) ;
677
+ self . enter_scope ( name, SymbolTableType :: Function , line_number ) ;
648
678
649
679
// Fill scope with parameter names:
650
680
self . scan_parameters ( & args. args ) ?;
0 commit comments