summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-11-27 13:31:39 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-11-27 13:31:39 +0000
commit0821309cb715d239f03f815a7c2c1a5e29932dbf (patch)
treef7dfc36b0910866bf5abe9f16280f9e8ebd07b4b
parenta7627f22ece738c3df8cb6c3d1502c7e9b20dbf2 (diff)
downloadpp2cc-0821309cb715d239f03f815a7c2c1a5e29932dbf.tar.gz
Support assignment using '=', support symbolic names (variables)
-rwxr-xr-xpp2cc.py49
1 files changed, 41 insertions, 8 deletions
diff --git a/pp2cc.py b/pp2cc.py
index ff81fc5..d09d792 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -264,7 +264,7 @@ class Parse(object):
self.addSource("@DATA")
for varName in self.globalVars:
padding = " " * (16 - len(varName) - 1)
- self.addSource(varName + padding + " DW 1")
+ self.addSource(self.nameToVar(varName) + padding + " DW 1")
self.addSource()
self.addSource("@CODE")
for line in self.codeSegment:
@@ -277,6 +277,13 @@ class Parse(object):
def defineGlobalVar(self, linked_node):
varname = linked_node.node.name
self.globalVars.append(varname)
+ def nameToVar(self, name):
+ """Returns the variable name which will be used in assembly
+
+ Keyword list:
+ name -- This name will be returned with the var_ prefix
+ """
+ return "var_" + name
def defineFunction(self, linked_node):
node = linked_node.node
linked_node.incrementLevel()
@@ -617,8 +624,12 @@ class Parse(object):
else:
raise RuntimeError("Unsupported constant type: " + node.type)
return [self.asm.binary_op("LOAD", register, value)]
- def parseID(self, linked_node):
- raise RuntimeError("Not implemented yet: symbolic names")
+ def parseID(self, linked_node, register="R0"):
+ name = linked_node.node.name
+ if not name in self.globalVars:
+ raise RuntimeError("Use of undefined variable '{}'".format(name))
+ var_name = self.nameToVar(name)
+ return [self.asm.binary_op("LOAD", register, "[GB+" + var_name + "]")]
def parseIf(self, linked_node):
linked_node.incrementLevel()
node = linked_node.node
@@ -759,14 +770,35 @@ class Parse(object):
for expr in linked_node.node.exprs:
lines += self.parseStatement(expr, linked_node)
return lines
+ def parseAssignment(self, linked_node):
+ lines = []
+ node = linked_node.node
+
+ # XXX support other types like pointers
+ if not isinstance(node.lvalue, c_ast.ID):
+ raise RuntimeError("Currently only assignments to symbolic names"
+ "are allowed")
+
+ name = node.lvalue.name
+ # name of variable as it appears in the ASM code
+ if not name in self.globalVars:
+ raise RuntimeError("Assignment to undefined variable '{}'".format(name))
+ var_name = self.nameToVar(node.lvalue.name)
+
+ expr_result = self.parseStatement(node.rvalue, linked_node)
+ lines += expr_result
+ result_reg = self.registers.find_register(expr_result)
+ if node.op == "=":
+ lines.append(self.asm.binary_op("STOR", result_reg, "[GB+" + var_name + "]"))
+ else:
+ raise RuntimeError("Unsupported assignment operator: " + node.op)
+ return lines
def parseStatement(self, node, parent_linked_node, level_increment=False):
linked_node = LinkedNode(node, parent_linked_node, level_increment=level_increment)
self.asm.level = linked_node.level
lines = []
- if isinstance(node, c_ast.Assignment):
- raise RuntimeError("Not implemented for type " + repr(node))
- elif isinstance(node, c_ast.Decl):
- self.defineGlobalVar(linked_node, parent_linked_node)
+ if isinstance(node, c_ast.Decl):
+ self.defineGlobalVar(linked_node)
elif isinstance(node, c_ast.FuncDecl):
raise RuntimeError("Not implemented for type " + repr(node))
elif isinstance(node, c_ast.PtrDecl):
@@ -774,7 +806,8 @@ class Parse(object):
else:
for entry in ("Compound", "BinaryOp", "If", "Constant", "ID",
"Return", "FuncCall", "UnaryOp", "Cast",
- "TernaryOp", "DoWhile", "While", "For", "ExprList"):
+ "TernaryOp", "DoWhile", "While", "For", "ExprList",
+ "Assignment"):
if isinstance(node, getattr(c_ast, entry)):
lines += getattr(self, "parse" + entry)(linked_node)
break