From 82396a5e3f6020345bbbabbc03295679bc0621fb Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 29 Nov 2011 13:26:55 +0000 Subject: Support indirection operator and pointer assignment --- pp2cc.py | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'pp2cc.py') 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 -- cgit v1.2.1