diff --git a/CodeGenUtils.py b/CodeGenUtils.py index 07f7b73ff85850112fff5d76f4763be0f1b3152f..c7b483f609d05574e445d113d86e61e19a140919 100644 --- a/CodeGenUtils.py +++ b/CodeGenUtils.py @@ -30,7 +30,7 @@ def pLabel(name, type, comment=""): used_labels.add(l) result = "" - if type in ["class", "method", "constant"]: # make global + if type in ["class", "method"]: # make global result += "global " + l + "\n" if comment: result += l + ": ;" + comment + "\n" diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py index 5be74d556209e19494b7292e3a38d66507977e71..23cb9896cf43efb2c227ad60ef8501fd5d915c72 100644 --- a/ExprPrimaryNodes.py +++ b/ExprPrimaryNodes.py @@ -118,7 +118,7 @@ class ArgsNode(ASTNode): if arg and hasattr(arg, "codeGen"): # children hasn't generated code yet # Note: this check is redundant if we're certain that every override of this method has the initial check - if not hasattr(arg, "code"): + if not hasattr(arg, "code"): arg.codeGen() self.code += arg.code self.code += p(instruction="push", arg1="eax", comment="pushing result of evaluation of argument") @@ -244,6 +244,13 @@ class AssignNode(ASTNode): raise Exception("ERROR: not reaching a assignment statement") self.outMaybe = inMaybe + def codeGen(self): + self.right.codeGen() + self.code = self.right.code + if self.left.prefixLink.__class__.__name__ == "VarDclNode": + # move init result to var location + self.code += p("mov", "[ebp + " + str(self.left.prefixLink.offset) + "]", "eax") + ################################################################################## # cast: castExpr LPAREN castType RPAREN unaryNotPlusMinus @@ -634,18 +641,18 @@ class MethodInvNode(ASTNode): else: raise Exception("ERROR: Class {} doesn't have a method {} with given argument types.".format(self.typeName, self.ID.name)) - + def reachCheck(self, inMaybe): if not inMaybe: raise Exception("ERROR: not reaching a variable declaration statement for var {}".format(self.name)) self.outMaybe = inMaybe - - + + def codeGen(self): if hasattr(self, "code"): return self.code = "" - # Only invoking static methods + # Only invoking static methods if "static" in self.method.mods: mLabel = "M_" + self.typeName + "_" + self.method.name + "_" + self.method.paramTypes (pro, epi) = genMethodInvoke(mLabel) @@ -674,15 +681,15 @@ class MethodInvNode(ASTNode): if c and hasattr(c, "codeGen"): # children hasn't generated code yet # Note: this check is redundant if we're certain that every override of this method has the initial check - if not hasattr(c, "code"): + if not hasattr(c, "code"): c.codeGen() self.code += c.code - - + + ################# Helper ####################### diff --git a/LineNodes.py b/LineNodes.py index d4474470842a68453ea17a472f8717921e79bb43..422c307b2b1984a596ca70f2d3da68a726a4e3c5 100644 --- a/LineNodes.py +++ b/LineNodes.py @@ -2,6 +2,7 @@ from AST import ASTNode, getParseTreeNodes, getASTNode from Environment import Env from ExprPrimaryNodes import makeNodeFromExpr, makeNodeFromAllPrimary, MethodInvNode, ClassCreateNode from TheTypeNode import TypeNode, TypeStruct +from CodeGenUtils import p # Contains: # block @@ -163,6 +164,15 @@ class VarDclNode(ASTNode): raise Exception("ERROR: not reaching a variable declaration statement for var {} in class {}".format(self.name, self.typeName)) self.outMaybe = inMaybe + def codeGen(self): + self.code = "" + if self.variableInit: + self.variableInit.codeGen() + self.code += self.variableInit.code + # move init result to var location + self.code += p("mov", "[ebp + " + str(self.offset) + "]", "eax") + + # ifStatement, ifElseStatement, ifElseStatementNoShortIf # Rules: # 1. ifStatement IF LPAREN expr RPAREN statement diff --git a/NameNode.py b/NameNode.py index 65d29672e126b3a97d11b9db9626b45dfc953a31..62acb8e6d074b33dd1622ccc7619c74440190524 100644 --- a/NameNode.py +++ b/NameNode.py @@ -3,6 +3,7 @@ from TheTypeNode import TypeStruct, getSupers import MemberNodes import TypeNodes from Environment import Env +from CodeGenUtils import p # name nodes: contains compID and IDs @@ -66,7 +67,7 @@ class NameNode(ASTNode): self.addToPrefix(typeNode) return True return False - + def checkLength(self): if not self.IDs: return True @@ -166,7 +167,7 @@ class NameNode(ASTNode): if self.checkThis(): self.pointToThis = True return - + # Checking if a1 is length if self.checkLength(): return @@ -252,6 +253,10 @@ class NameNode(ASTNode): # pprint(vars(self)) raise Exception("ERROR: Cannot check type of name {}".format(self.name)) + def codeGen(self): + self.code = "" + if self.prefixLink.__class__.__name__ == "VarDclNode": + self.code = p("mov", "eax", "[ebp + " + str(self.prefixLink.offset) + "]", "access local var" + self.name) # helper def checkProtected(dcl, usage): # get curType's class it was declared in diff --git a/Tests/A5/J1_00_Step0_localVar.java b/Tests/A5/J1_00_Step0_localVar.java new file mode 100644 index 0000000000000000000000000000000000000000..a9752c034f943a87456179f3c20e723a934ce085 --- /dev/null +++ b/Tests/A5/J1_00_Step0_localVar.java @@ -0,0 +1,10 @@ +// most basic test case for step 0 +public class J1_00_Step0_localVar { + public static int test() { + int i = 0; + i = 2; + int b = 3; + b = 4; + return i + b; + } +}