diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py index 0fbcee7168fd6eca61042be4f02b0959f29338f7..608c2e1cc5a09e0715585c0480144d9d106e0225 100644 --- a/ExprPrimaryNodes.py +++ b/ExprPrimaryNodes.py @@ -373,10 +373,9 @@ class ClassCreateNode(ASTNode): self.code += p(instruction="push", arg1="eax", comment="pushing object as first argument") # Evaluate arguments and pushing parameters if self.args and hasattr(self.args, "codeGen"): - if not hasattr(self.args, "code"): - self.args.codeGen() + self.args.codeGen() self.code += self.args.code - label = "M_"+self.cons.typeName+"_"+self.cons.name+"_"+self.cons.paramTypes + 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") diff --git a/MemberNodes.py b/MemberNodes.py index dfeed75cf15cc5e8dadeb2acf5921a040902644c..780bd809f04c1b9dfa28a5533495e2ba59d900f7 100644 --- a/MemberNodes.py +++ b/MemberNodes.py @@ -241,6 +241,7 @@ class MethodNode(ASTNode): self.code += genProcedure(bodyCode, "method definition for " + self.name) else: + self.code += ("mov", "eax", "0") self.code += p("ret", "") # This method is called instead of codeGen if this is a constructor @@ -248,36 +249,51 @@ class MethodNode(ASTNode): if hasattr(self, "code") and self.code != "": return + myClass = self.env.getNode(self.typeName, 'type') + self.label = "M_" + self.typeName + "_" + self.name + "_" + self.paramTypes + self.code = pLabel(self.typeName + "_" + self.name + "_" + self.paramTypes, "method") # label + thisLoc = len(self.params) * 4 + 8 + bodyCode = "" - 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) + # call parent constructor + if myClass.superClass: + suLabel = "M_" + myClass.superClass.name + "_" + bodyCode += importHelper(myClass.superClass.name, self.typeName, suLabel) + bodyCode += p("mov", "eax", "[ebp - " + thisLoc + "]") + bodyCode += p("push", "eax", None, "# Pass THIS as argument to superClass.") + bodyCode += p("call", suLabel) + + + # init fields + fields = sorted(myClass.fields, key=lambda x: x.order) + for f in fields: + if not 'static' in field.mods and f.variableDcl.variableInit: + f.variableDcl.variableInit.right.codeGen() + bodyCode += f.variableDcl.variableInit.right.code + bodyCode += p("mov", "ebx", "[ebp - " + thisLoc + "]") # THIS + bodyCode += p("mov", "[ebx + " + f.offset + " ]", "eax") + + # body code + if self.body: 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", "") - + bodyCode += ("mov", "eax", "0") + self.code += genProcedure(bodyCode, "Constructor definition for " + self.name + " " + self.paramTypes) ############# helper for forward ref checking ######## # Input: AST Node diff --git a/TypeNodes.py b/TypeNodes.py index 860ca7a974f9c35a3f58821a8b68bb4e01b2a907..14b6f8f9047e26a87a0592430e81025961c18762 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -289,12 +289,13 @@ class ClassNode(ClassInterNode): # Adding in fields that are not inherited from parent class to offset table # Note: excluding static fields - for field in self.fields: + fields = sorted(self.fields, key=lambda x: x.order) + for field in fields: if not 'static' in field.mods: lastFieldOffset += 4 self.fieldOffset[(self.name,field.name)] = lastFieldOffset field.offset = lastFieldOffset - + # Calculating the size of objects of this class self.size += (len(self.fieldOffset))*4 @@ -302,7 +303,7 @@ class ClassNode(ClassInterNode): def codeGen(self): if hasattr(self, "code"): return - + self.code = "" # For read-only section self.data = "" # For writeable data section @@ -417,11 +418,13 @@ class ClassNode(ClassInterNode): p(instruction="call", arg1="H_"+self.name+"_"+ "staticFieldMemoryInit") + \ p(instruction="ret", arg1="") - for c in self.children: - if c and hasattr(c, "codeGen"): - if not hasattr(c, "code"): # children hasn't generated code yet - c.codeGen() - self.code += c.code # don't want to repeat field code + for c in self.fields + self.methods: + c.codeGen() + self.code += c.code + + for c in self.constructors: + c.codeGenConstructor() + self.code += c.code #####################################################################