summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Function.py23
-rw-r--r--LinkedNode.py1
-rwxr-xr-xpp2cc.py12
3 files changed, 29 insertions, 7 deletions
diff --git a/Function.py b/Function.py
index de0c49d..38d01ea 100644
--- a/Function.py
+++ b/Function.py
@@ -19,10 +19,19 @@ __maintainer__ = "Peter Wu"
__email__ = "uwretep@gmail.com"
class Function(object):
- def __init__(self, node):
- self.name = node.decl.name
- self.node = node
+ def __init__(self, decl_node):
+ """Initializes an object for holding a function declaration and related
+ properties
+
+ Keyword arguments:
+ decl_node -- A Node object
+ """
+ assert type(decl_node).__name__ == "FuncDecl", ("decl_node is not a"
+ " function declaration")
+ self.decl_node = decl_node
+ self.name = self.decl_node.type.declname
self.reserved_stack = 0
+ self.linked_node = None
def labelBegin(self):
"""Returns a label pointing to the begin of a function"""
return "fn_" + self.name
@@ -40,3 +49,11 @@ class Function(object):
begin_address = self.reserved_stack + 1
self.reserved_stack += count
return begin_address
+ def setLinkedNode(self, linked_node):
+ """Assigns this function to a function node"""
+ assert linked_node.type == "FuncDef", ("Only function definitions can"
+ " be linked to a function")
+ self.linked_node = linked_node
+ def isLinked(self):
+ """Returns True if this function object is already linked to a node"""
+ return self.linked_node is not None
diff --git a/LinkedNode.py b/LinkedNode.py
index f068993..b24812a 100644
--- a/LinkedNode.py
+++ b/LinkedNode.py
@@ -101,6 +101,7 @@ class LinkedNode(object):
allocation function
"""
self.function = function
+ function.setLinkedNode(self)
self.variables.setFunction(function)
def getLocation(self):
if hasattr(self.node, "coord"):
diff --git a/pp2cc.py b/pp2cc.py
index 4c83afb..8f6a581 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -201,11 +201,14 @@ class Parse(object):
linked_node.incrementLevel()
self.asm.level = linked_node.level
+ # parse function declaration (which will parse params as well)
+ assert not self.parseStatement(node.decl, linked_node), ("Function"
+ " declaration should not return a line of assembly")
funcname = node.decl.name
- if funcname in self.functions:
+ function = self.functions[funcname]
+ if function.isLinked():
self.logger.error("Redefinition of function '{}'".format(funcname),
linked_node=linked_node)
- function = self.functions[funcname] = Function(node)
lbl_func = function.labelBegin()
lbl_end = function.labelEnd()
@@ -215,8 +218,6 @@ class Parse(object):
# save Base Pointer
lines = [self.asm.push(self.registers.BP, lbl_func)]
lines.append(self.asm.binary_op("LOAD", self.registers.BP, "SP"))
- # parse function declaration (which will parse params as well)
- lines += self.parseStatement(node.decl, linked_node)
body = self.parseStatement(node.body, linked_node)
self.asm.level = linked_node.level
@@ -1211,6 +1212,9 @@ class Parse(object):
def parseFuncDecl(self, linked_node):
lines = []
node = linked_node.node
+ funcname = node.type.declname
+ if not funcname in self.functions:
+ self.functions[funcname] = Function(node)
if node.args:
argstype = type(node.args).__name__
assert argstype == "ParamList", "Expected function arguments, found '{}' instead".format(argstype)