summaryrefslogtreecommitdiff
path: root/Function.py
blob: 3d8d59c3884ed04e4376d77368f4d29a09b426cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python
"""Compiles C into assembly for the practicum processor (PP2)

Copyright (C) 2011-2014 Peter Wu <lekensteyn@gmail.com>
Licensed under the MIT license <http://opensource.org/licenses/MIT>.
"""

__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