diff --git a/Test.py b/Test.py index 795dd2b60dcc38553210d6ee60cd50468104a0e7..5f4c3d0c76373902d0da0dfb96fc63f567d3e6ce 100644 --- a/Test.py +++ b/Test.py @@ -48,7 +48,10 @@ def a2Multiple(): testOutput = "output/" + c.split("/")[-1] if exists(testOutput): - rmtree(testOutput) + try: + rmtree(testOutput) + except: + rmtree("output/.DS_Store") makedirs(testOutput) copyfile('stdlib/5.0/runtime.s', testOutput + "/runtime.s") @@ -150,6 +153,7 @@ def run(testFiles, testOutput): codeGen(ASTs, testOutput) except Exception as e: return "code generation: " + e.args[0] + # codeGen(ASTs, testOutput) return "" diff --git a/TypeNodes.py b/TypeNodes.py index b50ee78b19575015b32a8af3e985d9467a608900..12a15e6652384c9120e01da6af81ba1f52c3ef81 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -163,7 +163,7 @@ class ClassNode(ClassInterNode): self.superClass = '' # these fields initially stores a string that represent the super #### Code generation relevant fields #### self.label = "" # label in assembly - self.methodOffset = {} # a dictionary that maps method signatures (method.name, method.paramTypes) to offsets in the CLASS memory layout + self.methodOffset = {} # a dictionary that maps method signatures (method.name, method.paramTypes) to (offset, constructorFlag) in the CLASS memory layout self.fieldOffset = {} # a dictionary that maps field names to offsets in OBJECT memory layout self.staticFieldLabels = [] # a list of static field labels @@ -320,19 +320,38 @@ class ClassNode(ClassInterNode): self.code += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number # 3. Assigning offsets to methods that aren't in the super class DECLARING memory segment for the methods + # Also simultaneosly creating a dictionary of methods for easier lookup + methodDict = {} # a map of methods of the form (method.name, method.paramTypes) -> method node for method in self.methods: + methodDict[(method.name, method.paramTypes)] = method if not (method.name, method.paramTypes) in self.methodOffset: lastMethodOffset += 4 self.methodOffset[(method.name, method.paramTypes)] = lastMethodOffset self.code += pLabel(name=self.name + "_" + method.name + "_" + method.paramTypes, type="vtable") self.code += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number + + # Adding inherited method to the methodDict + for i in self.inherits: + if isinstance(i, MethodNode): + key = (i.name, i.paramTypes) + if not key in methodDict: + methodDict[(i.name, i.paramTypes)] = i # print(self.methodOffset) self.code += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n" + + # 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations for key,value in self.methodOffset.items(): vLabel = "V_" + self.name + "_" + key[0] + "_" + key[1]+"" # method at class's vtable - mLabel = "M_" + self.name + "_" + key[0] + "_" + key[1] # method implementation + + className = "" # The name of the class that contains the most recent implementation + if key in methodDict: + className = methodDict[key].typeName + else: # a constructor + className = key[0] + + mLabel = "M_" + className + "_" + key[0] + "_" + key[1] # method implementation self.code += p(instruction="mov", arg1="eax", arg2=vLabel, comment="Filling in class memory segment for method " + mLabel) self.code += p(instruction="mov", arg1="[eax]", arg2="dword " + mLabel)