From 0821309cb715d239f03f815a7c2c1a5e29932dbf Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 27 Nov 2011 13:31:39 +0000 Subject: Support assignment using '=', support symbolic names (variables) --- pp2cc.py | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file 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 -- cgit v1.2.1