-
Notifications
You must be signed in to change notification settings - Fork 0
/
resolver.py
68 lines (60 loc) · 2.06 KB
/
resolver.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
from builtin import get
from builtin import lt, lte, gt, gte, ne, eq
from builtin import add, sub, mul, div
from builtin import LogicError
def resolve(expr, frame):
# Resolving tokens
if 'type' in expr:
if expr['type'] == 'name':
return expr['word']
elif expr['type'] in ('integer', 'string'):
return expr['type'].upper()
else:
# internal error
raise TypeError(f'Cannot resolve type for {expr}') # Resolving exprs
oper = expr['oper']['value']
if oper is get:
expr['left'] = frame
name = resolve(expr['right'])
return frame[name]['type']
elif oper in (lt, lte, gt, gte, ne, eq):
return 'BOOLEAN'
elif oper in (add, sub, mul, div):
lefttype = resolve(expr['left'])
righttype = resolve(expr['right'])
if lefttype != 'INTEGER':
raise LogicError(f"{expr['left']} Expected number, got {lefttype}")
if righttype != 'INTEGER':
raise LogicError(f"{expr['right']} Expected number, got {righttype}")
return 'INTEGER'
def verifyOutput(frame, stmt):
for expr in stmt['exprs']:
resolve(expr, frame)
def verifyDeclare(frame, stmt):
name = resolve(stmt['name'], frame)
type_ = resolve(stmt['type'], frame)
frame[name] = {'type': type_, 'value': None}
def verifyAssign(frame, stmt):
name = resolve(stmt['name'], frame)
valuetype = resolve(stmt['expr'], frame)
if name not in frame:
raise LogicError(f'Variable')
frametype = frame[name]['type']
if frametype != valuetype:
raise LogicError(f'Expected {frametype}, got {valuetype}')
def verify(frame, stmt):
if stmt['rule'] == 'output':
verifyOutput(frame, stmt)
elif stmt['rule'] == 'declare':
verifyDeclare(frame, stmt)
elif stmt['rule'] == 'assign':
verifyAssign(frame, stmt)
def inspect(statements):
frame = {}
for stmt in statements:
try:
verify(frame, stmt)
except LogicError:
print()
break
return statements, frame