From 9501b41bbb786fe66f3e2640ed82bd23e2c67596 Mon Sep 17 00:00:00 2001 From: pycsham <shampuiyanchloe@gmail.com> Date: Sun, 5 Apr 2020 00:19:36 -0400 Subject: [PATCH] implementing method invoke for static methods only --- CodeGenUtils.py | 16 ++++++++- ExprPrimaryNodes.py | 72 +++++++++++++++++++++++++++++++------- Tests/A5/J1_basicTest.java | 4 +++ 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/CodeGenUtils.py b/CodeGenUtils.py index 8234ab5..b5e5165 100644 --- a/CodeGenUtils.py +++ b/CodeGenUtils.py @@ -3,7 +3,7 @@ # String, String, String/None, String/None def p(instruction, arg1, arg2="", comment=""): result = " " + instruction + " " + str(arg1) - if arg2: + if arg2 != "": result += ", " + str(arg2) if comment: result += " ;" + comment @@ -62,6 +62,20 @@ def genProcedure(content, comment): return com + pro + content + epi + " ; End of a procedure\n" +# Adds method invoke prologue and eilogie around the content +def genMethodInvoke(method): + pro = ";Calling a method " + method + "\n" \ + + p(instruction="push", arg1="eax", comment="saving caller-save register eax") \ + + p(instruction="push", arg1="ecx", comment="saving caller-save register ecx") \ + + p(instruction="push", arg1="edx", comment="saving caller-save register edx") + + epi = p(instruction="pop", arg1="eax", comment="restoring caller-save register eax") \ + + p(instruction="pop", arg1="ecx", comment="restoring caller-save register ecx") \ + + p(instruction="pop", arg1="edx", comment="restoring caller-save register edx") \ + + "; End of method invocation\n" + + return (pro, epi) + #################################################### diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py index 66870ce..ddb5d92 100644 --- a/ExprPrimaryNodes.py +++ b/ExprPrimaryNodes.py @@ -4,6 +4,7 @@ from UnitNodes import LiteralNode import MemberNodes from TheTypeNode import TypeNode, TypeStruct from NameNode import NameNode, checkProtected +from CodeGenUtils import p, pLabel, genMethodInvoke # file containing smaller (lower level nodes) in the AST # nodes in this file: @@ -108,6 +109,20 @@ class ArgsNode(ASTNode): expr.disambigName() # helperDisambigName(expr) + def codeGen(self): + if hasattr(self, "code"): + return + self.code = "" + # Generating code for each of the arguments + for arg in self.exprs: + 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"): + arg.codeGen() + self.code += arg.code + self.code += p(instruction="push", arg1="eax", comment="pushing result of evaluation of argument") + ################################################################################### # Array Access @@ -324,18 +339,6 @@ class ClassCreateNode(ASTNode): if curClass.packageName != classDef.packageName: raise Exception("ERROR: In class {0}, using a protected constructor, but class {1} is not in class {0}'s package ({2}).".format(curClass.name, classDef.name, curClass.packageName)) - def codeGen(self): - if hasattr(self, "code"): - return - self.code = "" - - for c in self.children: - 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"): - c.codeGen() - self.code += c.code ################################################################################# @@ -600,6 +603,51 @@ class MethodInvNode(ASTNode): 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 + if "static" in self.method.mods: + mLabel = "M_" + self.typeName + "_" + self.method.name + "_" + self.method.paramTypes + (pro, epi) = genMethodInvoke(mLabel) + self.code += pro + + # Evaluate arguments + if self.args and hasattr(self.args, "codeGen"): + if not hasattr(self.args, "code"): + self.args.codeGen() + self.code += self.args.code + + # Calling static method + self.code += p(instruction="call", arg1=mLabel, comment="calling method") + # Popping off all the arguments + toPop = 0 + if self.args: + toPop = len(self.args.exprs) + + self.code += p(instruction="add", arg1="esp", arg2=toPop, comment="popping off all arguments off stack") + # Epilogue + self.code += epi + + # TODO: To be replaced later + else: + for c in self.children: + 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"): + c.codeGen() + self.code += c.code + + + + + + + ################# Helper ####################### diff --git a/Tests/A5/J1_basicTest.java b/Tests/A5/J1_basicTest.java index c2acd75..a718cc4 100644 --- a/Tests/A5/J1_basicTest.java +++ b/Tests/A5/J1_basicTest.java @@ -7,4 +7,8 @@ public class J1_basicTest { return 123; return 7; } + + public static void test2(){ + J1_basicTest.test(); + } } -- GitLab