-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
145 lines (119 loc) · 5.46 KB
/
main.py
File metadata and controls
145 lines (119 loc) · 5.46 KB
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
141
142
143
144
145
from parglare import Parser, Grammar
class Variables:
def __init__(self):
self.vars = {}
self.parent = None
def set(self, key, value):
self.vars[key] = value
def get(self, key):
if key in self.vars:
return self.vars[key]
elif self.parent is not None:
self.parent.get(key)
else:
print("No variable " + key)
exit()
def execute_procedure(ast, proc, args):
vars = Variables()
if len(args) != len(proc.params):
print("Wrong param num!")
exit()
for i in range(0, len(args)):
vars.set(proc.params[i].name, args[i])
if not hasattr(proc, 'statements'):
return
return execute_statements(ast, proc.statements, vars)
def execute_procedure_call(ast, proc_call, vars):
if proc_call.name == 'input':
return int(input(">> "))
elif proc_call.name == 'print':
if proc_call.args is not None:
for a in proc_call.args:
print(evaluate_expression(ast, a.expr, vars))
return
proc = next(filter(lambda p: p.name == proc_call.name, ast.procedures), None)
if proc is not None:
args = []
if proc_call.args is not None:
for a in proc_call.args:
args.append(evaluate_expression(ast, a.expr, vars))
return execute_procedure(ast, proc, args)
else:
print("Missing procedure " + proc_call.name)
exit()
def execute_declaration(ast, declaration, vars):
vars.set(declaration.name, evaluate_expression(ast, declaration.rval, vars))
def execute_assignment(ast, assignment, vars):
vars.set(assignment.lval.name, evaluate_expression(ast, assignment.rval, vars))
def execute_if(ast, if_stmt, vars):
if evaluate_expression(ast, if_stmt.expr, vars):
execute_statements(ast, if_stmt.statements, vars)
def execute_while(ast, while_stmt, vars):
while evaluate_expression(ast, while_stmt.expr, vars):
execute_statements(ast, while_stmt.statements, vars)
def execute_statements(ast, statements, vars):
for s in statements:
statement_type = type(s).__name__
if 'ProcedureCallStatement' == statement_type:
execute_procedure_call(ast, s.procedure, vars)
elif 'Declaration' == statement_type:
execute_declaration(ast, s, vars)
elif 'Assignment' == statement_type:
execute_assignment(ast, s, vars)
elif 'If' == statement_type:
execute_if(ast, s, vars)
elif 'While' == statement_type:
execute_while(ast, s, vars)
elif 'Return' == statement_type:
if hasattr(s, 'val'):
return evaluate_expression(ast, s.val, vars)
else:
return
def evaluate_expression(ast, expression, vars):
if hasattr(expression, 'op'):
if expression.op == '^':
return evaluate_expression(ast, expression.l, vars) ** evaluate_expression(ast, expression.r, vars)
elif expression.op == '*':
return evaluate_expression(ast, expression.l, vars) * evaluate_expression(ast, expression.r, vars)
elif expression.op == '/':
return evaluate_expression(ast, expression.l, vars) / evaluate_expression(ast, expression.r, vars)
elif expression.op == '+':
return evaluate_expression(ast, expression.l, vars) + evaluate_expression(ast, expression.r, vars)
elif expression.op == '-':
return evaluate_expression(ast, expression.l, vars) - evaluate_expression(ast, expression.r, vars)
elif expression.op == '<':
return evaluate_expression(ast, expression.l, vars) < evaluate_expression(ast, expression.r, vars)
elif expression.op == '<=':
return evaluate_expression(ast, expression.l, vars) <= evaluate_expression(ast, expression.r, vars)
elif expression.op == '>':
return evaluate_expression(ast, expression.l, vars) > evaluate_expression(ast, expression.r, vars)
elif expression.op == '>=':
return evaluate_expression(ast, expression.l, vars) >= evaluate_expression(ast, expression.r, vars)
elif expression.op == '==':
return evaluate_expression(ast, expression.l, vars) == evaluate_expression(ast, expression.r, vars)
elif expression.op == '!=':
return evaluate_expression(ast, expression.l, vars) != evaluate_expression(ast, expression.r, vars)
elif expression.op == '&&':
return evaluate_expression(ast, expression.l, vars) and evaluate_expression(ast, expression.r, vars)
elif expression.op == '||':
return evaluate_expression(ast, expression.l, vars) or evaluate_expression(ast, expression.r, vars)
elif expression.op == '!':
return not evaluate_expression(ast, expression.r, vars)
elif hasattr(expression, 'num'):
return int(expression.num)
elif hasattr(expression, 'bool'):
return bool(expression.bool)
elif hasattr(expression, 'id'):
return vars.get(expression.id)
elif hasattr(expression, 'proc'):
return execute_procedure_call(ast, expression.proc, vars)
elif hasattr(expression, 'expr'):
return evaluate_expression(ast, expression.expr, vars)
g = Grammar.from_file("borascript.pg")
parser = Parser(g)
ast = parser.parse_file("test.bs")
main_proc = next(filter(lambda p: p.name == 'main', ast.procedures), None)
if main_proc == None:
print("Missing main!")
exit()
execute_procedure(ast, main_proc, [])