summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Variables.py37
-rwxr-xr-xpp2cc.py3
2 files changed, 25 insertions, 15 deletions
diff --git a/Variables.py b/Variables.py
index 424f6bd..617113f 100644
--- a/Variables.py
+++ b/Variables.py
@@ -55,13 +55,15 @@ class Variables(object):
if self.parent_variables:
return self.parent_variables.getAddress(name)
raise RuntimeError("Use of undefined variable '{}'".format(name))
- def declName(self, name, size=1, is_param=False):
+ def declName(self, name, size=1, is_param=False, is_static=False):
"""Declares a variable in the nearest scope
Keyword arguments:
name -- The symbolic name of the variable
size -- The size of the memory to be allocated in words (default 1)
is_param -- Whether the name is a function parameter or not
+ is_static -- Whether the variable should be static or not. Values of
+ static variables are retained between function calls
"""
if name in self.local_vars or name in self.param_vars:
raise RuntimeError("Redeclaration of variable '{}'".format(name))
@@ -101,31 +103,38 @@ class GlobalVariables(Variables):
if name in self.global_vars:
return ("GB", self.global_vars[name])
raise RuntimeError("Use of undefined variable '{}'".format(name))
- def declName(self, name, size=1, is_param=False):
+ def declName(self, name, size=1, is_param=False, is_static=False):
"""Declares a variable in the nearest scope
Keyword arguments:
name -- The symbolic name of the variable
size -- The size of the memory to be allocated in words (default 1)
is_param -- Whether the name is a function parameter or not
+ is_static -- Whether the variable should be static or not. Static
+ variables in this global scope are only visible in the file itself
"""
if name in self.global_vars:
raise RuntimeError("Redeclaration of variable '{}'".format(name))
if is_param:
raise RuntimeError("Parameter '{}' declared in global context".format(name))
+
+ if is_static:
+ # static globals are prefixed with "svar_" and not shared between
+ # files
+ var_name = self._uniqName("svar_" + name)
else:
# global variables are prefixed "var_". Don't use _uniqName because
- # globals are by definition global and may be declared multiple
- # times
+ # globals may be declared multiple times and are still shared
var_name = "var_" + name
- self.global_vars[name] = var_name
- if var_name in self.defined_names:
- old_size = len(self.defined_names[var_name])
- if size != old_size:
- raise RuntimeError("Size {} of global '{}' does not equal"
- " an earlier definition {}"
- .format(size, name, old_size))
- else:
- # insert size items, initialized with 0
- self.defined_names[var_name] = ["0"] * size
+
+ self.global_vars[name] = var_name
+ if var_name in self.defined_names:
+ old_size = len(self.defined_names[var_name])
+ if size != old_size:
+ raise RuntimeError("Size {} of global '{}' does not equal"
+ " an earlier definition {}"
+ .format(size, name, old_size))
+ else:
+ # insert size items, initialized with 0
+ self.defined_names[var_name] = ["0"] * size
diff --git a/pp2cc.py b/pp2cc.py
index 8f6a581..03a57a1 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -1000,7 +1000,8 @@ class Parse(object):
size += 1
try:
- linked_node.variables.declName(name, size)
+ is_static = "static" in linked_node.node.storage
+ linked_node.variables.declName(name, size, is_static=is_static)
# address of variable split up in register and displacement
var_reg, var_disp = linked_node.variables.getAddress(name)
except RuntimeError as errmsg: