Skip to content
Snippets Groups Projects
Commit c51a5d86 authored by pycsham's avatar pycsham
Browse files

implemented class memory layout without SIT and subtype testing

parent 703755da
No related branches found
No related tags found
No related merge requests found
......@@ -72,6 +72,13 @@ class ASTNode():
for c in self.children:
if c and hasattr(c, 'reachCheck'):
c.reachCheck(inMaybe)
def code(self):
genCode = ""
for c in self.children:
if c and hasattr(c, "code"):
genCode += c.code()
return genCode
def printNodePretty(self, prefix=0):
pp = pprint.PrettyPrinter(indent=prefix)
......@@ -92,6 +99,30 @@ class ASTNode():
pp.pprint("-----children-----")
prefix += 1
return prefix
# Utility function for generating a single line of assembly code
# TODO: move to the correct file
# Output: A string that is a one line assembly instruction (new line included)
def oneLineAssemblyHelper(self, operator="", op1="", op2="", label="", comment=""):
genCode = ""
if label:
genCode += label
genCode += ":\n"
if operator:
genCode += operator
if op1:
genCode += " "
genCode += op1
if op2:
genCode += ", "
genCode += op2
if comment:
if operator:
genCode += " ;"
else:
genCode += ";"
genCode += comment
genCode += "\n"
return genCode
......
......@@ -53,4 +53,9 @@ def disamiguateAndTypeChecking(ASTs):
def reachabilityChecking(ASTs):
for t in ASTs:
t[1].reachCheck()
\ No newline at end of file
t[1].reachCheck()
#######################################################
def codeGen(ASTs):
for t in ASTs:
t[1].code()
\ No newline at end of file
......@@ -6,7 +6,7 @@ import traceback
from Scanning import scan
from Parsing import parse
from AstBuilding import astBuild, buildEnvAndLink, disamiguateAndTypeChecking, reachabilityChecking
from AstBuilding import astBuild, buildEnvAndLink, disamiguateAndTypeChecking, reachabilityChecking, codeGen
import Weeding
......@@ -162,6 +162,10 @@ def run(testFiles):
reachabilityChecking(ASTs)
except Exception as e:
return "reachabilityChecking: " + e.args[0]
try:
codeGen(ASTs)
except Exception as e:
return "code generation: " + e.args[0]
return ""
......
public class J1_basicTest {
public J1_basicTest() {}
public static int test() {
if (true)
return 123;
return 7;
}
}
......@@ -160,6 +160,10 @@ class ClassNode(ClassInterNode):
self.constructors = []
self.mods = []
self.superClass = '' # these fields initially stores a string that represent the super
#### Code generation relevant fields ####
self.label = "" # label in assembly
self.methodOffset = {} # a dictionary that maps method signatures (method.name, method.paramTypes) to offsets in the memory layout
self.staticFieldLabels = [] # a list of static field labels
for node in parseTree.children:
if node.name == 'classMod':
......@@ -261,6 +265,83 @@ class ClassNode(ClassInterNode):
raise Exception("ERROR: Constructor {0} doesn't have the same name as class {1}".format(constructor.name, self.name))
return
def code(self):
genCode = ""
# print("This is the super class: {}".format(self.superClass))
# Generate class label
self.label = "C_" + self.name
genCode += self.oneLineAssemblyHelper(label=self.label, comment="START OF CLASS MEMORY LAYOUT FOR CLASS " + self.canonName)
# TODO: SIT and subtype testing tables
####### ADDING METHODS TO CLASS MEMORY LAYOUT #########
# 1. Copying over the offsets of methods from superclass and DECLARING memory segment for the methods
lastOffset = -4 # stores the largest offset in the superCalss
# TODO: set this to 4 after the implemntation of both the SIT and subtype testing table
# Note: This is 4 less than the offset of where the next method would be located
# This is to accomodate for the addition of 4 to lastOffset in EVERY (including the first) iteration in the
# loops that loops through self.constructors and self.methods, in the case where there is no superClass
if self.superClass:
for key,value in self.superClass.methodOffset.items():
self.methodOffset[key] = value
newLabel = "VM_" + self.name + "_" + key[0] + "_" + key[1]
genCode += self.oneLineAssemblyHelper(label=newLabel, operator="dd", op1="64") # just declaring a memory segment with a random number
lastOffset = max(value, lastOffset)
# 2. Assigning offsets to constructors and DECLARING memory segment for the methods
for method in self.constructors:
lastOffset += 4
key = (method.name, method.paramTypes)
self.methodOffset[(method.name, method.paramTypes)] = lastOffset
newLabel = "VM_" + self.name + "_" + method.name + "_" + method.paramTypes
genCode += self.oneLineAssemblyHelper(label=newLabel, operator="dd", op1="64") # just declaring a memory segment with a random number
# 3. Assigning offsets to methods that aren't in the super class DECLARING memory segment for the methods
for method in self.methods:
if not (method.name, method.paramTypes) in self.methodOffset:
lastOffset += 4
self.methodOffset[(method.name, method.paramTypes)] = lastOffset
newLabel = "VM_" + self.name + "_" + method.name + "_" + method.paramTypes
genCode += self.oneLineAssemblyHelper(label=newLabel, operator="dd", op1="64") # just declaring a memory segment with a random number
# print(self.methodOffset)
genCode += self.oneLineAssemblyHelper(comment="END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name)
# 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations
for key,value in self.methodOffset.items():
vmLabel = "VM_" + self.name + "_" + key[0] + "_" + key[1]+"" # method at class's vtable
mLabel = "M_" + self.name + "_" + key[0] + "_" + key[1]
genCode += self.oneLineAssemblyHelper(operator="mov", op1="eax", op2=vmLabel, comment="Filling in class memory segment for method " + mLabel)
genCode += self.oneLineAssemblyHelper(operator="mov", op1="[eax]", op2=mLabel)
# print(genCode)
###########################################################
for c in self.children:
if c and hasattr(c, 'code'):
genCode += c.code()
return genCode
#####################################################################
# interface
class InterNode(ClassInterNode):
......
......@@ -5,7 +5,7 @@ from os.path import isfile, join
from Scanning import scan
from Parsing import parse
from AstBuilding import astBuild, buildEnvAndLink, disamiguateAndTypeChecking, reachabilityChecking
from AstBuilding import astBuild, buildEnvAndLink, disamiguateAndTypeChecking, reachabilityChecking, codeGen
import Weeding
......@@ -49,7 +49,7 @@ def main():
ASTs = astBuild(parseTrees)
except Exception as e: # for definite assignemnt
return 42
try:
buildEnvAndLink(ASTs)
except Exception as e:
......@@ -65,6 +65,11 @@ def main():
except Exception as e:
return 42
try:
codeGen(ASTs)
except Exception as e:
return 42
return 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment