From 6aaff7ae54dbe34ea6bf3f9ee8c93e9d79db3c22 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 1 Dec 2011 22:18:27 +0000 Subject: Fix stack corruption, support func calls with arguments and automatic variables --- LinkedNode.py | 71 +++++++++++++++++++++-------------------------------------- 1 file changed, 25 insertions(+), 46 deletions(-) (limited to 'LinkedNode.py') diff --git a/LinkedNode.py b/LinkedNode.py index 88bc6da..f068993 100644 --- a/LinkedNode.py +++ b/LinkedNode.py @@ -18,12 +18,9 @@ __version__ = "1.0" __maintainer__ = "Peter Wu" __email__ = "uwretep@gmail.com" -from Variables import Variables - class LinkedNode(object): """Stores nodes with a reference to the parent""" - def __init__(self, node, parent=None, level_increment=False, - defined_names=None): + def __init__(self, node, parent=None, level_increment=False): """Holds properties for a node Keyword arguments: @@ -31,8 +28,6 @@ class LinkedNode(object): parent -- a parent LinkedNode object level_increment -- True if the indentation level needs to be incremented, False otherwise - defined_names -- a list of names which will be used in the @DATA - section. If not set, it'll be looked up in the parent """ self.node = node if parent: @@ -46,48 +41,32 @@ class LinkedNode(object): self.variables = None # for supporting post increment and post decrement self.post_lines = [] - parent_variables = None # inherit level and variables from parent if parent: self.level = parent.level - self.variables = parent_variables = parent.variables - if not defined_names: - defined_names = parent.variables.defined_names + self.variables = parent.variables - # for is added for the init part (C99) - if self.type in ("Compound", "FileAST", "For"): - # the node appears to have an own variable scope - if defined_names is None: - raise RuntimeError("No object found for storing variables") - # pass function object for local variables allocation - function = self.getFunctionNode() - if function: - function = function.function - self.variables = Variables(parent_variables, defined_names, - function=function) - # 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 setVariablesObj(self, variables_obj): + """Sets a new variables scope object for this node""" + self.variables = variables_obj def handle_post_lines(self, lines): """Add post-increment lines to the lines list and clear the queue""" lines += self.post_lines self.post_lines = [] - def getScopeNode(self): - """Get the nearest node which introduces a new scope. - - If there is no node found an exception is raised because it expects at - least a global scope""" - if self.local_vars is not None: - return self - if self.parent: - return self.parent.getScopeNode() - raise RuntimeError("No global variable scope was found") + def needNewScope(self): + """Returns True if a new name scope is necessary and False otherwise""" + if self.type == "Compound": + if self.parent.type not in ("For", "FuncDef"): + return True + elif self.type in ("FileAST", "For", "FuncDef"): + return True + return False def isTypeStatement(self): """Returns True if the node is a statement type""" return self.type in ("Compound", "If", "Return", "DoWhile", "While", @@ -118,11 +97,14 @@ class LinkedNode(object): return self.parent.getFunctionNode() return None def setFunction(self, function): - """Sets the function object containing label information""" + """Sets the function object containing label information and a stack + allocation function + """ self.function = function + self.variables.setFunction(function) def getLocation(self): if hasattr(self.node, "coord"): - return self.node.coord + return str(self.node.coord) return "Unknown" def setBreak(self, break_label): """Marks this node as a loop or switch by setting the label for break @@ -153,9 +135,12 @@ class LinkedNode(object): if self.parent: return self.parent.getContinueNode() return None - def setLabel(self, label_name): - """Sets the label for this node and return the label name as it appears - in assembly + def setLabel(self, label_name, label_asm): + """Sets the label for this node + + Keyword arguments: + label_name -- The label name as can be used in C + label_asm -- The label as it appears in assembly """ if self.parent: function = self.parent.getFunctionNode() @@ -164,12 +149,6 @@ class LinkedNode(object): 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 return label_asm def lookupLabel(self, label_name): -- cgit v1.2.1