def flatten (self, node): """Takes an AST as input, and then "flattens" the tree into a list of statements.""" if isinstance(node, Function): # This is not a Function returned from the parse stage, but a top-level function # that is created in the closure-conversion pass. # We just need to flatten the "code" attribute, which is a Stmt. # Function(decorators, name, argnames, defaults, flags, doc, code, lineno=None) self.log.debug('in visit_Function, node.code = %s',node.code) code = self.flatten(node.code) for x in node.argnames: self.varalloc.add_var(x) return Function(node.decorators, node.name, node.argnames, node.defaults, node.flags, node.doc, code, node.lineno) elif isinstance(node, Return): x = self.flatten(node.value) retvar, retstmtlist = self.flatten(node.value) return retstmtlist + [Return(retvar)] elif isinstance(node, CallFuncIndirect): self.log.debug('CallFuncIndirect: args: %s', node.args) nodevar, nodestmtlist = self.flatten(node.node) tuplelist = [self.flatten(x) for x in node.args] varargs = [x[0] for x in tuplelist] varstmts = [x[1] for x in tuplelist] varname = self.varalloc.get_next_var() stmts = nodestmtlist + reduce(lambda x,y: x+y, varstmts, []) + [Assign([AssName(varname, 'OP_ASSIGN')], CallFuncIndirect(nodevar, varargs))] return (Name(varname), stmts) else: return P1Flattener.flatten(self, node)
def flatten(self, node): """Takes an AST as input, and then "flattens" the tree into a list of statements.""" if isinstance(node, Function): # This is not a Function returned from the parse stage, but a top-level function # that is created in the closure-conversion pass. # We just need to flatten the "code" attribute, which is a Stmt. # Function(decorators, name, argnames, defaults, flags, doc, code, lineno=None) self.log.debug('in visit_Function, node.code = %s', node.code) code = self.flatten(node.code) for x in node.argnames: self.varalloc.add_var(x) return Function(node.decorators, node.name, node.argnames, node.defaults, node.flags, node.doc, code, node.lineno) elif isinstance(node, Return): x = self.flatten(node.value) retvar, retstmtlist = self.flatten(node.value) return retstmtlist + [Return(retvar)] elif isinstance(node, CallFuncIndirect): self.log.debug('CallFuncIndirect: args: %s', node.args) nodevar, nodestmtlist = self.flatten(node.node) tuplelist = [self.flatten(x) for x in node.args] varargs = [x[0] for x in tuplelist] varstmts = [x[1] for x in tuplelist] varname = self.varalloc.get_next_var() stmts = nodestmtlist + reduce(lambda x, y: x + y, varstmts, []) + [ Assign([AssName(varname, 'OP_ASSIGN')], CallFuncIndirect(nodevar, varargs)) ] return (Name(varname), stmts) else: return P1Flattener.flatten(self, node)
return node if __name__ == "__main__": import sys, compiler import logging, logging.config from comp_util import * from p0parser import P0Parser from p1flattener import P1Flattener from p1insselector import P1InstructionSelector if len(sys.argv) < 2: sys.exit(1) # configure logging logging.config.fileConfig('logging.cfg') testcases = sys.argv[1:] for testcase in testcases: #parser = P0Parser() #parser.build() ast = compiler.parseFile(testcase) #ast = parser.parseFile(testcase) varalloc = VariableAllocator() explicator = P1Explicate(varalloc) flattener = P1Flattener(varalloc) instruction_selector = P1InstructionSelector(varalloc) ast = explicator.explicate(ast) ast = flattener.flatten(ast) ast = instruction_selector.visit(ast) stackallocator = P1StackAllocator(ast) ast = stackallocator.substitute() print prettyAST(ast)
def __init__ (self, varalloc, validate=False): P1Flattener.__init__(self, varalloc) self.validate = validate
def __init__(self, varalloc, validate=False): P1Flattener.__init__(self, varalloc) self.validate = validate