cinap_lenrekadd hg and python4bb9e2215 years agoHistory
1533 lines · 46.1 KB · Python
RawDownload
        '//=': 'INPLACE_FLOOR_DIVIDE',        '%=' : 'INPLACE_MODULO',        '**=': 'INPLACE_POWER',        '>>=': 'INPLACE_RSHIFT',        '<<=': 'INPLACE_LSHIFT',        '&=' : 'INPLACE_AND',        '^=' : 'INPLACE_XOR',        '|=' : 'INPLACE_OR',        }     def visitAugName(self, node, mode):        if mode == "load":            self.loadName(node.name)        elif mode == "store":            self.storeName(node.name)     def visitAugGetattr(self, node, mode):        if mode == "load":            self.visit(node.expr)            self.emit('DUP_TOP')            self.emit('LOAD_ATTR', self.mangle(node.attrname))        elif mode == "store":            self.emit('ROT_TWO')            self.emit('STORE_ATTR', self.mangle(node.attrname))     def visitAugSlice(self, node, mode):        if mode == "load":            self.visitSlice(node, 1)        elif mode == "store":            slice = 0            if node.lower:                slice = slice | 1            if node.upper:                slice = slice | 2            if slice == 0:                self.emit('ROT_TWO')            elif slice == 3:                self.emit('ROT_FOUR')            else:                self.emit('ROT_THREE')            self.emit('STORE_SLICE+%d' % slice)     def visitAugSubscript(self, node, mode):        if mode == "load":            self.visitSubscript(node, 1)        elif mode == "store":            self.emit('ROT_THREE')            self.emit('STORE_SUBSCR')     def visitExec(self, node):        self.visit(node.expr)        if node.locals is None:            self.emit('LOAD_CONST', None)        else:            self.visit(node.locals)        if node.globals is None:            self.emit('DUP_TOP')        else:            self.visit(node.globals)        self.emit('EXEC_STMT')     def visitCallFunc(self, node):        pos = 0        kw = 0        self.set_lineno(node)        self.visit(node.node)        for arg in node.args:            self.visit(arg)            if isinstance(arg, ast.Keyword):                kw = kw + 1            else:                pos = pos + 1        if node.star_args is not None:            self.visit(node.star_args)        if node.dstar_args is not None:            self.visit(node.dstar_args)        have_star = node.star_args is not None        have_dstar = node.dstar_args is not None        opcode = callfunc_opcode_info[have_star, have_dstar]        self.emit(opcode, kw << 8 | pos)     def visitPrint(self, node, newline=0):        self.set_lineno(node)        if node.dest:            self.visit(node.dest)        for child in node.nodes:            if node.dest:                self.emit('DUP_TOP')            self.visit(child)            if node.dest:                self.emit('ROT_TWO')                self.emit('PRINT_ITEM_TO')            else:                self.emit('PRINT_ITEM')        if node.dest and not newline:            self.emit('POP_TOP')     def visitPrintnl(self, node):        self.visitPrint(node, newline=1)        if node.dest:            self.emit('PRINT_NEWLINE_TO')        else:            self.emit('PRINT_NEWLINE')     def visitReturn(self, node):        self.set_lineno(node)        self.visit(node.value)        self.emit('RETURN_VALUE')     def visitYield(self, node):        self.set_lineno(node)        self.visit(node.value)        self.emit('YIELD_VALUE')     # slice and subscript stuff     def visitSlice(self, node, aug_flag=None):        # aug_flag is used by visitAugSlice        self.visit(node.expr)        slice = 0        if node.lower:            self.visit(node.lower)            slice = slice | 1        if node.upper:            self.visit(node.upper)            slice = slice | 2        if aug_flag:            if slice == 0:                self.emit('DUP_TOP')            elif slice == 3:                self.emit('DUP_TOPX', 3)            else:                self.emit('DUP_TOPX', 2)        if node.flags == 'OP_APPLY':            self.emit('SLICE+%d' % slice)        elif node.flags == 'OP_ASSIGN':            self.emit('STORE_SLICE+%d' % slice)        elif node.flags == 'OP_DELETE':            self.emit('DELETE_SLICE+%d' % slice)        else:            print "weird slice", node.flags            raise     def visitSubscript(self, node, aug_flag=None):        self.visit(node.expr)        for sub in node.subs:            self.visit(sub)        if len(node.subs) > 1:            self.emit('BUILD_TUPLE', len(node.subs))        if aug_flag:            self.emit('DUP_TOPX', 2)        if node.flags == 'OP_APPLY':            self.emit('BINARY_SUBSCR')        elif node.flags == 'OP_ASSIGN':            self.emit('STORE_SUBSCR')        elif node.flags == 'OP_DELETE':            self.emit('DELETE_SUBSCR')     # binary ops     def binaryOp(self, node, op):        self.visit(node.left)        self.visit(node.right)        self.emit(op)     def visitAdd(self, node):        return self.binaryOp(node, 'BINARY_ADD')     def visitSub(self, node):        return self.binaryOp(node, 'BINARY_SUBTRACT')     def visitMul(self, node):        return self.binaryOp(node, 'BINARY_MULTIPLY')     def visitDiv(self, node):        return self.binaryOp(node, self._div_op)     def visitFloorDiv(self, node):        return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')     def visitMod(self, node):        return self.binaryOp(node, 'BINARY_MODULO')     def visitPower(self, node):        return self.binaryOp(node, 'BINARY_POWER')     def visitLeftShift(self, node):        return self.binaryOp(node, 'BINARY_LSHIFT')     def visitRightShift(self, node):        return self.binaryOp(node, 'BINARY_RSHIFT')     # unary ops     def unaryOp(self, node, op):        self.visit(node.expr)        self.emit(op)     def visitInvert(self, node):        return self.unaryOp(node, 'UNARY_INVERT')     def visitUnarySub(self, node):        return self.unaryOp(node, 'UNARY_NEGATIVE')     def visitUnaryAdd(self, node):        return self.unaryOp(node, 'UNARY_POSITIVE')     def visitUnaryInvert(self, node):        return self.unaryOp(node, 'UNARY_INVERT')     def visitNot(self, node):        return self.unaryOp(node, 'UNARY_NOT')     def visitBackquote(self, node):        return self.unaryOp(node, 'UNARY_CONVERT')     # bit ops     def bitOp(self, nodes, op):        self.visit(nodes[0])        for node in nodes[1:]:            self.visit(node)            self.emit(op)     def visitBitand(self, node):        return self.bitOp(node.nodes, 'BINARY_AND')     def visitBitor(self, node):        return self.bitOp(node.nodes, 'BINARY_OR')     def visitBitxor(self, node):        return self.bitOp(node.nodes, 'BINARY_XOR')     # object constructors     def visitEllipsis(self, node):        self.emit('LOAD_CONST', Ellipsis)     def visitTuple(self, node):        self.set_lineno(node)        for elt in node.nodes:            self.visit(elt)        self.emit('BUILD_TUPLE', len(node.nodes))     def visitList(self, node):        self.set_lineno(node)        for elt in node.nodes:            self.visit(elt)        self.emit('BUILD_LIST', len(node.nodes))     def visitSliceobj(self, node):        for child in node.nodes:            self.visit(child)        self.emit('BUILD_SLICE', len(node.nodes))     def visitDict(self, node):        self.set_lineno(node)        self.emit('BUILD_MAP', 0)        for k, v in node.items:            self.emit('DUP_TOP')            self.visit(k)            self.visit(v)            self.emit('ROT_THREE')            self.emit('STORE_SUBSCR') class NestedScopeMixin:    """Defines initClass() for nested scoping (Python 2.2-compatible)"""    def initClass(self):        self.__class__.NameFinder = LocalNameFinder        self.__class__.FunctionGen = FunctionCodeGenerator        self.__class__.ClassGen = ClassCodeGenerator class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):    __super_init = CodeGenerator.__init__     scopes = None     def __init__(self, tree):        self.graph = pyassem.PyFlowGraph("<module>", tree.filename)        self.futures = future.find_futures(tree)        self.__super_init()        walk(tree, self)     def get_module(self):        return self class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):    __super_init = CodeGenerator.__init__     scopes = None    futures = ()     def __init__(self, tree):        self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)        self.__super_init()        walk(tree, self)     def get_module(self):        return self class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):     __super_init = CodeGenerator.__init__     scopes = None    futures = ()     def __init__(self, tree):        self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)        self.__super_init()        self.set_lineno(tree)        walk(tree, self)        self.emit('RETURN_VALUE')     def get_module(self):        return self     def visitDiscard(self, node):        # XXX Discard means it's an expression.  Perhaps this is a bad        # name.        self.visit(node.expr)        self.emit('PRINT_EXPR') class AbstractFunctionCode:    optimized = 1    lambdaCount = 0     def __init__(self, func, scopes, isLambda, class_name, mod):        self.class_name = class_name        self.module = mod        if isLambda:            klass = FunctionCodeGenerator            name = "<lambda.%d>" % klass.lambdaCount            klass.lambdaCount = klass.lambdaCount + 1        else:            name = func.name         args, hasTupleArg = generateArgList(func.argnames)        self.graph = pyassem.PyFlowGraph(name, func.filename, args,                                         optimized=1)        self.isLambda = isLambda        self.super_init()         if not isLambda and func.doc:            self.setDocstring(func.doc)         lnf = walk(func.code, self.NameFinder(args), verbose=0)        self.locals.push(lnf.getLocals())        if func.varargs:            self.graph.setFlag(CO_VARARGS)        if func.kwargs:            self.graph.setFlag(CO_VARKEYWORDS)        self.set_lineno(func)        if hasTupleArg:            self.generateArgUnpack(func.argnames)     def get_module(self):        return self.module     def finish(self):        self.graph.startExitBlock()        if not self.isLambda:            self.emit('LOAD_CONST', None)        self.emit('RETURN_VALUE')     def generateArgUnpack(self, args):        for i in range(len(args)):            arg = args[i]            if isinstance(arg, tuple):                self.emit('LOAD_FAST', '.%d' % (i * 2))                self.unpackSequence(arg)     def unpackSequence(self, tup):        if VERSION > 1:            self.emit('UNPACK_SEQUENCE', len(tup))        else:            self.emit('UNPACK_TUPLE', len(tup))        for elt in tup:            if isinstance(elt, tuple):                self.unpackSequence(elt)            else:                self._nameOp('STORE', elt)     unpackTuple = unpackSequence class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,                            CodeGenerator):    super_init = CodeGenerator.__init__ # call be other init    scopes = None     __super_init = AbstractFunctionCode.__init__     def __init__(self, func, scopes, isLambda, class_name, mod):        self.scopes = scopes        self.scope = scopes[func]        self.__super_init(func, scopes, isLambda, class_name, mod)        self.graph.setFreeVars(self.scope.get_free_vars())        self.graph.setCellVars(self.scope.get_cell_vars())        if self.scope.generator is not None:            self.graph.setFlag(CO_GENERATOR) class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,                           CodeGenerator):    super_init = CodeGenerator.__init__ # call be other init    scopes = None     __super_init = AbstractFunctionCode.__init__     def __init__(self, gexp, scopes, class_name, mod):        self.scopes = scopes        self.scope = scopes[gexp]        self.__super_init(gexp, scopes, 1, class_name, mod)        self.graph.setFreeVars(self.scope.get_free_vars())        self.graph.setCellVars(self.scope.get_cell_vars())        self.graph.setFlag(CO_GENERATOR) class AbstractClassCode:     def __init__(self, klass, scopes, module):        self.class_name = klass.name        self.module = module        self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,                                           optimized=0, klass=1)        self.super_init()        lnf = walk(klass.code, self.NameFinder(), verbose=0)        self.locals.push(lnf.getLocals())        self.graph.setFlag(CO_NEWLOCALS)        if klass.doc:            self.setDocstring(klass.doc)     def get_module(self):        return self.module     def finish(self):        self.graph.startExitBlock()        self.emit('LOAD_LOCALS')        self.emit('RETURN_VALUE') class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):    super_init = CodeGenerator.__init__    scopes = None     __super_init = AbstractClassCode.__init__     def __init__(self, klass, scopes, module):        self.scopes = scopes        self.scope = scopes[klass]        self.__super_init(klass, scopes, module)        self.graph.setFreeVars(self.scope.get_free_vars())        self.graph.setCellVars(self.scope.get_cell_vars())        self.set_lineno(klass)        self.emit("LOAD_GLOBAL", "__name__")        self.storeName("__module__")        if klass.doc:            self.emit("LOAD_CONST", klass.doc)            self.storeName('__doc__') def generateArgList(arglist):    """Generate an arg list marking TupleArgs"""    args = []    extra = []    count = 0    for i in range(len(arglist)):        elt = arglist[i]        if isinstance(elt, str):            args.append(elt)        elif isinstance(elt, tuple):            args.append(TupleArg(i * 2, elt))            extra.extend(misc.flatten(elt))            count = count + 1        else:            raise ValueError, "unexpect argument type:", elt    return args + extra, count def findOp(node):    """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""    v = OpFinder()    walk(node, v, verbose=0)    return v.op class OpFinder:    def __init__(self):        self.op = None    def visitAssName(self, node):        if self.op is None:            self.op = node.flags        elif self.op != node.flags:            raise ValueError, "mixed ops in stmt"    visitAssAttr = visitAssName    visitSubscript = visitAssName class Delegator:    """Base class to support delegation for augmented assignment nodes     To generator code for augmented assignments, we use the following    wrapper classes.  In visitAugAssign, the left-hand expression node    is visited twice.  The first time the visit uses the normal method    for that node .  The second time the visit uses a different method    that generates the appropriate code to perform the assignment.    These delegator classes wrap the original AST nodes in order to

Lines 1001–1500 of 1533. Previous lines