#!/usr/bin/env python """Compiles C into assembly for the practicum processor (PP2) Copyright (C) 2011-2014 Peter Wu Licensed under the MIT license . """ __author__ = "Peter Wu" __copyright__ = "Copyright (C) 2011-2014 Peter Wu" __credits__ = ["Peter Wu"] __license__ = "MIT" __version__ = "1.0" __maintainer__ = "Peter Wu" __email__ = "lekensteyn@gmail.com" class Function(object): 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 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") self.decl_node = decl_node 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 self.label_begin def labelEnd(self): """Returns a label pointing to the end of a function""" 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 Keyword arguments: count -- The number of words to be allocated which should be at least 1 """ assert count > 0, "The stack allocation count must be at least 1" 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