-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQuackChecker.py
More file actions
93 lines (72 loc) · 3.57 KB
/
Copy pathQuackChecker.py
File metadata and controls
93 lines (72 loc) · 3.57 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
import sys
import AST
class QuackChecker():
def __init__(self, ast):
self.tree = ast
self.check = True
self.reserved = ["class", "def", "extends", "if", "elif",
"else", "while", "return", "and", "or",
"not", "typecase"]
self.identifiers = ["String", "Int", "Obj", "Boolean",
"true", "false", "Nothing", "none"]
self.types = ["Int", "Boolean", "Obj"]
self.var_inits = {}
#print(f"init typechecker of class {self.__class__.__name__}")
#print(f"{self.tree.children}")
def explicit_types(self):
def check_types(root):
if root.children:
for node in root.children:
check_types(node)
print(type(root))
check_explicit_type(root)
def check_explicit_type(node):
if isinstance(node, AST.AssigNode) and node.var_type != None:
# check to make sure type is supported
if node.var_type.name not in self.types:
raise Exception(f"Unsupported type of {node.var_type.name} found")
# check to make sure name is not reserved keyword
if node.var_name.name in self.types:
raise Exception(f"Usage of reserved keyword {node.var_name.name} as name found")
if isinstance(node, AST.R_ExpNode):
if node.expression in self.types:
raise Exception(f"Usage of reserved keyword {node.expression} as name found")
if isinstance(node, AST.OpHelp):
# TODO: check if same types
if type(node.left) is AST.OpHelp:
# recurse down
print("recurse down")
check_explicit_type(node.left)
elif type(node.left) is not AST.OpHelp and type(node.right) is not AST.OpHelp:
print(node.left, node.right)
if type(node.left) is not AST.NumberNode:
leftType = self.var_inits[node.left.name]
else:
leftType = node.left.type
if type(node.right) is not AST.NumberNode:
rightType = self.var_inits[node.right.name]
else:
rightType = node.right.type
if leftType != rightType:
print(type(leftType))
print(type(rightType))
raise Exception(f"Type mismatch of {leftType} to {rightType} on operation {node.op}")
#if isinstance(node, AST.Return_Node):
# # check to make sure name is not reserved keyword
# if node.value.name in self.types:
# raise Exception(f"Usage of reserved keyword {node.value.name} as name found")
check_types(self.tree)
def collect_inits(self):
def walk(root):
if isinstance(root, AST.AssigNode):
# TODO: fix this, no idea why this works
# still has a token in the name and type field for some reason
if (root.var_type != None):
self.var_inits[root.var_name.get_name()] = root.var_type.name
if root.children:
for node in root.children:
walk(node)
print(type(root))
walk(self.tree)
def check_expression_node():
print(f"checking program node")