diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py index d04a094a14649292f69e51014d66b4b0767f8852..a66264e1e879fab17431bd08a95600b5de653432 100644 --- a/ExprPrimaryNodes.py +++ b/ExprPrimaryNodes.py @@ -169,7 +169,7 @@ class ArrayAccessNode(ASTNode): if not self.index.myType.isNum(): raise Exception("ERROR: Array index must be a number.") self.myType = TypeStruct(self.array.myType.name, self.array.myType.typePointer) - + def getIfFalse(self, label): self.codeGen() return self.code + p("cmp", "eax", "[G__Zero]") + p("je", label) @@ -497,18 +497,22 @@ class ClassCreateNode(ASTNode): # 3. Calling constructor self.code += "; Calling constructor for object\n" - self.code += p(instruction="push", arg1="eax", comment="pushing object as first argument") - # Evaluate arguments and pushing parameters + + # Evaluate arguments if self.args and hasattr(self.args, "codeGen"): - self.args.codeGen() + if not hasattr(self.args, "code"): + self.args.codeGen() self.code += self.args.code + + self.code += p(instruction="push", arg1="eax", comment="pushing object as last argument") label = "M_" + self.cons.typeName + "_" + self.cons.name + "_" + self.cons.paramTypes self.code += importHelper(classDef.name, self.typeName, label) self.code += p(instruction="call", arg1=label, comment="Calling constructor") # 4. Popping parameters and pointer to object - self.code += p(instruction="add", arg1="esp", arg2=len(self.args.exprs)*4, comment="Popping parameters") + \ - p(instruction="pop", arg1="eax", comment="eax now contains pointer to newly created object") + self.code += p(instruction="pop", arg1="eax", comment="eax now contains pointer to newly created object") + self.code += p(instruction="add", arg1="esp", arg2=len(self.args.exprs)*4, comment="Popping parameters") + self.code += ";End of object creation\n" @@ -590,7 +594,7 @@ class ExprNode(ASTNode): self.myType.link(self.env) # var1 + var2 === String.valueOf(var1).concat( String.valueOf(var2) ) - + # methodInvoc name LPAREN args RPAREN (because it's static) # MethodInvNode # ID = NameNode @@ -612,7 +616,7 @@ class ExprNode(ASTNode): # valueOfMethodInvLeft.checkType() # valueOfMethodInvRight.checkType() - + # methodInvoc primary PERIOD ID LPAREN args RPAREN # MethodInvNode # primary = self.left @@ -630,7 +634,7 @@ class ExprNode(ASTNode): self.concatMethodInv = MethodInvNode(self.parseTree, self.typeName, concatNameNode, rightArgMethodInv, valueOfMethodInvLeft) # 4. Check type to be safe self.concatMethodInv.checkType() - + return raise Exception("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.left.myType.name, self.right.myType.name, self.op)) @@ -939,7 +943,7 @@ class FieldAccessNode(ASTNode): checkProtected(self.ID.prefixLink, self) except: # where there are no mods return - + def getIfFalse(self, label): self.codeGen() return self.code + p("cmp", "eax", "[G__Zero]") + p("je", label) diff --git a/MemberNodes.py b/MemberNodes.py index 4a3d14c93f93a3fcf03d82ef26b549f5dc8fb01c..86094fa64feaccdf3c34f62d723b50cd817cc2c4 100644 --- a/MemberNodes.py +++ b/MemberNodes.py @@ -260,6 +260,14 @@ class MethodNode(ASTNode): if hasattr(self, "code") and self.code != "": return + # populate param offsets + # params + stackoffset = 12 + rparams = self.params.copy() + rparams.reverse() + for i, param in enumerate(rparams): + param.offset = i * 4 + stackoffset # 12 since the stack is now of the order: ebp, eip, o, params + myClass = self.env.getNode(self.typeName, 'type') self.label = "M_" + self.typeName + "_" + self.name + "_" + self.paramTypes diff --git a/UnitNodes.py b/UnitNodes.py index 15d466e337b367f3cdc9881cbb090a9a02660ff7..69b361a27edce62ecf9ad639ec72e534d6a43de5 100644 --- a/UnitNodes.py +++ b/UnitNodes.py @@ -65,7 +65,7 @@ class LiteralNode(ASTNode): self.code += ";Start of String Literal Creation for class " + self.typeName + "\n" # generate array of characters # then call new String(array) - + # remove quotation marks value = self.value[1:-1] @@ -84,7 +84,7 @@ class LiteralNode(ASTNode): aLabel = "A_char" self.code += p(instruction="extern", arg1=aLabel) + \ p(instruction="mov", arg1="[eax]", arg2="dword "+aLabel, comment="first item is vtable pointer") - + # 3. Storing length in the second slot self.code += p(instruction="mov", arg1="[eax+4]", arg2="ecx", comment="storing array length in second slot") @@ -99,7 +99,7 @@ class LiteralNode(ASTNode): self.code += p(instruction="pop", arg1="ecx", comment="restoring register ecx") self.code += ";End of char array creation\n" - # SECOND: create new string object with the char array + # SECOND: create new string object with the char array # push array pointer self.code += p(instruction="push", arg1="eax", comment="save pointer to char array") @@ -122,9 +122,10 @@ class LiteralNode(ASTNode): # 3. Calling constructor self.code += "; Calling constructor for String\n" - self.code += p(instruction="push", arg1="eax", comment="pushing object as first argument") # Evaluate arguments and pushing parameters self.code += p("push", "ebx", comment="add our char array as arg") + self.code += p(instruction="push", arg1="eax", comment="pushing object as last argument") + # 4. call String::String(char[] chars) label = "M_String_String_char" @@ -132,8 +133,8 @@ class LiteralNode(ASTNode): self.code += p(instruction="call", arg1=label, comment="Calling constructor") # 4. Popping parameters and pointer to object - self.code += p(instruction="add", arg1="esp", arg2=4, comment="Popping parameters") self.code += p(instruction="pop", arg1="eax", comment="eax now contains pointer to newly created object") + self.code += p("add", "esp", "4", "Popping parameters") self.code += ";End of object creation\n" self.code += ";End of String Literal Creation for class " + self.typeName + "\n" return