summaryrefslogtreecommitdiff
path: root/Variables.py
blob: 1d37f0f2676b2ecf4b5efb3549b4330fd8e15b46 (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
#!/usr/bin/env python
"""Compiles C into assembly for the practicum processor (PP2)

All rights reserved, you may not redistribute or use this program without prior
permission from Peter Wu or Xander Houtman. Use of this program is entirely
your own risk. In no circumstances can the authors of this program be held
responsible for any damage including, but not limited to, financial damage or
data loss. Modification of this program is not allowed without prior
permission. The generated output (assembly and messages) are not subject to
this license.
"""

__author__ = "Peter Wu"
__copyright__ = "Copyright 2011, Peter Wu"
__credits__ = ["Peter Wu"]
__license__ = "Proprietary"
__version__ = "1.0"
__maintainer__ = "Peter Wu"
__email__ = "uwretep@gmail.com"

class Variables(object):
    def __init__(self, defined_names, parent_variables):
        """A scope for holding variable names
        
        Keywords arguments:
        defined_names -- A list of defined variables to which additional
        variables might be appended
        parent_variables -- the parent Variables object. If None, it's a global
        variable scope
        """
        self.local_vars = {}
        self.defined_names = defined_names
        self.parent_variables = parent_variables
    def uniqName(self, name):
        """Returns an unique variable name"""
        uniq_name = name
        i = 0
        while uniq_name in self.defined_names:
            uniq_name = name + "_" + str(i)
            i += 1
        return uniq_name
    def getName(self, name):
        """Gets the name of a declared variable as it appears in the @DATA
        section"""
        if name in self.local_vars:
            return self.local_vars[name]
        if self.parent_variables:
            return self.parent_variables.getName(name)
        raise RuntimeError("Use of undefined variable '{}'".format(name))
    def declName(self, name, size=1, prefix="var"):
        """Declares a variable in the nearest scope and returns the label
        name"""
        if name in self.local_vars:
            raise RuntimeError("Redeclaration of variable '{}'".format(name))
        # global variables are prefixed "var_", locals with "varl_"
        var_name = prefix + ("l_" if self.parent_variables else "_") + name
        var_name = self.uniqName(var_name)
        self.local_vars[name] = var_name
        self.defined_names[var_name] = size
        return var_name