summaryrefslogtreecommitdiff
path: root/pp2cc.py
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-11-29 13:26:55 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-11-29 13:26:55 +0000
commit82396a5e3f6020345bbbabbc03295679bc0621fb (patch)
tree3bf373b371f8a2e716c4fa3eb942f80556d4a781 /pp2cc.py
parent6890b1638700688df26e9d2cf809cfb8d976a15e (diff)
downloadpp2cc-82396a5e3f6020345bbbabbc03295679bc0621fb.tar.gz
Support indirection operator and pointer assignment
Diffstat (limited to 'pp2cc.py')
-rwxr-xr-xpp2cc.py42
1 files changed, 28 insertions, 14 deletions
diff --git a/pp2cc.py b/pp2cc.py
index 0e3fe28..742faaf 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -643,8 +643,7 @@ class Parse(object):
elif op == "&":
raise RuntimeError("Address operator '&' is not supported.")
elif op == "*":
- # XXX support writing to addresses? (IOAREA)
- raise RuntimeError("Indirection operator '*' is not supported.")
+ lines.append(self.asm.binary_op("LOAD", reg, "[" + reg + "]"))
elif op == "sizeof":
raise RuntimeError("Sizeof operator 'sizeof' is not supported.")
elif op == "p++" or op == "p--":
@@ -917,25 +916,40 @@ class Parse(object):
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.parseExpression(node.rvalue, linked_node)
lines += expr_result
result_reg = self.registers.find_register(expr_result)
+
+ self.registers.alloc(result_reg)
+ lvalue_reg = self.registers.alloc()
+ self.registers.free(lvalue_reg)
+ self.registers.free(result_reg)
+ lines += self.parseLValue(LinkedNode(node.lvalue, linked_node),
+ register=lvalue_reg)
+
if node.op == "=":
- lines.append(self.asm.binary_op("STOR", result_reg, "[GB+" + var_name + "]"))
+ lines.append(self.asm.binary_op("STOR", result_reg,
+ "[" + lvalue_reg + "]"))
else:
raise RuntimeError("Unsupported assignment operator: " + node.op)
return lines
+ def parseLValue(self, linked_node, register="R0"):
+ lines = []
+ if linked_node.type == "UnaryOp" and linked_node.node.op == "*":
+ lines += self.parseLValue(LinkedNode(linked_node.node.expr,
+ linked_node), register)
+ lines.append(self.asm.binary_op("LOAD", register,
+ "[" + register + "]"))
+ elif linked_node.type == "ID":
+ name = linked_node.node.name
+ if not name in self.globalVars:
+ raise RuntimeError("Use of undefined variable '{}'".format(name))
+ var_name = self.nameToVar(name)
+ lines.append(self.asm.binary_op("LOAD", register, "GB"))
+ lines.append(self.asm.binary_op("ADD", register, var_name))
+ else:
+ raise RuntimeError("Expected a lvalue (pointer or names)")
+ return lines
def parseDecl(self, linked_node):
lines = []
varname = linked_node.node.name