-
Notifications
You must be signed in to change notification settings - Fork 0
/
Class.py
174 lines (154 loc) · 5.69 KB
/
Class.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
from pprint import pprint
import re
class Class:
classes = []
def __init__(self, name, parentName=None):
self.parent = parentName
self.children = []
self.name = name
self.variables = []
self.methods = []
Class.classes.append(self)
@staticmethod
def handleInheritance():
roots = []
for cls in Class.classes:
par = cls.parent
if par != None:
parObj = Class.searchClass(par)
cls.parent = parObj
parObj.children.append(cls)
else:
roots.append(cls)
# Loop through roots to chlldren
for root in roots:
root.extendsParent(None)
def extendsParent(self , parrent):
if parrent != None:
self.extendVariables(parrent)
self.extendMethods(parrent)
for child in self.children:
child.extendsParent(self)
# Inherit Variables an Methods from parent
def extendVariables(self, parent):
tmpVars = self.variables
self.variables = []
for var in parent.variables:
self.variables.append(var.copy())
for var in tmpVars:
if not self.variableExists(var['name']):
self.variables.append(var.copy())
def extendMethods(self, parent):
tmpMethods = self.methods
self.methods = []
for method in parent.methods:
self.methods.append(method.copy())
for method in tmpMethods:
if not self.methodExists(method['name']):
self.methods.append(method.copy())
else:
self.overrideMethod(method['name'])
# Find Offset of Variables and Methods from Start Address
def variableOffset(self, name):
for i in range(len(self.variables)):
if self.variables[i]['name'] == name:
return 4*i + 4
raise Exception("Variable ( " + name + " ) not found !!!")
def methodOffset(self, name):
for i in range(len(self.methods)):
if self.methods[i]['name'] == name:
return 4*i
raise Exception("Method ( " + name + " ) fot found !!!")
# Check Where a Variable or a Method Exists or not ( Search by name )
def variableExists(self, name):
for var in self.variables:
if var['name'] == name:
return True
return False
def methodExists(self, name):
for method in self.methods:
if method['name'] == name:
return True
return False
# Add Variable or Method
def addVariable(self, name, varType):
self.variables.append({'name': name, 'type': varType})
def getVariable(self , name):
for var in self.variables:
if var['name'] == name:
return var
raise Exception("Variable (" + name + ") not exists in Class !!!")
def addMethod(self, name, methodType):
self.methods.append({'name': name, 'type': methodType, 'prefix': self.name})
def getMethod(self , name):
for method in self.methods:
if method['name'] == name:
return method
raise Exception("Method (" + name + ") not exists in Class !!!")
def overrideMethod(self, name):
for method in self.methods:
if method['name'] == name:
method['prefix'] = self.name
return
raise Exception("Method ( " + name + " ) not found to override !!!")
# Search Class By Name
@staticmethod
def searchClass(searchKey):
for c in Class.classes:
if c.name == searchKey:
return c
return None
# Get Vtables of Classes
@staticmethod
def getVtables():
code = ''
for c in Class.classes:
code += c.name + "_vtable:\n"
for method in c.methods:
code += "\t.word " + method['prefix'] + "_" + method['name'] + "\n"
return code
# Get Constructors of classes
def getConstructors():
code = ''
for c in Class.classes:
size = (len(c.variables) + 1) * 4;
code += "# Constructor for Class : " + c.name + "\n"
code += c.name + "_Constructor:\n"
code += "li $a0 , " + str(size) + " # Size of Object ( including Vtable address at index 0 )\n"
code += "li $v0 , 9\n"
code += "syscall\n"
code += "la $t0 , " + c.name + "_vtable # Loading Vtable Address of this Class\n"
code += "sw $t0 , 0($v0) # Storing Vtable pointer at index 0 of object\n"
code += "jr $ra\n\n"
return code
# Check whether 2 classes are convertable or not
@staticmethod
def areConvertable(name1 , name2):
if name1 == "null_type" or name2 == "null_type":
return True;
a = Class.searchClass(name1)
b = Class.searchClass(name2)
if a == None or b == None:
return False
tmpb = b
while tmpb.parent != None:
if tmpb.parent.name == a.name:
return True
tmpb = tmpb.parent
tmpa = a
while tmpa.parent != None:
if tmpa.parent.name == b.name:
return True
tmpa = tmpa.parent
return False
# Log
@staticmethod
def log():
for c in Class.classes:
print("----------------- Class name : " + c.name + " ------------------")
print("---- Variables")
for var in c.variables:
print("- Name : " + var['name'] + " , Type : " + var['type'])
print("---- Methods")
for m in c.methods:
print("- Name : " + m['name'] + " , Type : " + m['type'])