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