diff --git a/LineNodes.py b/LineNodes.py index f697308d154d1325eacb7dc3734dadaf6dba5017..fc9edff10acca6c9a44bbef88f65be15e19d8d87 100644 --- a/LineNodes.py +++ b/LineNodes.py @@ -165,6 +165,9 @@ class VarDclNode(ASTNode): self.outMaybe = inMaybe def codeGen(self): + if hasattr(self, "code") and self.code != "": + return + self.code = "" if self.variableInit: self.variableInit.codeGen() @@ -172,6 +175,11 @@ class VarDclNode(ASTNode): # move init result to var location self.code += p("mov", "[ebp + " + str(self.offset) + "]", "eax") + def addr(self): + result = p("mov", "eax", "ebp") + result += p("add", "eax", str(self.offset)) + return result + # ifStatement, ifElseStatement, ifElseStatementNoShortIf # Rules: diff --git a/MemberNodes.py b/MemberNodes.py index caa85f7a4d8765ff11e0f25dc1d0564d54ecd166..928a38b60ec71032e24409e43cea9f823862d15d 100644 --- a/MemberNodes.py +++ b/MemberNodes.py @@ -55,69 +55,34 @@ class FieldNode(ASTNode): # Note: 1. Not calling codeGen for variableDcl since all variableDcl code are assuming that the variable is a LOCAL variable # 2. Only calling codeGen on the variableInit of self.variableDcl if the field is static, since non-static fields should - # be initialized by the constructor + # be initialized by the constructor def codeGen(self): if hasattr(self, "code"): return self.code = "" - label = self.typeName + "_" + self.name - # result: eax contains the pointer to the memory block on heap - def heapAllocate(): - - self.code += p(instruction="mov", arg1="eax", arg2=self.variableDcl.myType.getSize(), comment="size of field in bytes") + \ - p(instruction="call", arg1="__malloc", comment="allocating space on heap for the field") - - # static fields: the pointer lives in assembly if "static" in self.mods: self.code += ";Declaring a static field: " + label + "\n" self.code += pLabel(name=label, type="static") + \ p(instruction="dd", arg1="64", comment="Declaring space on assembly for a static field") - # Allocating space on heap for the static field - heapAllocate() - - # Filling in label with pointer's address - self.code += p(instruction="mov", arg1="ebx", arg2="dword S_"+label) + \ - p(instruction="mov", arg1="[ebx]", arg2="eax", comment="eax is a pointer to heap") - self.code += ";End of declaration of static field\n" - # Initializing static fields # static fields are intialized in the order of declaration within the class and has to be intialized # before the test() method is being called initNode = self.variableDcl.variableInit if initNode: - if not hasattr(initNode, "code"): - initNode.codeGen() + initNode.codeGen() self.code += "; Calculating the initial value of declared field: " + label + "\n" self.code += initNode.code - self.code += "; End of the calculation of the initial value of declared field\n" - # Moving the initial value to the correct location - self.code += "; Moving the initial value to heap for field: " + label + "\n" - self.code += p(instruction="mov", arg1="ecx", arg2="[S_"+label+"]", comment="obtaining pointer of static field") + \ - p(instruction="mov", arg1="[ecx]", arg2="eax", comment="moving value in eax to heap") - self.code += "; End of the moving of initial value to heap\n" - - else: - # Creating a function that allocates memory on heap for the field (to be called by classCreateNode) - # result: register ecx stores pointer to the allocated memory for the field - self.code += ";A function that allocates memory on heap for the field: " + label + "\n" - self.code += pLabel(name=label, type="field") - self.code += p(instruction="push", arg1="eax", comment="saving the register eax to be restored later") - # Allocating space on heap for the field - heapAllocate() - self.code += p(instruction="mov", arg1="ecx", arg2="eax", comment="ecx stores pointer to the allocated memory") + \ - p(instruction="pop", arg1="eax", comment="restoring the original value of eax") - self.code += "; End of function\n" - - # See the "Note" above the function declaration for codeGen for why codeGen isn't called on it's children - - - + # Filling in label with pointer's address + self.code += p(instruction="mov", arg1="ebx", arg2="dword S_"+label) + \ + p(instruction="mov", arg1="[ebx]", arg2="eax", comment="eax is a pointer to field value in heap") + self.code += ";End of declaration of static field\n" + ########################################################### @@ -275,6 +240,40 @@ class MethodNode(ASTNode): else: self.code += p("ret", "") + # This method is called instead of codeGen if this is a constructor + def codeGenConstructor(self): + if hasattr(self, "code") and self.code != "": + return + + + + self.label = "M_" + self.typeName + "_" + self.paramTypes + self.code = pLabel(self.typeName + "_" + self.paramTypes, "method") # label + + # init fields + + # body code + if self.body: + bodyCode = "" + # push all local var to stack + vars = getVarDclNodes(self.body) + for i in range(len(vars)): + vars[i].offset = i * 4 + 16 + bodyCode += p("push", 0) + + self.body.codeGen() + bodyCode += self.body.code + + bodyCode += self.label + "_end: ; end of method for " + self.name + "\n" + + # pop off all the local var + for i in range(len(vars)): + bodyCode += p("pop", "edx") + + self.code += genProcedure(bodyCode, "method definition for " + self.name) + else: + self.code += p("ret", "") + ############# helper for forward ref checking ########