-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathsyntree.py
73 lines (59 loc) · 2.95 KB
/
syntree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class LabelFactory: # this is a suffix to add to all function names
counter = 0 # in particular, it is useful for function overloading
@staticmethod # it is also useful for different goto labels (loops, conditional statements etc) in assembly code
def cur_label():
return "uniqstr%d" % LabelFactory.counter
def new_label():
LabelFactory.counter += 1
return "uniqstr%d" % LabelFactory.counter
class Type:
VOID = 0
INT = 1
BOOL = 2
STRING = 3
class Function:
def __init__(self, name, args, var, fun, body, deco):
self.name = name # function name, string
self.args = args # function arguments, list of tuples (name, type)
self.var = var # local variables, list of tuples (name, type)
self.fun = fun # nested functions, list of Function nodes
self.body = body # function body, list of statement nodes (Print/Return/Assign/While/IfThenElse/FunCall)
self.deco = deco | {'label' : name+'_'+LabelFactory.new_label()} # decoration dictionary to be filled by the parser (line number) and by the semantic analyzer (return type, scope id etc)
# statements
class Print:
def __init__(self, expr, newline, deco):
self.expr, self.newline, self.deco = expr, newline, deco
class Return:
def __init__(self, expr, deco):
self.expr, self.deco = expr, deco
class Assign:
def __init__(self, name, expr, deco):
self.name, self.expr, self.deco = name, expr, deco
class While:
def __init__(self, expr, body, deco):
self.expr, self.body, self.deco = expr, body, deco
class IfThenElse:
def __init__(self, expr, ibody, ebody, deco):
self.expr, self.ibody, self.ebody, self.deco = expr, ibody, ebody, deco
# expressions
class ArithOp:
def __init__(self, op, left, right, deco):
self.op, self.left, self.right, self.deco = op, left, right, deco | {'type' : Type.INT}
class LogicOp:
def __init__(self, op, left, right, deco):
self.op, self.left, self.right, self.deco = op, left, right, deco | {'type' : Type.BOOL}
class Integer:
def __init__(self, value, deco):
self.value, self.deco = value, deco | {'type' : Type.INT}
class Boolean:
def __init__(self, value, deco):
self.value, self.deco = value, deco | {'type' : Type.BOOL}
class String:
def __init__(self, value, deco):
self.value, self.deco = value, deco | {'type' : Type.STRING, 'label' : LabelFactory.new_label() }
class Var:
def __init__(self, name, deco):
self.name, self.deco = name, deco
class FunCall: # depending on the context, a function call can be a statement or an expression
def __init__(self, name, args, deco):
self.name, self.args, self.deco = name, args, deco