Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../lib64/python2..../compiler
File: pycodegen.py
import imp
[0] Fix | Delete
import os
[1] Fix | Delete
import marshal
[2] Fix | Delete
import struct
[3] Fix | Delete
import sys
[4] Fix | Delete
from cStringIO import StringIO
[5] Fix | Delete
[6] Fix | Delete
from compiler import ast, parse, walk, syntax
[7] Fix | Delete
from compiler import pyassem, misc, future, symbols
[8] Fix | Delete
from compiler.consts import SC_LOCAL, SC_GLOBAL_IMPLICIT, SC_GLOBAL_EXPLICIT, \
[9] Fix | Delete
SC_FREE, SC_CELL
[10] Fix | Delete
from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
[11] Fix | Delete
CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
[12] Fix | Delete
CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION)
[13] Fix | Delete
from compiler.pyassem import TupleArg
[14] Fix | Delete
[15] Fix | Delete
# XXX The version-specific code can go, since this code only works with 2.x.
[16] Fix | Delete
# Do we have Python 1.x or Python 2.x?
[17] Fix | Delete
try:
[18] Fix | Delete
VERSION = sys.version_info[0]
[19] Fix | Delete
except AttributeError:
[20] Fix | Delete
VERSION = 1
[21] Fix | Delete
[22] Fix | Delete
callfunc_opcode_info = {
[23] Fix | Delete
# (Have *args, Have **args) : opcode
[24] Fix | Delete
(0,0) : "CALL_FUNCTION",
[25] Fix | Delete
(1,0) : "CALL_FUNCTION_VAR",
[26] Fix | Delete
(0,1) : "CALL_FUNCTION_KW",
[27] Fix | Delete
(1,1) : "CALL_FUNCTION_VAR_KW",
[28] Fix | Delete
}
[29] Fix | Delete
[30] Fix | Delete
LOOP = 1
[31] Fix | Delete
EXCEPT = 2
[32] Fix | Delete
TRY_FINALLY = 3
[33] Fix | Delete
END_FINALLY = 4
[34] Fix | Delete
[35] Fix | Delete
def compileFile(filename, display=0):
[36] Fix | Delete
f = open(filename, 'U')
[37] Fix | Delete
buf = f.read()
[38] Fix | Delete
f.close()
[39] Fix | Delete
mod = Module(buf, filename)
[40] Fix | Delete
try:
[41] Fix | Delete
mod.compile(display)
[42] Fix | Delete
except SyntaxError:
[43] Fix | Delete
raise
[44] Fix | Delete
else:
[45] Fix | Delete
f = open(filename + "c", "wb")
[46] Fix | Delete
mod.dump(f)
[47] Fix | Delete
f.close()
[48] Fix | Delete
[49] Fix | Delete
def compile(source, filename, mode, flags=None, dont_inherit=None):
[50] Fix | Delete
"""Replacement for builtin compile() function"""
[51] Fix | Delete
if flags is not None or dont_inherit is not None:
[52] Fix | Delete
raise RuntimeError, "not implemented yet"
[53] Fix | Delete
[54] Fix | Delete
if mode == "single":
[55] Fix | Delete
gen = Interactive(source, filename)
[56] Fix | Delete
elif mode == "exec":
[57] Fix | Delete
gen = Module(source, filename)
[58] Fix | Delete
elif mode == "eval":
[59] Fix | Delete
gen = Expression(source, filename)
[60] Fix | Delete
else:
[61] Fix | Delete
raise ValueError("compile() 3rd arg must be 'exec' or "
[62] Fix | Delete
"'eval' or 'single'")
[63] Fix | Delete
gen.compile()
[64] Fix | Delete
return gen.code
[65] Fix | Delete
[66] Fix | Delete
class AbstractCompileMode:
[67] Fix | Delete
[68] Fix | Delete
mode = None # defined by subclass
[69] Fix | Delete
[70] Fix | Delete
def __init__(self, source, filename):
[71] Fix | Delete
self.source = source
[72] Fix | Delete
self.filename = filename
[73] Fix | Delete
self.code = None
[74] Fix | Delete
[75] Fix | Delete
def _get_tree(self):
[76] Fix | Delete
tree = parse(self.source, self.mode)
[77] Fix | Delete
misc.set_filename(self.filename, tree)
[78] Fix | Delete
syntax.check(tree)
[79] Fix | Delete
return tree
[80] Fix | Delete
[81] Fix | Delete
def compile(self):
[82] Fix | Delete
pass # implemented by subclass
[83] Fix | Delete
[84] Fix | Delete
def getCode(self):
[85] Fix | Delete
return self.code
[86] Fix | Delete
[87] Fix | Delete
class Expression(AbstractCompileMode):
[88] Fix | Delete
[89] Fix | Delete
mode = "eval"
[90] Fix | Delete
[91] Fix | Delete
def compile(self):
[92] Fix | Delete
tree = self._get_tree()
[93] Fix | Delete
gen = ExpressionCodeGenerator(tree)
[94] Fix | Delete
self.code = gen.getCode()
[95] Fix | Delete
[96] Fix | Delete
class Interactive(AbstractCompileMode):
[97] Fix | Delete
[98] Fix | Delete
mode = "single"
[99] Fix | Delete
[100] Fix | Delete
def compile(self):
[101] Fix | Delete
tree = self._get_tree()
[102] Fix | Delete
gen = InteractiveCodeGenerator(tree)
[103] Fix | Delete
self.code = gen.getCode()
[104] Fix | Delete
[105] Fix | Delete
class Module(AbstractCompileMode):
[106] Fix | Delete
[107] Fix | Delete
mode = "exec"
[108] Fix | Delete
[109] Fix | Delete
def compile(self, display=0):
[110] Fix | Delete
tree = self._get_tree()
[111] Fix | Delete
gen = ModuleCodeGenerator(tree)
[112] Fix | Delete
if display:
[113] Fix | Delete
import pprint
[114] Fix | Delete
print pprint.pprint(tree)
[115] Fix | Delete
self.code = gen.getCode()
[116] Fix | Delete
[117] Fix | Delete
def dump(self, f):
[118] Fix | Delete
f.write(self.getPycHeader())
[119] Fix | Delete
marshal.dump(self.code, f)
[120] Fix | Delete
[121] Fix | Delete
MAGIC = imp.get_magic()
[122] Fix | Delete
[123] Fix | Delete
def getPycHeader(self):
[124] Fix | Delete
# compile.c uses marshal to write a long directly, with
[125] Fix | Delete
# calling the interface that would also generate a 1-byte code
[126] Fix | Delete
# to indicate the type of the value. simplest way to get the
[127] Fix | Delete
# same effect is to call marshal and then skip the code.
[128] Fix | Delete
mtime = os.path.getmtime(self.filename)
[129] Fix | Delete
mtime = struct.pack('<i', mtime)
[130] Fix | Delete
return self.MAGIC + mtime
[131] Fix | Delete
[132] Fix | Delete
class LocalNameFinder:
[133] Fix | Delete
"""Find local names in scope"""
[134] Fix | Delete
def __init__(self, names=()):
[135] Fix | Delete
self.names = misc.Set()
[136] Fix | Delete
self.globals = misc.Set()
[137] Fix | Delete
for name in names:
[138] Fix | Delete
self.names.add(name)
[139] Fix | Delete
[140] Fix | Delete
# XXX list comprehensions and for loops
[141] Fix | Delete
[142] Fix | Delete
def getLocals(self):
[143] Fix | Delete
for elt in self.globals.elements():
[144] Fix | Delete
if self.names.has_elt(elt):
[145] Fix | Delete
self.names.remove(elt)
[146] Fix | Delete
return self.names
[147] Fix | Delete
[148] Fix | Delete
def visitDict(self, node):
[149] Fix | Delete
pass
[150] Fix | Delete
[151] Fix | Delete
def visitGlobal(self, node):
[152] Fix | Delete
for name in node.names:
[153] Fix | Delete
self.globals.add(name)
[154] Fix | Delete
[155] Fix | Delete
def visitFunction(self, node):
[156] Fix | Delete
self.names.add(node.name)
[157] Fix | Delete
[158] Fix | Delete
def visitLambda(self, node):
[159] Fix | Delete
pass
[160] Fix | Delete
[161] Fix | Delete
def visitImport(self, node):
[162] Fix | Delete
for name, alias in node.names:
[163] Fix | Delete
self.names.add(alias or name)
[164] Fix | Delete
[165] Fix | Delete
def visitFrom(self, node):
[166] Fix | Delete
for name, alias in node.names:
[167] Fix | Delete
self.names.add(alias or name)
[168] Fix | Delete
[169] Fix | Delete
def visitClass(self, node):
[170] Fix | Delete
self.names.add(node.name)
[171] Fix | Delete
[172] Fix | Delete
def visitAssName(self, node):
[173] Fix | Delete
self.names.add(node.name)
[174] Fix | Delete
[175] Fix | Delete
def is_constant_false(node):
[176] Fix | Delete
if isinstance(node, ast.Const):
[177] Fix | Delete
if not node.value:
[178] Fix | Delete
return 1
[179] Fix | Delete
return 0
[180] Fix | Delete
[181] Fix | Delete
class CodeGenerator:
[182] Fix | Delete
"""Defines basic code generator for Python bytecode
[183] Fix | Delete
[184] Fix | Delete
This class is an abstract base class. Concrete subclasses must
[185] Fix | Delete
define an __init__() that defines self.graph and then calls the
[186] Fix | Delete
__init__() defined in this class.
[187] Fix | Delete
[188] Fix | Delete
The concrete class must also define the class attributes
[189] Fix | Delete
NameFinder, FunctionGen, and ClassGen. These attributes can be
[190] Fix | Delete
defined in the initClass() method, which is a hook for
[191] Fix | Delete
initializing these methods after all the classes have been
[192] Fix | Delete
defined.
[193] Fix | Delete
"""
[194] Fix | Delete
[195] Fix | Delete
optimized = 0 # is namespace access optimized?
[196] Fix | Delete
__initialized = None
[197] Fix | Delete
class_name = None # provide default for instance variable
[198] Fix | Delete
[199] Fix | Delete
def __init__(self):
[200] Fix | Delete
if self.__initialized is None:
[201] Fix | Delete
self.initClass()
[202] Fix | Delete
self.__class__.__initialized = 1
[203] Fix | Delete
self.checkClass()
[204] Fix | Delete
self.locals = misc.Stack()
[205] Fix | Delete
self.setups = misc.Stack()
[206] Fix | Delete
self.last_lineno = None
[207] Fix | Delete
self._setupGraphDelegation()
[208] Fix | Delete
self._div_op = "BINARY_DIVIDE"
[209] Fix | Delete
[210] Fix | Delete
# XXX set flags based on future features
[211] Fix | Delete
futures = self.get_module().futures
[212] Fix | Delete
for feature in futures:
[213] Fix | Delete
if feature == "division":
[214] Fix | Delete
self.graph.setFlag(CO_FUTURE_DIVISION)
[215] Fix | Delete
self._div_op = "BINARY_TRUE_DIVIDE"
[216] Fix | Delete
elif feature == "absolute_import":
[217] Fix | Delete
self.graph.setFlag(CO_FUTURE_ABSIMPORT)
[218] Fix | Delete
elif feature == "with_statement":
[219] Fix | Delete
self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
[220] Fix | Delete
elif feature == "print_function":
[221] Fix | Delete
self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION)
[222] Fix | Delete
[223] Fix | Delete
def initClass(self):
[224] Fix | Delete
"""This method is called once for each class"""
[225] Fix | Delete
[226] Fix | Delete
def checkClass(self):
[227] Fix | Delete
"""Verify that class is constructed correctly"""
[228] Fix | Delete
try:
[229] Fix | Delete
assert hasattr(self, 'graph')
[230] Fix | Delete
assert getattr(self, 'NameFinder')
[231] Fix | Delete
assert getattr(self, 'FunctionGen')
[232] Fix | Delete
assert getattr(self, 'ClassGen')
[233] Fix | Delete
except AssertionError, msg:
[234] Fix | Delete
intro = "Bad class construction for %s" % self.__class__.__name__
[235] Fix | Delete
raise AssertionError, intro
[236] Fix | Delete
[237] Fix | Delete
def _setupGraphDelegation(self):
[238] Fix | Delete
self.emit = self.graph.emit
[239] Fix | Delete
self.newBlock = self.graph.newBlock
[240] Fix | Delete
self.startBlock = self.graph.startBlock
[241] Fix | Delete
self.nextBlock = self.graph.nextBlock
[242] Fix | Delete
self.setDocstring = self.graph.setDocstring
[243] Fix | Delete
[244] Fix | Delete
def getCode(self):
[245] Fix | Delete
"""Return a code object"""
[246] Fix | Delete
return self.graph.getCode()
[247] Fix | Delete
[248] Fix | Delete
def mangle(self, name):
[249] Fix | Delete
if self.class_name is not None:
[250] Fix | Delete
return misc.mangle(name, self.class_name)
[251] Fix | Delete
else:
[252] Fix | Delete
return name
[253] Fix | Delete
[254] Fix | Delete
def parseSymbols(self, tree):
[255] Fix | Delete
s = symbols.SymbolVisitor()
[256] Fix | Delete
walk(tree, s)
[257] Fix | Delete
return s.scopes
[258] Fix | Delete
[259] Fix | Delete
def get_module(self):
[260] Fix | Delete
raise RuntimeError, "should be implemented by subclasses"
[261] Fix | Delete
[262] Fix | Delete
# Next five methods handle name access
[263] Fix | Delete
[264] Fix | Delete
def isLocalName(self, name):
[265] Fix | Delete
return self.locals.top().has_elt(name)
[266] Fix | Delete
[267] Fix | Delete
def storeName(self, name):
[268] Fix | Delete
self._nameOp('STORE', name)
[269] Fix | Delete
[270] Fix | Delete
def loadName(self, name):
[271] Fix | Delete
self._nameOp('LOAD', name)
[272] Fix | Delete
[273] Fix | Delete
def delName(self, name):
[274] Fix | Delete
self._nameOp('DELETE', name)
[275] Fix | Delete
[276] Fix | Delete
def _nameOp(self, prefix, name):
[277] Fix | Delete
name = self.mangle(name)
[278] Fix | Delete
scope = self.scope.check_name(name)
[279] Fix | Delete
if scope == SC_LOCAL:
[280] Fix | Delete
if not self.optimized:
[281] Fix | Delete
self.emit(prefix + '_NAME', name)
[282] Fix | Delete
else:
[283] Fix | Delete
self.emit(prefix + '_FAST', name)
[284] Fix | Delete
elif scope == SC_GLOBAL_EXPLICIT:
[285] Fix | Delete
self.emit(prefix + '_GLOBAL', name)
[286] Fix | Delete
elif scope == SC_GLOBAL_IMPLICIT:
[287] Fix | Delete
if not self.optimized:
[288] Fix | Delete
self.emit(prefix + '_NAME', name)
[289] Fix | Delete
else:
[290] Fix | Delete
self.emit(prefix + '_GLOBAL', name)
[291] Fix | Delete
elif scope == SC_FREE or scope == SC_CELL:
[292] Fix | Delete
self.emit(prefix + '_DEREF', name)
[293] Fix | Delete
else:
[294] Fix | Delete
raise RuntimeError, "unsupported scope for var %s: %d" % \
[295] Fix | Delete
(name, scope)
[296] Fix | Delete
[297] Fix | Delete
def _implicitNameOp(self, prefix, name):
[298] Fix | Delete
"""Emit name ops for names generated implicitly by for loops
[299] Fix | Delete
[300] Fix | Delete
The interpreter generates names that start with a period or
[301] Fix | Delete
dollar sign. The symbol table ignores these names because
[302] Fix | Delete
they aren't present in the program text.
[303] Fix | Delete
"""
[304] Fix | Delete
if self.optimized:
[305] Fix | Delete
self.emit(prefix + '_FAST', name)
[306] Fix | Delete
else:
[307] Fix | Delete
self.emit(prefix + '_NAME', name)
[308] Fix | Delete
[309] Fix | Delete
# The set_lineno() function and the explicit emit() calls for
[310] Fix | Delete
# SET_LINENO below are only used to generate the line number table.
[311] Fix | Delete
# As of Python 2.3, the interpreter does not have a SET_LINENO
[312] Fix | Delete
# instruction. pyassem treats SET_LINENO opcodes as a special case.
[313] Fix | Delete
[314] Fix | Delete
def set_lineno(self, node, force=False):
[315] Fix | Delete
"""Emit SET_LINENO if necessary.
[316] Fix | Delete
[317] Fix | Delete
The instruction is considered necessary if the node has a
[318] Fix | Delete
lineno attribute and it is different than the last lineno
[319] Fix | Delete
emitted.
[320] Fix | Delete
[321] Fix | Delete
Returns true if SET_LINENO was emitted.
[322] Fix | Delete
[323] Fix | Delete
There are no rules for when an AST node should have a lineno
[324] Fix | Delete
attribute. The transformer and AST code need to be reviewed
[325] Fix | Delete
and a consistent policy implemented and documented. Until
[326] Fix | Delete
then, this method works around missing line numbers.
[327] Fix | Delete
"""
[328] Fix | Delete
lineno = getattr(node, 'lineno', None)
[329] Fix | Delete
if lineno is not None and (lineno != self.last_lineno
[330] Fix | Delete
or force):
[331] Fix | Delete
self.emit('SET_LINENO', lineno)
[332] Fix | Delete
self.last_lineno = lineno
[333] Fix | Delete
return True
[334] Fix | Delete
return False
[335] Fix | Delete
[336] Fix | Delete
# The first few visitor methods handle nodes that generator new
[337] Fix | Delete
# code objects. They use class attributes to determine what
[338] Fix | Delete
# specialized code generators to use.
[339] Fix | Delete
[340] Fix | Delete
NameFinder = LocalNameFinder
[341] Fix | Delete
FunctionGen = None
[342] Fix | Delete
ClassGen = None
[343] Fix | Delete
[344] Fix | Delete
def visitModule(self, node):
[345] Fix | Delete
self.scopes = self.parseSymbols(node)
[346] Fix | Delete
self.scope = self.scopes[node]
[347] Fix | Delete
self.emit('SET_LINENO', 0)
[348] Fix | Delete
if node.doc:
[349] Fix | Delete
self.emit('LOAD_CONST', node.doc)
[350] Fix | Delete
self.storeName('__doc__')
[351] Fix | Delete
lnf = walk(node.node, self.NameFinder(), verbose=0)
[352] Fix | Delete
self.locals.push(lnf.getLocals())
[353] Fix | Delete
self.visit(node.node)
[354] Fix | Delete
self.emit('LOAD_CONST', None)
[355] Fix | Delete
self.emit('RETURN_VALUE')
[356] Fix | Delete
[357] Fix | Delete
def visitExpression(self, node):
[358] Fix | Delete
self.set_lineno(node)
[359] Fix | Delete
self.scopes = self.parseSymbols(node)
[360] Fix | Delete
self.scope = self.scopes[node]
[361] Fix | Delete
self.visit(node.node)
[362] Fix | Delete
self.emit('RETURN_VALUE')
[363] Fix | Delete
[364] Fix | Delete
def visitFunction(self, node):
[365] Fix | Delete
self._visitFuncOrLambda(node, isLambda=0)
[366] Fix | Delete
if node.doc:
[367] Fix | Delete
self.setDocstring(node.doc)
[368] Fix | Delete
self.storeName(node.name)
[369] Fix | Delete
[370] Fix | Delete
def visitLambda(self, node):
[371] Fix | Delete
self._visitFuncOrLambda(node, isLambda=1)
[372] Fix | Delete
[373] Fix | Delete
def _visitFuncOrLambda(self, node, isLambda=0):
[374] Fix | Delete
if not isLambda and node.decorators:
[375] Fix | Delete
for decorator in node.decorators.nodes:
[376] Fix | Delete
self.visit(decorator)
[377] Fix | Delete
ndecorators = len(node.decorators.nodes)
[378] Fix | Delete
else:
[379] Fix | Delete
ndecorators = 0
[380] Fix | Delete
[381] Fix | Delete
gen = self.FunctionGen(node, self.scopes, isLambda,
[382] Fix | Delete
self.class_name, self.get_module())
[383] Fix | Delete
walk(node.code, gen)
[384] Fix | Delete
gen.finish()
[385] Fix | Delete
self.set_lineno(node)
[386] Fix | Delete
for default in node.defaults:
[387] Fix | Delete
self.visit(default)
[388] Fix | Delete
self._makeClosure(gen, len(node.defaults))
[389] Fix | Delete
for i in range(ndecorators):
[390] Fix | Delete
self.emit('CALL_FUNCTION', 1)
[391] Fix | Delete
[392] Fix | Delete
def visitClass(self, node):
[393] Fix | Delete
gen = self.ClassGen(node, self.scopes,
[394] Fix | Delete
self.get_module())
[395] Fix | Delete
walk(node.code, gen)
[396] Fix | Delete
gen.finish()
[397] Fix | Delete
self.set_lineno(node)
[398] Fix | Delete
self.emit('LOAD_CONST', node.name)
[399] Fix | Delete
for base in node.bases:
[400] Fix | Delete
self.visit(base)
[401] Fix | Delete
self.emit('BUILD_TUPLE', len(node.bases))
[402] Fix | Delete
self._makeClosure(gen, 0)
[403] Fix | Delete
self.emit('CALL_FUNCTION', 0)
[404] Fix | Delete
self.emit('BUILD_CLASS')
[405] Fix | Delete
self.storeName(node.name)
[406] Fix | Delete
[407] Fix | Delete
# The rest are standard visitor methods
[408] Fix | Delete
[409] Fix | Delete
# The next few implement control-flow statements
[410] Fix | Delete
[411] Fix | Delete
def visitIf(self, node):
[412] Fix | Delete
end = self.newBlock()
[413] Fix | Delete
numtests = len(node.tests)
[414] Fix | Delete
for i in range(numtests):
[415] Fix | Delete
test, suite = node.tests[i]
[416] Fix | Delete
if is_constant_false(test):
[417] Fix | Delete
# XXX will need to check generator stuff here
[418] Fix | Delete
continue
[419] Fix | Delete
self.set_lineno(test)
[420] Fix | Delete
self.visit(test)
[421] Fix | Delete
nextTest = self.newBlock()
[422] Fix | Delete
self.emit('POP_JUMP_IF_FALSE', nextTest)
[423] Fix | Delete
self.nextBlock()
[424] Fix | Delete
self.visit(suite)
[425] Fix | Delete
self.emit('JUMP_FORWARD', end)
[426] Fix | Delete
self.startBlock(nextTest)
[427] Fix | Delete
if node.else_:
[428] Fix | Delete
self.visit(node.else_)
[429] Fix | Delete
self.nextBlock(end)
[430] Fix | Delete
[431] Fix | Delete
def visitWhile(self, node):
[432] Fix | Delete
self.set_lineno(node)
[433] Fix | Delete
[434] Fix | Delete
loop = self.newBlock()
[435] Fix | Delete
else_ = self.newBlock()
[436] Fix | Delete
[437] Fix | Delete
after = self.newBlock()
[438] Fix | Delete
self.emit('SETUP_LOOP', after)
[439] Fix | Delete
[440] Fix | Delete
self.nextBlock(loop)
[441] Fix | Delete
self.setups.push((LOOP, loop))
[442] Fix | Delete
[443] Fix | Delete
self.set_lineno(node, force=True)
[444] Fix | Delete
self.visit(node.test)
[445] Fix | Delete
self.emit('POP_JUMP_IF_FALSE', else_ or after)
[446] Fix | Delete
[447] Fix | Delete
self.nextBlock()
[448] Fix | Delete
self.visit(node.body)
[449] Fix | Delete
self.emit('JUMP_ABSOLUTE', loop)
[450] Fix | Delete
[451] Fix | Delete
self.startBlock(else_) # or just the POPs if not else clause
[452] Fix | Delete
self.emit('POP_BLOCK')
[453] Fix | Delete
self.setups.pop()
[454] Fix | Delete
if node.else_:
[455] Fix | Delete
self.visit(node.else_)
[456] Fix | Delete
self.nextBlock(after)
[457] Fix | Delete
[458] Fix | Delete
def visitFor(self, node):
[459] Fix | Delete
start = self.newBlock()
[460] Fix | Delete
anchor = self.newBlock()
[461] Fix | Delete
after = self.newBlock()
[462] Fix | Delete
self.setups.push((LOOP, start))
[463] Fix | Delete
[464] Fix | Delete
self.set_lineno(node)
[465] Fix | Delete
self.emit('SETUP_LOOP', after)
[466] Fix | Delete
self.visit(node.list)
[467] Fix | Delete
self.emit('GET_ITER')
[468] Fix | Delete
[469] Fix | Delete
self.nextBlock(start)
[470] Fix | Delete
self.set_lineno(node, force=1)
[471] Fix | Delete
self.emit('FOR_ITER', anchor)
[472] Fix | Delete
self.visit(node.assign)
[473] Fix | Delete
self.visit(node.body)
[474] Fix | Delete
self.emit('JUMP_ABSOLUTE', start)
[475] Fix | Delete
self.nextBlock(anchor)
[476] Fix | Delete
self.emit('POP_BLOCK')
[477] Fix | Delete
self.setups.pop()
[478] Fix | Delete
if node.else_:
[479] Fix | Delete
self.visit(node.else_)
[480] Fix | Delete
self.nextBlock(after)
[481] Fix | Delete
[482] Fix | Delete
def visitBreak(self, node):
[483] Fix | Delete
if not self.setups:
[484] Fix | Delete
raise SyntaxError, "'break' outside loop (%s, %d)" % \
[485] Fix | Delete
(node.filename, node.lineno)
[486] Fix | Delete
self.set_lineno(node)
[487] Fix | Delete
self.emit('BREAK_LOOP')
[488] Fix | Delete
[489] Fix | Delete
def visitContinue(self, node):
[490] Fix | Delete
if not self.setups:
[491] Fix | Delete
raise SyntaxError, "'continue' outside loop (%s, %d)" % \
[492] Fix | Delete
(node.filename, node.lineno)
[493] Fix | Delete
kind, block = self.setups.top()
[494] Fix | Delete
if kind == LOOP:
[495] Fix | Delete
self.set_lineno(node)
[496] Fix | Delete
self.emit('JUMP_ABSOLUTE', block)
[497] Fix | Delete
self.nextBlock()
[498] Fix | Delete
elif kind == EXCEPT or kind == TRY_FINALLY:
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function