1
1
from syntree import *
2
2
from symtable import *
3
3
4
+ class LabelFactory : # this is a suffix to add to all function names
5
+ counter = 0 # in particular, it is useful for function overloading
6
+ @staticmethod # it is also useful for different goto labels (loops, conditional statements etc) in assembly code
7
+ def new_label ():
8
+ LabelFactory .counter += 1
9
+ return "uniqstr%d" % LabelFactory .counter
10
+
4
11
def build_symtable (ast ):
5
12
if not isinstance (ast , Function ) or ast .name != 'main' or ast .deco ['type' ] != Type .VOID or len (ast .args )> 0 :
6
13
raise Exception ('Cannot find a valid entry point' )
7
14
symtable = SymbolTable ()
8
15
symtable .add_fun (ast .name , [], ast .deco )
16
+ ast .deco ['label' ] = ast .name + '_' + LabelFactory .new_label () # unique label
9
17
process_scope (ast , symtable )
10
18
11
19
def process_scope (fun , symtable ):
@@ -17,6 +25,7 @@ def process_scope(fun, symtable):
17
25
symtable .add_var (* v )
18
26
for f in fun .fun : # process nested functions: first add function symbols to the table
19
27
symtable .add_fun (f .name , [d ['type' ] for v ,d in f .args ], f .deco )
28
+ f .deco ['label' ] = f .name + '_' + LabelFactory .new_label () # still need unique labels
20
29
for f in fun .fun : # then process nested function bodies
21
30
process_scope (f , symtable )
22
31
for s in fun .body : # process the list of statements
@@ -82,6 +91,7 @@ def process_expr(n, symtable): # process "expression" syntax tree nodes
82
91
for s in n .args :
83
92
process_expr (s , symtable )
84
93
deco = symtable .find_fun (n .name , [a .deco ['type' ] for a in n .args ])
94
+ n .deco ['fundeco' ] = deco # save the function symbol, useful for overloading and for stack preparation
85
95
n .deco ['type' ] = deco ['type' ]
86
96
elif isinstance (n , String ): # no type checking is necessary
87
97
n .deco ['type' ] = Type .STRING
0 commit comments