summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AsmLine.py15
-rw-r--r--AsmParser.py9
-rw-r--r--Variables.py5
-rwxr-xr-xpp2cc.py24
4 files changed, 37 insertions, 16 deletions
diff --git a/AsmLine.py b/AsmLine.py
index 4561b30..5a5249f 100644
--- a/AsmLine.py
+++ b/AsmLine.py
@@ -47,25 +47,25 @@ class AsmLine(object):
line = label + ":" + line
parts = self.re_whitespace.split(line, 1)
- instruction = parts[0]
+ self.instruction = parts[0]
- if instruction in Asm.operators_binary:
+ if self.instruction in Asm.operators_binary:
# a label for sure
reg, operand = self.re_whitespace.split(parts[1], 1)
self.register = reg
self.setOperand(operand)
- elif instruction in Asm.operators_branch:
+ elif self.instruction in Asm.operators_branch:
# skip validation of reg for speed
self.register = parts[1]
- elif instruction in Asm.operators_unary:
+ elif self.instruction in Asm.operators_unary:
self.setOperand(parts[1])
- elif instruction in Asm.operators_misc_reg:
+ elif self.instruction in Asm.operators_misc_reg:
self.register = parts[1]
- elif instruction in Asm.operators_misc_noreg:
+ elif self.instruction in Asm.operators_misc_noreg:
# no args
pass
else:
- raise RuntimeError("Unknown instruction '{}'".format(instruction))
+ raise RuntimeError("Unknown instruction '{}'".format(self.instruction))
def setOperand(self, str):
"""Sets the operand for this object either as a string or an identifier
object
@@ -112,3 +112,4 @@ class AsmLine(object):
if self.operand:
# join all operand parts together
line += " " + "".join(str(elm) for elm in self.operand)
+ return line
diff --git a/AsmParser.py b/AsmParser.py
index 4ab25ed..24755f6 100644
--- a/AsmParser.py
+++ b/AsmParser.py
@@ -29,7 +29,7 @@ class AsmParser(object):
self.defined_names = parent.defined_names
else:
self.parent = None
- self.data = []
+ self.data = {}
self.code = []
# defined labels for the assembly files
self.labels = []
@@ -99,7 +99,7 @@ class AsmParser(object):
if what == "DS":
# DS initializes names with zero, let's convert it to
# DW to make it compatible with the Parser
- self.addData(name, [0 for x in range(0, int(data))])
+ self.addData(name, ["0"] * int(data))
else:
self.addData(name, data.split(","))
line = ""
@@ -166,4 +166,7 @@ class AsmParser(object):
if self.parent:
raise RuntimeError("You can only get the lines for @CODE from the"
" root node")
- return [elm for elm in self.code]
+ return [str(elm) for elm in self.code]
+ def getDataDefinitions(self):
+ """Returns the data section as a dictionary"""
+ return self.data \ No newline at end of file
diff --git a/Variables.py b/Variables.py
index bab1a34..b84d0ad 100644
--- a/Variables.py
+++ b/Variables.py
@@ -118,4 +118,7 @@ class GlobalVariables(Variables):
# global variables are prefixed "var_"
var_name = self._uniqName("var_" + name)
self.global_vars[name] = var_name
- self.defined_names[var_name] = size
+ if var_name not in self.defined_names:
+ self.defined_names[var_name] = []
+ # insert size items, initialized with 0
+ self.defined_names[var_name] += ["0"] * size
diff --git a/pp2cc.py b/pp2cc.py
index ffe9ee4..d3aac94 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -80,7 +80,8 @@ class Parse(object):
self.binary_ops.update(self.comparison_ops)
self.binary_ops.update(self.shift_ops)
- # local and global variable names to be defined in @DATA
+ # global variable names to be defined in @DATA. key: name, value: list
+ # of initializers
self.varNames = {}
self.functions = {}
# holds instructions for initializing the global variables
@@ -158,16 +159,29 @@ class Parse(object):
new_label = self.uniqLbl(label)
self.asm_node.renameId(label, new_label)
self.labels.add(new_label)
+ for name, init_vals in self.asm_node.getDataDefinitions().iteritems():
+ if name in self.varNames:
+ old_count = len(self.varNames[name])
+ new_count = len(init_vals)
+ if old_count != new_count:
+ self.logger.error("Global variable '{}' was defined before"
+ ", but the length of the initializers"
+ " are not equal. Old: {}, new: {}"
+ .format(name, old_count, new_count))
+ elif self.varNames[name] != init_vals:
+ self.logger.warning("The initialization of global variable"
+ " '{}' contains different values"
+ .format(name))
+ self.varNames[name] = init_vals
self.codeSegment += self.asm_node.getCodeLines()
def getSource(self):
"""Retrieves the ASM source. You need to compile it first"""
output = []
output.append("@DATA")
- for varName, size in self.varNames.iteritems():
+ for varName, initializers in self.varNames.iteritems():
padding = " " * (16 - len(varName) - 1)
- assert size > 0, "Size of '{}' must be at least 1".format(varName)
- initializers = "0,".repeat(size)[0:-1]
- output.append(varName + padding + " DW " + initializers)
+ assert len(initializers) > 0, "Size of '{}' must be at least 1".format(varName)
+ output.append(varName + padding + " DW " + ",".join(initializers))
output.append("")
output.append("@CODE")
# initialization of global variables