summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-12-03 14:30:41 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-12-03 14:30:41 +0000
commit4b297842f3b45c7857623c1c309654c339b28d85 (patch)
treef7b2c0085a456f7602370d502f93f89a38bfa2f7
parentcbb589740133d53224fcd66c4c2decf43a7eca6e (diff)
downloadpp2cc-4b297842f3b45c7857623c1c309654c339b28d85.tar.gz
Support for static functions
-rw-r--r--Function.py22
-rwxr-xr-xpp2cc.py10
2 files changed, 25 insertions, 7 deletions
diff --git a/Function.py b/Function.py
index 38d01ea..6be2bfe 100644
--- a/Function.py
+++ b/Function.py
@@ -19,12 +19,14 @@ __maintainer__ = "Peter Wu"
__email__ = "uwretep@gmail.com"
class Function(object):
- def __init__(self, decl_node):
+ def __init__(self, decl_node, is_static=False, uniq_provider=None):
"""Initializes an object for holding a function declaration and related
properties
Keyword arguments:
- decl_node -- A Node object
+ decl_node -- A Node object
+ is_static -- True if the function is static, False otherwise. Static
+ functions are local to a file and won't be visible to other files.
"""
assert type(decl_node).__name__ == "FuncDecl", ("decl_node is not a"
" function declaration")
@@ -32,12 +34,24 @@ class Function(object):
self.name = self.decl_node.type.declname
self.reserved_stack = 0
self.linked_node = None
+ self.is_static = is_static
+ common_fn_prefix = "sfn_" if self.isStatic() else "fn_"
+ if self.isStatic():
+ assert uniq_provider != None, "No unique label provider found"
+ self.label_begin = uniq_provider("sfn_" + self.name)
+ self.label_end = uniq_provider("sfne_" + self.name)
+ else:
+ self.label_begin = "fn_" + self.name
+ self.label_end = "fne_" + self.name
+ def isStatic(self):
+ """Returns True if this is a static function, False otherwise"""
+ return self.is_static
def labelBegin(self):
"""Returns a label pointing to the begin of a function"""
- return "fn_" + self.name
+ return self.label_begin
def labelEnd(self):
"""Returns a label pointing to the end of a function"""
- return "fne_" + self.name
+ return self.label_end
def allocStack(self, count=1):
"""Reserve some memory (for local variables and params) on the stack
and return the begin of the allocated memory
diff --git a/pp2cc.py b/pp2cc.py
index 190f10a..bc9259f 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -150,6 +150,10 @@ class Parse(object):
" node, but also found " +
str(thing), linked_node=linked_node)
self.codeSegment += self.parseStatement(thing, root_node)
+ # hack: static functions are local to a file, so remove them
+ for funcname, function in self.functions.items():
+ if function.isStatic():
+ del self.functions[funcname]
def compileASM(self):
"""Processes lines of assembly and merge it into the output"""
for label in self.asm_node.labels:
@@ -212,8 +216,6 @@ class Parse(object):
lbl_func = function.labelBegin()
lbl_end = function.labelEnd()
- self.addLabel(lbl_func)
- self.addLabel(lbl_end)
linked_node.setFunction(function)
# save Base Pointer
lines = [self.asm.push(self.registers.BP, lbl_func)]
@@ -1225,7 +1227,9 @@ class Parse(object):
node = linked_node.node
funcname = node.type.declname
if not funcname in self.functions:
- self.functions[funcname] = Function(node)
+ is_static = "static" in linked_node.parent.node.storage
+ self.functions[funcname] = Function(node, is_static=is_static,
+ uniq_provider=self.uniqLbl)
if node.args:
argstype = type(node.args).__name__
assert argstype == "ParamList", "Expected function arguments, found '{}' instead".format(argstype)