summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-11-27 14:08:03 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-11-27 14:08:03 +0000
commitd511864f8ad4094e0a96bbae384ee0913538aa36 (patch)
treec0472b92a15edae5bcbfcb3480d4e4386d10be21
parent0821309cb715d239f03f815a7c2c1a5e29932dbf (diff)
downloadpp2cc-d511864f8ad4094e0a96bbae384ee0913538aa36.tar.gz
Allow for declaration of variables within functions. Warning: local variables
are not implemented, every variable is global
-rwxr-xr-xpp2cc.py45
1 files 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