summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-11-27 11:51:28 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-11-27 11:51:28 +0000
commit05b07aa2580c063d8c3dffd5eb147e5b4078783f (patch)
treeabd451d6ea881a98eabd4311ca34f5d70054313d
parentd86d01eb11da9a736dc708ceb0341cdc24526a6a (diff)
downloadpp2cc-05b07aa2580c063d8c3dffd5eb147e5b4078783f.tar.gz
Support for loops
-rwxr-xr-xpp2cc.py33
1 files changed, 30 insertions, 3 deletions
diff --git a/pp2cc.py b/pp2cc.py
index 38858d1..c050cf6 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -725,6 +725,35 @@ class Parse(object):
# }
lines.append(self.asm.noop(lbl_while_end))
return lines
+ def parseFor(self, linked_node):
+ """Returns ASM for a for loop
+
+ for (init; cond; next) { body; } is equivalent to:
+ init; while (cond) { body; next; }
+ Note that for (;;){} is allowed too which is equivalent to:
+ while (true) {}
+ """
+ node = linked_node.node
+ lines = []
+ lbl_for = self.uniqLbl("for")
+ lbl_for_end = self.uniqLbl("forEnd")
+
+ if node.init: # init;
+ lines += self.parseStatement(node.init, linked_node)
+ # while (
+ lines.append(self.asm.noop(lbl_for))
+ if node.cond: # if no condition, it's should evaluate to true
+ lines += self.parseStatement(node.cond, linked_node)
+ lines.append(self.asm.branch_op("BEQ", lbl_for_end))
+ # ){ body;
+ lines += self.parseStatement(node.stmt, linked_node)
+ if node.next: # next;
+ lines += self.parseStatement(node.next, linked_node)
+
+ lines.append(self.asm.branch_op("BRA", lbl_for))
+ # }
+ lines.append(self.asm.noop(lbl_for_end))
+ 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
@@ -735,8 +764,6 @@ class Parse(object):
self.defineGlobalVar(linked_node, parent_linked_node)
elif isinstance(node, c_ast.ExprList):
raise RuntimeError("Not implemented for type " + repr(node))
- elif isinstance(node, c_ast.For):
- raise RuntimeError("Not implemented for type " + repr(node))
elif isinstance(node, c_ast.FuncDecl):
raise RuntimeError("Not implemented for type " + repr(node))
elif isinstance(node, c_ast.PtrDecl):
@@ -744,7 +771,7 @@ class Parse(object):
else:
for entry in ("Compound", "BinaryOp", "If", "Constant", "ID",
"Return", "FuncCall", "UnaryOp", "Cast",
- "TernaryOp", "DoWhile", "While"):
+ "TernaryOp", "DoWhile", "While", "For"):
if isinstance(node, getattr(c_ast, entry)):
lines += getattr(self, "parse" + entry)(linked_node)
break