Skip to content
Snippets Groups Projects
Commit baee5e15 authored by Pui Yan Chloe Sham's avatar Pui Yan Chloe Sham
Browse files

Merge branch 'field-init' into 'CodeGenField'

Field init

See merge request !10
parents 3c047153 6218edfc
No related branches found
No related tags found
2 merge requests!14Insta field,!10Field init
......@@ -165,6 +165,9 @@ class VarDclNode(ASTNode):
self.outMaybe = inMaybe
def codeGen(self):
if hasattr(self, "code") and self.code != "":
return
self.code = ""
if self.variableInit:
self.variableInit.codeGen()
......@@ -172,6 +175,11 @@ class VarDclNode(ASTNode):
# move init result to var location
self.code += p("mov", "[ebp + " + str(self.offset) + "]", "eax")
def addr(self):
result = p("mov", "eax", "ebp")
result += p("add", "eax", str(self.offset))
return result
# ifStatement, ifElseStatement, ifElseStatementNoShortIf
# Rules:
......
......@@ -55,69 +55,34 @@ class FieldNode(ASTNode):
# Note: 1. Not calling codeGen for variableDcl since all variableDcl code are assuming that the variable is a LOCAL variable
# 2. Only calling codeGen on the variableInit of self.variableDcl if the field is static, since non-static fields should
# be initialized by the constructor
# be initialized by the constructor
def codeGen(self):
if hasattr(self, "code"):
return
self.code = ""
label = self.typeName + "_" + self.name
# result: eax contains the pointer to the memory block on heap
def heapAllocate():
self.code += p(instruction="mov", arg1="eax", arg2=self.variableDcl.myType.getSize(), comment="size of field in bytes") + \
p(instruction="call", arg1="__malloc", comment="allocating space on heap for the field")
# static fields: the pointer lives in assembly
if "static" in self.mods:
self.code += ";Declaring a static field: " + label + "\n"
self.code += pLabel(name=label, type="static") + \
p(instruction="dd", arg1="64", comment="Declaring space on assembly for a static field")
# Allocating space on heap for the static field
heapAllocate()
# Filling in label with pointer's address
self.code += p(instruction="mov", arg1="ebx", arg2="dword S_"+label) + \
p(instruction="mov", arg1="[ebx]", arg2="eax", comment="eax is a pointer to heap")
self.code += ";End of declaration of static field\n"
# Initializing static fields
# static fields are intialized in the order of declaration within the class and has to be intialized
# before the test() method is being called
initNode = self.variableDcl.variableInit
if initNode:
if not hasattr(initNode, "code"):
initNode.codeGen()
initNode.codeGen()
self.code += "; Calculating the initial value of declared field: " + label + "\n"
self.code += initNode.code
self.code += "; End of the calculation of the initial value of declared field\n"
# Moving the initial value to the correct location
self.code += "; Moving the initial value to heap for field: " + label + "\n"
self.code += p(instruction="mov", arg1="ecx", arg2="[S_"+label+"]", comment="obtaining pointer of static field") + \
p(instruction="mov", arg1="[ecx]", arg2="eax", comment="moving value in eax to heap")
self.code += "; End of the moving of initial value to heap\n"
else:
# Creating a function that allocates memory on heap for the field (to be called by classCreateNode)
# result: register ecx stores pointer to the allocated memory for the field
self.code += ";A function that allocates memory on heap for the field: " + label + "\n"
self.code += pLabel(name=label, type="field")
self.code += p(instruction="push", arg1="eax", comment="saving the register eax to be restored later")
# Allocating space on heap for the field
heapAllocate()
self.code += p(instruction="mov", arg1="ecx", arg2="eax", comment="ecx stores pointer to the allocated memory") + \
p(instruction="pop", arg1="eax", comment="restoring the original value of eax")
self.code += "; End of function\n"
# See the "Note" above the function declaration for codeGen for why codeGen isn't called on it's children
# Filling in label with pointer's address
self.code += p(instruction="mov", arg1="ebx", arg2="dword S_"+label) + \
p(instruction="mov", arg1="[ebx]", arg2="eax", comment="eax is a pointer to field value in heap")
self.code += ";End of declaration of static field\n"
###########################################################
......@@ -275,6 +240,40 @@ class MethodNode(ASTNode):
else:
self.code += p("ret", "")
# This method is called instead of codeGen if this is a constructor
def codeGenConstructor(self):
if hasattr(self, "code") and self.code != "":
return
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)
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", "")
############# helper for forward ref checking ########
......
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