From 16eb62608bbec4781621b67550d3c2ebf9c00ff8 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 30 Nov 2011 19:09:16 +0000 Subject: Support for evil goto and labels (debugging aid!!!) --- pp2cc.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pp2cc.py b/pp2cc.py index ca50191..78ce05d 100755 --- a/pp2cc.py +++ b/pp2cc.py @@ -289,10 +289,15 @@ class LinkedNode(object): if defined_names is None: raise RuntimeError("No object found for storing variables") self.variables = Variables(defined_names, parent_variables) + # Identifiers which are in use (think of variables and labels) + self.defined_names = defined_names if not self.variables: raise RuntimeError("No variables object found") if level_increment: self.incrementLevel() + # labels are limited to function contexts + if self.type == "FuncDef": + self.goto_labels = {} def handle_post_lines(self, lines): """Add post-increment lines to the lines list and clear the queue""" lines += self.post_lines @@ -372,6 +377,32 @@ class LinkedNode(object): if self.parent: return self.parent.getContinueNode() return None + def setLabel(self, label_name): + """Sets the label for this node""" + if self.parent: + function = self.parent.getFunctionNode() + if not self.parent or not function: + raise RuntimeError("Labels are only allowed in functions") + if label_name in function.goto_labels: + raise RuntimeError("Duplicate label '{}'".format(label_name)) + + label_asm = "lbl_" + label_name + i = 0 + while label_asm in self.defined_names: + label_asm = "lbl_" + label_name + str(i) + i += 1 + + function.goto_labels[label_name] = label_asm + def lookupLabel(self, label_name): + """Returns the label name as it appears in assembly for label_name""" + # get the nearest function for this node + if self.parent: + function = self.parent.getFunctionNode() + if not self.parent or not function: + raise RuntimeError("Labels are only allowed in functions") + if label_name in function.goto_labels: + return function.goto_labels[label_name] + raise RuntimeError("Label '{}' used but not defined".format(name)) class Function(object): def __init__(self, node): @@ -1301,6 +1332,19 @@ class Parse(object): lines.append(self.asm.binary_op("LOAD", name_reg, "[" + name_reg + "+" + index_reg + "]")) return lines + def parseLabel(self, linked_node): + lines = [] + label_name = linked_node.node.name + linked_node.setLabel(label_name) + lines.append(self.asm.noop(label_name)) + lines += self.parseStatement(linked_node.node.stmt, linked_node) + return lines + def parseGoto(self, linked_node): + """Provides support for the infinitely abused goto statement. Use it + for debugging only! + """ + label_name = linked_node.lookupLabel(linked_node.node.name) + return [self.asm.branch_op("BRA", label_name)] 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 -- cgit v1.2.1