blob: 6d5a41c411501080fbaae8774b515fd7f8408fb2 [file] [log] [blame]
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001import imp
Jeremy Hylton53187f32000-02-08 19:01:29 +00002import os
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00003import marshal
Jeremy Hylton53187f32000-02-08 19:01:29 +00004import struct
Jeremy Hylton9c048f92000-10-13 21:58:13 +00005import sys
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00006from cStringIO import StringIO
7
Jeremy Hylton37c93512001-09-17 18:03:55 +00008from compiler import ast, parse, walk, syntax
Jeremy Hylton364f9b92001-04-12 06:40:42 +00009from compiler import pyassem, misc, future, symbols
Neil Schemenauer92c3b212009-02-07 00:54:41 +000010from compiler.consts import SC_LOCAL, SC_GLOBAL_IMPLICIT, SC_GLOBAL_EXPLICT, \
11 SC_FREE, SC_CELL
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000012from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
Neal Norwitzeaed39f2006-03-03 19:12:58 +000013 CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
Eric Smith5d5c63f2008-03-19 02:11:30 +000014 CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton71ebc332001-08-30 20:25:55 +000015from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000016
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000017# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000018# Do we have Python 1.x or Python 2.x?
19try:
20 VERSION = sys.version_info[0]
21except AttributeError:
22 VERSION = 1
23
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000024callfunc_opcode_info = {
25 # (Have *args, Have **args) : opcode
26 (0,0) : "CALL_FUNCTION",
27 (1,0) : "CALL_FUNCTION_VAR",
28 (0,1) : "CALL_FUNCTION_KW",
29 (1,1) : "CALL_FUNCTION_VAR_KW",
30}
31
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000032LOOP = 1
33EXCEPT = 2
34TRY_FINALLY = 3
35END_FINALLY = 4
36
Jeremy Hylton9dca3642001-09-17 21:02:51 +000037def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000038 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000039 buf = f.read()
40 f.close()
41 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000042 try:
43 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000044 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000045 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000046 else:
47 f = open(filename + "c", "wb")
48 mod.dump(f)
49 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000050
Jeremy Hylton9dca3642001-09-17 21:02:51 +000051def compile(source, filename, mode, flags=None, dont_inherit=None):
52 """Replacement for builtin compile() function"""
53 if flags is not None or dont_inherit is not None:
54 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000055
Jeremy Hylton9dca3642001-09-17 21:02:51 +000056 if mode == "single":
57 gen = Interactive(source, filename)
58 elif mode == "exec":
59 gen = Module(source, filename)
60 elif mode == "eval":
61 gen = Expression(source, filename)
62 else:
63 raise ValueError("compile() 3rd arg must be 'exec' or "
64 "'eval' or 'single'")
65 gen.compile()
66 return gen.code
67
68class AbstractCompileMode:
69
70 mode = None # defined by subclass
71
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000072 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000073 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000074 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000075 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000076
Jeremy Hylton9dca3642001-09-17 21:02:51 +000077 def _get_tree(self):
78 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000079 misc.set_filename(self.filename, tree)
80 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000081 return tree
82
83 def compile(self):
84 pass # implemented by subclass
85
86 def getCode(self):
87 return self.code
88
89class Expression(AbstractCompileMode):
90
91 mode = "eval"
92
93 def compile(self):
94 tree = self._get_tree()
95 gen = ExpressionCodeGenerator(tree)
96 self.code = gen.getCode()
97
98class Interactive(AbstractCompileMode):
99
100 mode = "single"
101
102 def compile(self):
103 tree = self._get_tree()
104 gen = InteractiveCodeGenerator(tree)
105 self.code = gen.getCode()
106
107class Module(AbstractCompileMode):
108
109 mode = "exec"
110
111 def compile(self, display=0):
112 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000113 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000114 if display:
115 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000116 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000117 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000118
119 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000120 f.write(self.getPycHeader())
121 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000122
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000123 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000124
125 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000126 # compile.c uses marshal to write a long directly, with
127 # calling the interface that would also generate a 1-byte code
128 # to indicate the type of the value. simplest way to get the
129 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000130 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000131 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000132 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000133
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000134class LocalNameFinder:
135 """Find local names in scope"""
136 def __init__(self, names=()):
137 self.names = misc.Set()
138 self.globals = misc.Set()
139 for name in names:
140 self.names.add(name)
141
142 # XXX list comprehensions and for loops
143
144 def getLocals(self):
145 for elt in self.globals.elements():
146 if self.names.has_elt(elt):
147 self.names.remove(elt)
148 return self.names
149
150 def visitDict(self, node):
151 pass
152
153 def visitGlobal(self, node):
154 for name in node.names:
155 self.globals.add(name)
156
157 def visitFunction(self, node):
158 self.names.add(node.name)
159
160 def visitLambda(self, node):
161 pass
162
163 def visitImport(self, node):
164 for name, alias in node.names:
165 self.names.add(alias or name)
166
167 def visitFrom(self, node):
168 for name, alias in node.names:
169 self.names.add(alias or name)
170
171 def visitClass(self, node):
172 self.names.add(node.name)
173
174 def visitAssName(self, node):
175 self.names.add(node.name)
176
Jeremy Hylton2afff322001-08-27 21:51:52 +0000177def is_constant_false(node):
178 if isinstance(node, ast.Const):
179 if not node.value:
180 return 1
181 return 0
182
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000183class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000184 """Defines basic code generator for Python bytecode
185
186 This class is an abstract base class. Concrete subclasses must
187 define an __init__() that defines self.graph and then calls the
188 __init__() defined in this class.
189
190 The concrete class must also define the class attributes
191 NameFinder, FunctionGen, and ClassGen. These attributes can be
192 defined in the initClass() method, which is a hook for
193 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000194 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000195 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000196
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000197 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000198 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000199 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000200
Jeremy Hylton37c93512001-09-17 18:03:55 +0000201 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000202 if self.__initialized is None:
203 self.initClass()
204 self.__class__.__initialized = 1
205 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000206 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000207 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000208 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000209 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000210 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000211
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000212 # XXX set flags based on future features
213 futures = self.get_module().futures
214 for feature in futures:
215 if feature == "division":
216 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000217 self._div_op = "BINARY_TRUE_DIVIDE"
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000218 elif feature == "absolute_import":
219 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
220 elif feature == "with_statement":
221 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Eric Smith5d5c63f2008-03-19 02:11:30 +0000222 elif feature == "print_function":
223 self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000224
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000225 def initClass(self):
226 """This method is called once for each class"""
227
228 def checkClass(self):
229 """Verify that class is constructed correctly"""
230 try:
231 assert hasattr(self, 'graph')
232 assert getattr(self, 'NameFinder')
233 assert getattr(self, 'FunctionGen')
234 assert getattr(self, 'ClassGen')
235 except AssertionError, msg:
236 intro = "Bad class construction for %s" % self.__class__.__name__
237 raise AssertionError, intro
238
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000239 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000240 self.emit = self.graph.emit
241 self.newBlock = self.graph.newBlock
242 self.startBlock = self.graph.startBlock
243 self.nextBlock = self.graph.nextBlock
244 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000245
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000246 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000247 """Return a code object"""
248 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000249
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000250 def mangle(self, name):
251 if self.class_name is not None:
252 return misc.mangle(name, self.class_name)
253 else:
254 return name
255
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000256 def parseSymbols(self, tree):
257 s = symbols.SymbolVisitor()
258 walk(tree, s)
259 return s.scopes
260
261 def get_module(self):
262 raise RuntimeError, "should be implemented by subclasses"
263
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000264 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000265
Jeremy Hylton40245602000-02-08 21:15:48 +0000266 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000267 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000268
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000269 def storeName(self, name):
270 self._nameOp('STORE', name)
271
272 def loadName(self, name):
273 self._nameOp('LOAD', name)
274
275 def delName(self, name):
276 self._nameOp('DELETE', name)
277
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000278 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000279 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000280 scope = self.scope.check_name(name)
281 if scope == SC_LOCAL:
282 if not self.optimized:
283 self.emit(prefix + '_NAME', name)
284 else:
285 self.emit(prefix + '_FAST', name)
Neil Schemenauer92c3b212009-02-07 00:54:41 +0000286 elif scope == SC_GLOBAL_EXPLICT:
287 self.emit(prefix + '_GLOBAL', name)
288 elif scope == SC_GLOBAL_IMPLICIT:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000289 if not self.optimized:
290 self.emit(prefix + '_NAME', name)
291 else:
292 self.emit(prefix + '_GLOBAL', name)
293 elif scope == SC_FREE or scope == SC_CELL:
294 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000295 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000296 raise RuntimeError, "unsupported scope for var %s: %d" % \
297 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000298
Jeremy Hylton13d70942001-04-12 21:04:43 +0000299 def _implicitNameOp(self, prefix, name):
300 """Emit name ops for names generated implicitly by for loops
301
302 The interpreter generates names that start with a period or
303 dollar sign. The symbol table ignores these names because
304 they aren't present in the program text.
305 """
306 if self.optimized:
307 self.emit(prefix + '_FAST', name)
308 else:
309 self.emit(prefix + '_NAME', name)
310
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000311 # The set_lineno() function and the explicit emit() calls for
312 # SET_LINENO below are only used to generate the line number table.
313 # As of Python 2.3, the interpreter does not have a SET_LINENO
314 # instruction. pyassem treats SET_LINENO opcodes as a special case.
315
316 def set_lineno(self, node, force=False):
317 """Emit SET_LINENO if necessary.
318
319 The instruction is considered necessary if the node has a
320 lineno attribute and it is different than the last lineno
321 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000322
323 Returns true if SET_LINENO was emitted.
324
325 There are no rules for when an AST node should have a lineno
326 attribute. The transformer and AST code need to be reviewed
327 and a consistent policy implemented and documented. Until
328 then, this method works around missing line numbers.
329 """
330 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000331 if lineno is not None and (lineno != self.last_lineno
332 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000333 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000334 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000335 return True
336 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000337
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000338 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000339 # code objects. They use class attributes to determine what
340 # specialized code generators to use.
341
342 NameFinder = LocalNameFinder
343 FunctionGen = None
344 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000345
346 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000347 self.scopes = self.parseSymbols(node)
348 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000349 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000350 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000351 self.emit('LOAD_CONST', node.doc)
352 self.storeName('__doc__')
353 lnf = walk(node.node, self.NameFinder(), verbose=0)
354 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000355 self.visit(node.node)
356 self.emit('LOAD_CONST', None)
357 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000358
Barry Warsaw52acb492001-12-21 20:04:22 +0000359 def visitExpression(self, node):
360 self.set_lineno(node)
361 self.scopes = self.parseSymbols(node)
362 self.scope = self.scopes[node]
363 self.visit(node.node)
364 self.emit('RETURN_VALUE')
365
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000366 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000367 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000368 if node.doc:
369 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000370 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000371
372 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000373 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000374
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000375 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000376 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000377 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000378 self.visit(decorator)
379 ndecorators = len(node.decorators.nodes)
380 else:
381 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000382
Jeremy Hylton37c93512001-09-17 18:03:55 +0000383 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000384 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000385 walk(node.code, gen)
386 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000387 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000388 for default in node.defaults:
389 self.visit(default)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000390 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000391 for i in range(ndecorators):
392 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000393
394 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000395 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000396 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000397 walk(node.code, gen)
398 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000399 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000400 self.emit('LOAD_CONST', node.name)
401 for base in node.bases:
402 self.visit(base)
403 self.emit('BUILD_TUPLE', len(node.bases))
Neil Schemenauer06ded092006-08-04 16:20:30 +0000404 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000405 self.emit('CALL_FUNCTION', 0)
406 self.emit('BUILD_CLASS')
407 self.storeName(node.name)
408
409 # The rest are standard visitor methods
410
411 # The next few implement control-flow statements
412
413 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000414 end = self.newBlock()
415 numtests = len(node.tests)
416 for i in range(numtests):
417 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000418 if is_constant_false(test):
419 # XXX will need to check generator stuff here
420 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000421 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000422 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000423 nextTest = self.newBlock()
424 self.emit('JUMP_IF_FALSE', nextTest)
425 self.nextBlock()
426 self.emit('POP_TOP')
427 self.visit(suite)
428 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000429 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000430 self.emit('POP_TOP')
431 if node.else_:
432 self.visit(node.else_)
433 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000434
435 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000436 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000437
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000438 loop = self.newBlock()
439 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000440
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000441 after = self.newBlock()
442 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000444 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000445 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000446
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000447 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000448 self.visit(node.test)
449 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000450
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000451 self.nextBlock()
452 self.emit('POP_TOP')
453 self.visit(node.body)
454 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000455
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000456 self.startBlock(else_) # or just the POPs if not else clause
457 self.emit('POP_TOP')
458 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000459 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 if node.else_:
461 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000462 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000463
464 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000465 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000466 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000467 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000468 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000469
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000470 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000471 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000472 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000473 self.emit('GET_ITER')
474
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000475 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000476 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000477 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478 self.visit(node.assign)
479 self.visit(node.body)
480 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000481 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000482 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000483 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000484 if node.else_:
485 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000486 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000487
488 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000489 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000490 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000491 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000492 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000493 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000494
495 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000496 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000497 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000498 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000499 kind, block = self.setups.top()
500 if kind == LOOP:
501 self.set_lineno(node)
502 self.emit('JUMP_ABSOLUTE', block)
503 self.nextBlock()
504 elif kind == EXCEPT or kind == TRY_FINALLY:
505 self.set_lineno(node)
506 # find the block that starts the loop
507 top = len(self.setups)
508 while top > 0:
509 top = top - 1
510 kind, loop_block = self.setups[top]
511 if kind == LOOP:
512 break
513 if kind != LOOP:
514 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000515 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000516 self.emit('CONTINUE_LOOP', loop_block)
517 self.nextBlock()
518 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000519 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000520 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000521
522 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000523 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000524 for child in node.nodes[:-1]:
525 self.visit(child)
526 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000527 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000528 self.emit('POP_TOP')
529 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000530 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000531
532 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000533 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000534
535 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000536 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000537
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000538 def visitIfExp(self, node):
539 endblock = self.newBlock()
540 elseblock = self.newBlock()
541 self.visit(node.test)
542 self.emit('JUMP_IF_FALSE', elseblock)
543 self.emit('POP_TOP')
544 self.visit(node.then)
545 self.emit('JUMP_FORWARD', endblock)
546 self.nextBlock(elseblock)
547 self.emit('POP_TOP')
548 self.visit(node.else_)
549 self.nextBlock(endblock)
550
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000551 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000552 self.visit(node.expr)
553 cleanup = self.newBlock()
554 for op, code in node.ops[:-1]:
555 self.visit(code)
556 self.emit('DUP_TOP')
557 self.emit('ROT_THREE')
558 self.emit('COMPARE_OP', op)
559 self.emit('JUMP_IF_FALSE', cleanup)
560 self.nextBlock()
561 self.emit('POP_TOP')
562 # now do the last comparison
563 if node.ops:
564 op, code = node.ops[-1]
565 self.visit(code)
566 self.emit('COMPARE_OP', op)
567 if len(node.ops) > 1:
568 end = self.newBlock()
569 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000570 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000571 self.emit('ROT_TWO')
572 self.emit('POP_TOP')
573 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000574
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000575 # list comprehensions
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000576 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000577 self.set_lineno(node)
578 # setup list
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000579 self.emit('BUILD_LIST', 0)
Tim Peterse0c446b2001-10-18 21:57:37 +0000580
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000581 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000582 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000583 start, anchor = self.visit(for_)
584 cont = None
585 for if_ in for_.ifs:
586 if cont is None:
587 cont = self.newBlock()
588 self.visit(if_, cont)
589 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000590
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000591 self.visit(node.expr)
Antoine Pitroud0c35152008-12-17 00:38:28 +0000592 self.emit('LIST_APPEND', len(node.quals) + 1)
Tim Peterse0c446b2001-10-18 21:57:37 +0000593
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000594 for start, cont, anchor in stack:
595 if cont:
596 skip_one = self.newBlock()
597 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000598 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000599 self.emit('POP_TOP')
600 self.nextBlock(skip_one)
601 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000602 self.startBlock(anchor)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000603
604 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000605 start = self.newBlock()
606 anchor = self.newBlock()
607
608 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000609 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000611 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000612 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000613 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000614 self.visit(node.assign)
615 return start, anchor
616
617 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000618 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000619 self.visit(node.test)
620 self.emit('JUMP_IF_FALSE', branch)
621 self.newBlock()
622 self.emit('POP_TOP')
623
Neil Schemenauer06ded092006-08-04 16:20:30 +0000624 def _makeClosure(self, gen, args):
625 frees = gen.scope.get_free_vars()
626 if frees:
627 for name in frees:
628 self.emit('LOAD_CLOSURE', name)
629 self.emit('BUILD_TUPLE', len(frees))
630 self.emit('LOAD_CONST', gen)
631 self.emit('MAKE_CLOSURE', args)
632 else:
633 self.emit('LOAD_CONST', gen)
634 self.emit('MAKE_FUNCTION', args)
635
Raymond Hettinger354433a2004-05-19 08:20:33 +0000636 def visitGenExpr(self, node):
637 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
638 self.get_module())
639 walk(node.code, gen)
640 gen.finish()
641 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000642 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000643 # precomputation of outmost iterable
644 self.visit(node.code.quals[0].iter)
645 self.emit('GET_ITER')
646 self.emit('CALL_FUNCTION', 1)
647
648 def visitGenExprInner(self, node):
649 self.set_lineno(node)
650 # setup list
651
652 stack = []
653 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000654 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000655 cont = None
656 for if_ in for_.ifs:
657 if cont is None:
658 cont = self.newBlock()
659 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000660 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000661
662 self.visit(node.expr)
663 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000664 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000665
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000666 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000667 if cont:
668 skip_one = self.newBlock()
669 self.emit('JUMP_FORWARD', skip_one)
670 self.startBlock(cont)
671 self.emit('POP_TOP')
672 self.nextBlock(skip_one)
673 self.emit('JUMP_ABSOLUTE', start)
674 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000675 self.emit('POP_BLOCK')
676 self.setups.pop()
Neil Schemenauer4db626f2009-02-06 21:08:52 +0000677 self.nextBlock(end)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000678
Raymond Hettinger354433a2004-05-19 08:20:33 +0000679 self.emit('LOAD_CONST', None)
680
681 def visitGenExprFor(self, node):
682 start = self.newBlock()
683 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000684 end = self.newBlock()
685
686 self.setups.push((LOOP, start))
687 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000688
Raymond Hettinger354433a2004-05-19 08:20:33 +0000689 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000690 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000691 else:
692 self.visit(node.iter)
693 self.emit('GET_ITER')
694
695 self.nextBlock(start)
696 self.set_lineno(node, force=True)
697 self.emit('FOR_ITER', anchor)
698 self.nextBlock()
699 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000700 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000701
702 def visitGenExprIf(self, node, branch):
703 self.set_lineno(node, force=True)
704 self.visit(node.test)
705 self.emit('JUMP_IF_FALSE', branch)
706 self.newBlock()
707 self.emit('POP_TOP')
708
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000709 # exception related
710
711 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000712 # XXX would be interesting to implement this via a
713 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000714 if __debug__:
715 end = self.newBlock()
716 self.set_lineno(node)
717 # XXX AssertionError appears to be special case -- it is always
718 # loaded as a global even if there is a local name. I guess this
719 # is a sort of renaming op.
720 self.nextBlock()
721 self.visit(node.test)
722 self.emit('JUMP_IF_TRUE', end)
723 self.nextBlock()
724 self.emit('POP_TOP')
725 self.emit('LOAD_GLOBAL', 'AssertionError')
726 if node.fail:
727 self.visit(node.fail)
728 self.emit('RAISE_VARARGS', 2)
729 else:
730 self.emit('RAISE_VARARGS', 1)
731 self.nextBlock(end)
732 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000733
734 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000735 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000736 n = 0
737 if node.expr1:
738 self.visit(node.expr1)
739 n = n + 1
740 if node.expr2:
741 self.visit(node.expr2)
742 n = n + 1
743 if node.expr3:
744 self.visit(node.expr3)
745 n = n + 1
746 self.emit('RAISE_VARARGS', n)
747
748 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000749 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000750 handlers = self.newBlock()
751 end = self.newBlock()
752 if node.else_:
753 lElse = self.newBlock()
754 else:
755 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000756 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000757 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000758 self.nextBlock(body)
759 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000760 self.visit(node.body)
761 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000762 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000763 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000764 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000765
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000766 last = len(node.handlers) - 1
767 for i in range(len(node.handlers)):
768 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000769 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000770 if expr:
771 self.emit('DUP_TOP')
772 self.visit(expr)
773 self.emit('COMPARE_OP', 'exception match')
774 next = self.newBlock()
775 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000776 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000777 self.emit('POP_TOP')
778 self.emit('POP_TOP')
779 if target:
780 self.visit(target)
781 else:
782 self.emit('POP_TOP')
783 self.emit('POP_TOP')
784 self.visit(body)
785 self.emit('JUMP_FORWARD', end)
786 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000787 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000788 else:
789 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000790 if expr: # XXX
791 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000792 self.emit('END_FINALLY')
793 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000794 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000795 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000796 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000797
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000798 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000799 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000801 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000802 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000803 self.nextBlock(body)
804 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 self.visit(node.body)
806 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000807 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000808 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000809 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000810 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 self.visit(node.final)
812 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000813 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000814
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000815 __with_count = 0
816
817 def visitWith(self, node):
818 body = self.newBlock()
819 final = self.newBlock()
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000820 self.__with_count += 1
Neil Schemenauer98c3b852009-02-07 00:13:39 +0000821 valuevar = "_[%d]" % self.__with_count
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000822 self.set_lineno(node)
823 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000824 self.emit('DUP_TOP')
825 self.emit('LOAD_ATTR', '__exit__')
Nick Coghlan7af53be2008-03-07 14:13:28 +0000826 self.emit('ROT_TWO')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000827 self.emit('LOAD_ATTR', '__enter__')
828 self.emit('CALL_FUNCTION', 0)
829 if node.vars is None:
830 self.emit('POP_TOP')
831 else:
832 self._implicitNameOp('STORE', valuevar)
833 self.emit('SETUP_FINALLY', final)
834 self.nextBlock(body)
835 self.setups.push((TRY_FINALLY, body))
836 if node.vars is not None:
837 self._implicitNameOp('LOAD', valuevar)
838 self._implicitNameOp('DELETE', valuevar)
839 self.visit(node.vars)
840 self.visit(node.body)
841 self.emit('POP_BLOCK')
842 self.setups.pop()
843 self.emit('LOAD_CONST', None)
844 self.nextBlock(final)
845 self.setups.push((END_FINALLY, final))
846 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000847 self.emit('END_FINALLY')
848 self.setups.pop()
849 self.__with_count -= 1
850
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000851 # misc
852
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000853 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000854 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000855 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000856 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000857
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000858 def visitConst(self, node):
859 self.emit('LOAD_CONST', node.value)
860
861 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000862 self.emit('LOAD_CONST', node.name)
863 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000864
865 def visitGlobal(self, node):
866 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000867 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000868
869 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000870 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000871 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000872
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000873 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000874 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000875
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000876 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000877 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000878 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000879 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000880 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000881 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000882 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000883 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000884 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000885 if alias:
886 self._resolveDots(name)
887 self.storeName(alias)
888 else:
889 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000890
891 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000892 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000893 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000894 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000895 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000896 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000897 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000898 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000899 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000900 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000901 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000902 if VERSION > 1:
903 if name == '*':
904 self.namespace = 0
905 self.emit('IMPORT_STAR')
906 # There can only be one name w/ from ... import *
907 assert len(node.names) == 1
908 return
909 else:
910 self.emit('IMPORT_FROM', name)
911 self._resolveDots(name)
912 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000913 else:
914 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000915 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000916
Jeremy Hylton20516082000-09-01 20:33:26 +0000917 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000918 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000919 if len(elts) == 1:
920 return
921 for elt in elts[1:]:
922 self.emit('LOAD_ATTR', elt)
923
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000924 def visitGetattr(self, node):
925 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000926 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000927
928 # next five implement assignments
929
930 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000931 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000932 self.visit(node.expr)
933 dups = len(node.nodes) - 1
934 for i in range(len(node.nodes)):
935 elt = node.nodes[i]
936 if i < dups:
937 self.emit('DUP_TOP')
938 if isinstance(elt, ast.Node):
939 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000940
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000941 def visitAssName(self, node):
942 if node.flags == 'OP_ASSIGN':
943 self.storeName(node.name)
944 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000945 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000946 self.delName(node.name)
947 else:
948 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000949
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000950 def visitAssAttr(self, node):
951 self.visit(node.expr)
952 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000953 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000954 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000955 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000956 else:
957 print "warning: unexpected flags:", node.flags
958 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000959
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000960 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000961 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000962 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000963 for child in node.nodes:
964 self.visit(child)
965
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000966 if VERSION > 1:
967 visitAssTuple = _visitAssSequence
968 visitAssList = _visitAssSequence
969 else:
970 def visitAssTuple(self, node):
971 self._visitAssSequence(node, 'UNPACK_TUPLE')
972
973 def visitAssList(self, node):
974 self._visitAssSequence(node, 'UNPACK_LIST')
975
976 # augmented assignment
977
978 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000979 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000980 aug_node = wrap_aug(node.node)
981 self.visit(aug_node, "load")
982 self.visit(node.expr)
983 self.emit(self._augmented_opcode[node.op])
984 self.visit(aug_node, "store")
985
986 _augmented_opcode = {
987 '+=' : 'INPLACE_ADD',
988 '-=' : 'INPLACE_SUBTRACT',
989 '*=' : 'INPLACE_MULTIPLY',
990 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000991 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000992 '%=' : 'INPLACE_MODULO',
993 '**=': 'INPLACE_POWER',
994 '>>=': 'INPLACE_RSHIFT',
995 '<<=': 'INPLACE_LSHIFT',
996 '&=' : 'INPLACE_AND',
997 '^=' : 'INPLACE_XOR',
998 '|=' : 'INPLACE_OR',
999 }
1000
1001 def visitAugName(self, node, mode):
1002 if mode == "load":
1003 self.loadName(node.name)
1004 elif mode == "store":
1005 self.storeName(node.name)
1006
1007 def visitAugGetattr(self, node, mode):
1008 if mode == "load":
1009 self.visit(node.expr)
1010 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001011 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001012 elif mode == "store":
1013 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001014 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001015
1016 def visitAugSlice(self, node, mode):
1017 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001018 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001019 elif mode == "store":
1020 slice = 0
1021 if node.lower:
1022 slice = slice | 1
1023 if node.upper:
1024 slice = slice | 2
1025 if slice == 0:
1026 self.emit('ROT_TWO')
1027 elif slice == 3:
1028 self.emit('ROT_FOUR')
1029 else:
1030 self.emit('ROT_THREE')
1031 self.emit('STORE_SLICE+%d' % slice)
1032
1033 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001034 if mode == "load":
1035 self.visitSubscript(node, 1)
1036 elif mode == "store":
1037 self.emit('ROT_THREE')
1038 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001039
1040 def visitExec(self, node):
1041 self.visit(node.expr)
1042 if node.locals is None:
1043 self.emit('LOAD_CONST', None)
1044 else:
1045 self.visit(node.locals)
1046 if node.globals is None:
1047 self.emit('DUP_TOP')
1048 else:
1049 self.visit(node.globals)
1050 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001051
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001052 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001053 pos = 0
1054 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001055 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001056 self.visit(node.node)
1057 for arg in node.args:
1058 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001059 if isinstance(arg, ast.Keyword):
1060 kw = kw + 1
1061 else:
1062 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001063 if node.star_args is not None:
1064 self.visit(node.star_args)
1065 if node.dstar_args is not None:
1066 self.visit(node.dstar_args)
1067 have_star = node.star_args is not None
1068 have_dstar = node.dstar_args is not None
1069 opcode = callfunc_opcode_info[have_star, have_dstar]
1070 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001071
Jeremy Hylton2afff322001-08-27 21:51:52 +00001072 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001073 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001074 if node.dest:
1075 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001076 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001077 if node.dest:
1078 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001079 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001080 if node.dest:
1081 self.emit('ROT_TWO')
1082 self.emit('PRINT_ITEM_TO')
1083 else:
1084 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001085 if node.dest and not newline:
1086 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001087
1088 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001089 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001090 if node.dest:
1091 self.emit('PRINT_NEWLINE_TO')
1092 else:
1093 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001094
1095 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001096 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001097 self.visit(node.value)
1098 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001099
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001100 def visitYield(self, node):
1101 self.set_lineno(node)
1102 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001103 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001104
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001105 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001106
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001107 def visitSlice(self, node, aug_flag=None):
1108 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001109 self.visit(node.expr)
1110 slice = 0
1111 if node.lower:
1112 self.visit(node.lower)
1113 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001114 if node.upper:
1115 self.visit(node.upper)
1116 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001117 if aug_flag:
1118 if slice == 0:
1119 self.emit('DUP_TOP')
1120 elif slice == 3:
1121 self.emit('DUP_TOPX', 3)
1122 else:
1123 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001124 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001125 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001126 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001127 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001128 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001129 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001130 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001131 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001133
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001134 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001135 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001136 for sub in node.subs:
1137 self.visit(sub)
1138 if len(node.subs) > 1:
1139 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001140 if aug_flag:
1141 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001142 if node.flags == 'OP_APPLY':
1143 self.emit('BINARY_SUBSCR')
1144 elif node.flags == 'OP_ASSIGN':
1145 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001146 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001147 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001148
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001149 # binary ops
1150
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001151 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001152 self.visit(node.left)
1153 self.visit(node.right)
1154 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001155
1156 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001157 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001158
1159 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001160 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001161
1162 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001163 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001164
1165 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001166 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001167
Jeremy Hylton94afe322001-08-29 18:14:39 +00001168 def visitFloorDiv(self, node):
1169 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1170
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001171 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001173
Jeremy Hylton126960b2000-02-14 21:33:10 +00001174 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001175 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001176
1177 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001179
1180 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001181 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001182
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001183 # unary ops
1184
1185 def unaryOp(self, node, op):
1186 self.visit(node.expr)
1187 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001188
Jeremy Hylton126960b2000-02-14 21:33:10 +00001189 def visitInvert(self, node):
1190 return self.unaryOp(node, 'UNARY_INVERT')
1191
Jeremy Hylton40245602000-02-08 21:15:48 +00001192 def visitUnarySub(self, node):
1193 return self.unaryOp(node, 'UNARY_NEGATIVE')
1194
1195 def visitUnaryAdd(self, node):
1196 return self.unaryOp(node, 'UNARY_POSITIVE')
1197
1198 def visitUnaryInvert(self, node):
1199 return self.unaryOp(node, 'UNARY_INVERT')
1200
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001201 def visitNot(self, node):
1202 return self.unaryOp(node, 'UNARY_NOT')
1203
Jeremy Hylton40245602000-02-08 21:15:48 +00001204 def visitBackquote(self, node):
1205 return self.unaryOp(node, 'UNARY_CONVERT')
1206
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001207 # bit ops
1208
Jeremy Hyltona5058122000-02-14 14:14:29 +00001209 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001210 self.visit(nodes[0])
1211 for node in nodes[1:]:
1212 self.visit(node)
1213 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001214
1215 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001216 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001217
1218 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001219 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001220
1221 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001222 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001223
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001224 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001225
Jeremy Hyltona5058122000-02-14 14:14:29 +00001226 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001227 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001228
Jeremy Hylton40245602000-02-08 21:15:48 +00001229 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001230 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001231 for elt in node.nodes:
1232 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001233 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001234
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001235 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001236 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001237 for elt in node.nodes:
1238 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001239 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001240
1241 def visitSliceobj(self, node):
1242 for child in node.nodes:
1243 self.visit(child)
1244 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001245
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001247 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001248 self.emit('BUILD_MAP', 0)
1249 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001250 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001251 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001252 self.visit(v)
1253 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001254 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001255
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001256class NestedScopeMixin:
1257 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001258 def initClass(self):
1259 self.__class__.NameFinder = LocalNameFinder
1260 self.__class__.FunctionGen = FunctionCodeGenerator
1261 self.__class__.ClassGen = ClassCodeGenerator
1262
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001263class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001264 __super_init = CodeGenerator.__init__
1265
1266 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001267
Jeremy Hylton37c93512001-09-17 18:03:55 +00001268 def __init__(self, tree):
1269 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001270 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001271 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001272 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001273
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001274 def get_module(self):
1275 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001276
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001277class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1278 __super_init = CodeGenerator.__init__
1279
1280 scopes = None
1281 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001282
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001283 def __init__(self, tree):
1284 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1285 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001286 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001287
1288 def get_module(self):
1289 return self
1290
1291class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1292
1293 __super_init = CodeGenerator.__init__
1294
1295 scopes = None
1296 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001297
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001298 def __init__(self, tree):
1299 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1300 self.__super_init()
1301 self.set_lineno(tree)
1302 walk(tree, self)
1303 self.emit('RETURN_VALUE')
1304
1305 def get_module(self):
1306 return self
Tim Peterse4418602002-02-16 07:34:19 +00001307
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001308 def visitDiscard(self, node):
1309 # XXX Discard means it's an expression. Perhaps this is a bad
1310 # name.
1311 self.visit(node.expr)
1312 self.emit('PRINT_EXPR')
1313
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001314class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001315 optimized = 1
1316 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001317
Jeremy Hylton37c93512001-09-17 18:03:55 +00001318 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001319 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001320 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001321 if isLambda:
1322 klass = FunctionCodeGenerator
1323 name = "<lambda.%d>" % klass.lambdaCount
1324 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001325 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001326 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001327
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001328 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001329 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1330 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001331 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001332 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001333
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001334 if not isLambda and func.doc:
1335 self.setDocstring(func.doc)
1336
Jeremy Hylton2afff322001-08-27 21:51:52 +00001337 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001338 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001339 if func.varargs:
1340 self.graph.setFlag(CO_VARARGS)
1341 if func.kwargs:
1342 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001343 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001344 if hasTupleArg:
1345 self.generateArgUnpack(func.argnames)
1346
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001347 def get_module(self):
1348 return self.module
1349
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001350 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001351 self.graph.startExitBlock()
1352 if not self.isLambda:
1353 self.emit('LOAD_CONST', None)
1354 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001355
1356 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001357 for i in range(len(args)):
1358 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001359 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001360 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001361 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001362
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001363 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001364 if VERSION > 1:
1365 self.emit('UNPACK_SEQUENCE', len(tup))
1366 else:
1367 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001368 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001369 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001370 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001371 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001372 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001373
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001374 unpackTuple = unpackSequence
1375
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001376class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001377 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001378 super_init = CodeGenerator.__init__ # call be other init
1379 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001380
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001381 __super_init = AbstractFunctionCode.__init__
1382
Jeremy Hylton37c93512001-09-17 18:03:55 +00001383 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001384 self.scopes = scopes
1385 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001386 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001387 self.graph.setFreeVars(self.scope.get_free_vars())
1388 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001389 if self.scope.generator is not None:
1390 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001391
Raymond Hettinger354433a2004-05-19 08:20:33 +00001392class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1393 CodeGenerator):
1394 super_init = CodeGenerator.__init__ # call be other init
1395 scopes = None
1396
1397 __super_init = AbstractFunctionCode.__init__
1398
1399 def __init__(self, gexp, scopes, class_name, mod):
1400 self.scopes = scopes
1401 self.scope = scopes[gexp]
1402 self.__super_init(gexp, scopes, 1, class_name, mod)
1403 self.graph.setFreeVars(self.scope.get_free_vars())
1404 self.graph.setCellVars(self.scope.get_cell_vars())
1405 self.graph.setFlag(CO_GENERATOR)
1406
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001407class AbstractClassCode:
1408
Jeremy Hylton37c93512001-09-17 18:03:55 +00001409 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001410 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001411 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001412 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001413 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001414 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001415 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001416 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001417 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001418 if klass.doc:
1419 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001420
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001421 def get_module(self):
1422 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001423
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001424 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001425 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001426 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001427 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001428
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001429class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001430 super_init = CodeGenerator.__init__
1431 scopes = None
1432
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001433 __super_init = AbstractClassCode.__init__
1434
Jeremy Hylton37c93512001-09-17 18:03:55 +00001435 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001436 self.scopes = scopes
1437 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001438 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001439 self.graph.setFreeVars(self.scope.get_free_vars())
1440 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001441 self.set_lineno(klass)
1442 self.emit("LOAD_GLOBAL", "__name__")
1443 self.storeName("__module__")
1444 if klass.doc:
1445 self.emit("LOAD_CONST", klass.doc)
1446 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001447
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001448def generateArgList(arglist):
1449 """Generate an arg list marking TupleArgs"""
1450 args = []
1451 extra = []
1452 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001453 for i in range(len(arglist)):
1454 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001455 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001456 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001457 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001458 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001459 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001460 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001461 else:
1462 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001463 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001464
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001465def findOp(node):
1466 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1467 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001468 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001469 return v.op
1470
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001471class OpFinder:
1472 def __init__(self):
1473 self.op = None
1474 def visitAssName(self, node):
1475 if self.op is None:
1476 self.op = node.flags
1477 elif self.op != node.flags:
1478 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001479 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001480 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001481
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001482class Delegator:
1483 """Base class to support delegation for augmented assignment nodes
1484
1485 To generator code for augmented assignments, we use the following
1486 wrapper classes. In visitAugAssign, the left-hand expression node
1487 is visited twice. The first time the visit uses the normal method
1488 for that node . The second time the visit uses a different method
1489 that generates the appropriate code to perform the assignment.
1490 These delegator classes wrap the original AST nodes in order to
1491 support the variant visit methods.
1492 """
1493 def __init__(self, obj):
1494 self.obj = obj
1495
1496 def __getattr__(self, attr):
1497 return getattr(self.obj, attr)
1498
1499class AugGetattr(Delegator):
1500 pass
1501
1502class AugName(Delegator):
1503 pass
1504
1505class AugSlice(Delegator):
1506 pass
1507
1508class AugSubscript(Delegator):
1509 pass
1510
1511wrapper = {
1512 ast.Getattr: AugGetattr,
1513 ast.Name: AugName,
1514 ast.Slice: AugSlice,
1515 ast.Subscript: AugSubscript,
1516 }
1517
1518def wrap_aug(node):
1519 return wrapper[node.__class__](node)
1520
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001521if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001522 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001523 compileFile(file)