-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast_ds.py
140 lines (116 loc) · 2.93 KB
/
ast_ds.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class ArithmeticExp:
pass
class IntExp(ArithmeticExp):
def __init__(self, i):
self.i = i
def eval(self, env):
return self.i
class VarExp(ArithmeticExp):
def __init__(self, (x, _)):
self.x = x
def eval(self, env):
if self.x in env:
return env[self.x]
else:
return 0
class BinopExp(ArithmeticExp):
def __init__(self, (op, _), left, right):
self.op = op
self.left = left
self.right = right
def eval(self, env):
left_val = self.left.eval(env)
right_val = self.right.eval(env)
if self.op == '+':
return left_val + right_val
elif self.op == '-':
return left_val - right_val
elif self.op == '*':
return left_val * right_val
elif self.op == '/':
return left_val / right_val
else:
raise Exception('Unknown operator' + self.op)
class BooleanExp:
pass
class RelExp(BooleanExp):
def __init__(self, (op, _), left, right):
self.op = op
self.left = left
self.right = right
def eval(self, env):
left_val = self.left.eval(env)
right_val = self.right.eval(env)
if self.op == '<':
return left_val < right_val
elif self.op == '>':
return left_val > right_val
elif self.op == '<=':
return left_val <= right_val
elif self.op == '>=':
return left_val >= right_val
elif self.op == '==':
return left_val == right_val
elif self.op == '!=':
return left_val != right_val
else:
raise Exception('Unknown operator' + self.op)
class AndExp(BooleanExp):
def __init__(self, left, right):
self.left = left
self.right = right
def eval(self, env):
left_val = self.left.eval(env)
right_val = self.right.eval(env)
return left_val and right_val
class OrExp(BooleanExp):
def __init__(self, left, right):
self.left = left
self.right = right
def eval(self, env):
left_val = self.left.eval(env)
right_val = self.right.eval(env)
return left_val or right_val
class NotExp(BooleanExp):
def __init__(self, exp):
self.exp = exp
def eval(self, env):
val = self.exp.eval(env)
return not val
class Statement:
pass
class AssignmentStatement(Statement):
def __init__(self, (name, _), val):
self.name = name
self.val = val
def eval(self, env):
val = self.val.eval(env)
env[self.name] = val
class WhileStatement(Statement):
def __init__(self, condition, body):
self.condition = condition
self.body = body
def eval(self, env):
eval_cond = self.condition.eval(env)
while eval_cond:
self.body.eval(env)
eval_cond = self.condition.eval(env)
class IfStatement(Statement):
def __init__(self, condition, true_body, false_body):
self.condition = condition
self.true_body = true_body
self.false_body = false_body
def eval(self, env):
eval_cond = self.condition.eval(env)
if eval_cond:
self.true_body.eval(env)
else:
if self.false_body:
self.false_body.eval(env)
class CompoundStatement(Statement):
def __init__(self, first, second):
self.first = first
self.second = second
def eval(self, env):
self.first.eval(env)
self.second.eval(env)