From d511864f8ad4094e0a96bbae384ee0913538aa36 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 27 Nov 2011 14:08:03 +0000 Subject: Allow for declaration of variables within functions. Warning: local variables are not implemented, every variable is global --- pp2cc.py | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/pp2cc.py b/pp2cc.py index d09d792..db1886e 100755 --- a/pp2cc.py +++ b/pp2cc.py @@ -251,14 +251,13 @@ class Parse(object): """Loops through the nodes in an AST syntax tree and generates ASM""" root_node = LinkedNode(self.node) for thing in self.node.ext: - linked_node = LinkedNode(thing, root_node) - self.asm.level = linked_node.level - if isinstance(thing, c_ast.Decl): - self.defineGlobalVar(linked_node) - elif isinstance(thing, c_ast.FuncDef): - self.defineFunction(linked_node) - else: - raise RuntimeError("I don't know a node in the global scope: " + str(thing)) + if not isinstance(thing, c_ast.Decl) and not isinstance(thing, c_ast.FuncDef): + linked_node = LinkedNode(thing, parent=root_node) + self.logger.warning("I expected a variable or function" + " definition or declaration in the root" + " node, but also found " + + str(thing), linked_node=linked_node) + self.codeSegment += self.parseStatement(thing, root_node) def getSource(self): """Retrieves the ASM source. You need to compile it first""" self.addSource("@DATA") @@ -274,9 +273,6 @@ class Parse(object): self.addSource("@END") def addSource(self, line=''): print line - 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 @@ -284,7 +280,7 @@ class Parse(object): name -- This name will be returned with the var_ prefix """ return "var_" + name - def defineFunction(self, linked_node): + def parseFuncDef(self, linked_node): node = linked_node.node linked_node.incrementLevel() self.asm.level = linked_node.level @@ -300,21 +296,20 @@ class Parse(object): self.addLabel(lbl_end) linked_node.setFunction(function) - self.codeSegment.append(self.asm.noop(lbl_func)) + lines = [self.asm.noop(lbl_func)] - stmts = self.parseStatement(node.body, linked_node) + lines += self.parseStatement(node.body, linked_node) self.asm.level = linked_node.level - for stmt in stmts: - self.codeSegment.append(stmt) - + # functions other than main() are subroutines #if funcname != "main": # since main should never be left, add the instruction anyway. # Otherwise, it'd crash anyway because it loops into the stack (if it # had not crashed before) - self.codeSegment.append(self.asm.format_line("RTS", label=lbl_end)) + lines.append(self.asm.format_line("RTS", label=lbl_end)) # add an extra newline - self.codeSegment.append("") + lines.append("") + return lines def functionLabel(self, name): if name in self.functions: function = self.functions[name] @@ -793,13 +788,17 @@ class Parse(object): else: raise RuntimeError("Unsupported assignment operator: " + node.op) return lines + def parseDecl(self, linked_node): + varname = linked_node.node.name + if varname in self.globalVars: + raise RuntimeError("Redefinition of variable '{}'".format(varname)) + self.globalVars.append(varname) + return [] 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.Decl): - self.defineGlobalVar(linked_node) - elif isinstance(node, c_ast.FuncDecl): + if isinstance(node, c_ast.FuncDecl): raise RuntimeError("Not implemented for type " + repr(node)) elif isinstance(node, c_ast.PtrDecl): raise RuntimeError("Not implemented for type " + repr(node)) @@ -807,7 +806,7 @@ class Parse(object): for entry in ("Compound", "BinaryOp", "If", "Constant", "ID", "Return", "FuncCall", "UnaryOp", "Cast", "TernaryOp", "DoWhile", "While", "For", "ExprList", - "Assignment"): + "Assignment", "Decl", "FuncDef"): if isinstance(node, getattr(c_ast, entry)): lines += getattr(self, "parse" + entry)(linked_node) break -- cgit v1.2.1