blob: 4f2ecf2ae87f2d5974a1789a7c41bc3d0e39fd3a [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()
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000424 self.emit('POP_JUMP_IF_FALSE', nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000425 self.nextBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000426 self.visit(suite)
427 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000428 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000429 if node.else_:
430 self.visit(node.else_)
431 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000432
433 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000434 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000435
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000436 loop = self.newBlock()
437 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000438
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000439 after = self.newBlock()
440 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000441
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000442 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000443 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000444
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000445 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000446 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000447 self.emit('POP_JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000448
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000449 self.nextBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000450 self.visit(node.body)
451 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000452
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000453 self.startBlock(else_) # or just the POPs if not else clause
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000454 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000455 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000456 if node.else_:
457 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000458 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000459
460 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000461 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000462 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000463 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000464 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000465
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000466 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000467 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000468 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000469 self.emit('GET_ITER')
470
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000471 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000472 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000473 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000474 self.visit(node.assign)
475 self.visit(node.body)
476 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000477 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000479 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000480 if node.else_:
481 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000482 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000483
484 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000485 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000486 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000487 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000488 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000489 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000490
491 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000492 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000493 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000494 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000495 kind, block = self.setups.top()
496 if kind == LOOP:
497 self.set_lineno(node)
498 self.emit('JUMP_ABSOLUTE', block)
499 self.nextBlock()
500 elif kind == EXCEPT or kind == TRY_FINALLY:
501 self.set_lineno(node)
502 # find the block that starts the loop
503 top = len(self.setups)
504 while top > 0:
505 top = top - 1
506 kind, loop_block = self.setups[top]
507 if kind == LOOP:
508 break
509 if kind != LOOP:
510 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000511 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000512 self.emit('CONTINUE_LOOP', loop_block)
513 self.nextBlock()
514 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000515 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000516 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000517
518 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000519 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000520 for child in node.nodes[:-1]:
521 self.visit(child)
522 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000523 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000524 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000525 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000526
527 def visitAnd(self, node):
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000528 self.visitTest(node, 'JUMP_IF_FALSE_OR_POP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000529
530 def visitOr(self, node):
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000531 self.visitTest(node, 'JUMP_IF_TRUE_OR_POP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000533 def visitIfExp(self, node):
534 endblock = self.newBlock()
535 elseblock = self.newBlock()
536 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000537 self.emit('POP_JUMP_IF_FALSE', elseblock)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000538 self.visit(node.then)
539 self.emit('JUMP_FORWARD', endblock)
540 self.nextBlock(elseblock)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000541 self.visit(node.else_)
542 self.nextBlock(endblock)
543
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000544 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000545 self.visit(node.expr)
546 cleanup = self.newBlock()
547 for op, code in node.ops[:-1]:
548 self.visit(code)
549 self.emit('DUP_TOP')
550 self.emit('ROT_THREE')
551 self.emit('COMPARE_OP', op)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000552 self.emit('JUMP_IF_FALSE_OR_POP', cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000553 self.nextBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000554 # now do the last comparison
555 if node.ops:
556 op, code = node.ops[-1]
557 self.visit(code)
558 self.emit('COMPARE_OP', op)
559 if len(node.ops) > 1:
560 end = self.newBlock()
561 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000562 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000563 self.emit('ROT_TWO')
564 self.emit('POP_TOP')
565 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000566
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000567 # list comprehensions
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000568 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000569 self.set_lineno(node)
570 # setup list
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000571 self.emit('BUILD_LIST', 0)
Tim Peterse0c446b2001-10-18 21:57:37 +0000572
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000573 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000574 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000575 start, anchor = self.visit(for_)
576 cont = None
577 for if_ in for_.ifs:
578 if cont is None:
579 cont = self.newBlock()
580 self.visit(if_, cont)
581 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000582
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000583 self.visit(node.expr)
Antoine Pitroud0c35152008-12-17 00:38:28 +0000584 self.emit('LIST_APPEND', len(node.quals) + 1)
Tim Peterse0c446b2001-10-18 21:57:37 +0000585
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000586 for start, cont, anchor in stack:
587 if cont:
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000588 self.nextBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000589 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000590 self.startBlock(anchor)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000591
Alexandre Vassalottib6465472010-01-11 22:36:12 +0000592 def visitSetComp(self, node):
593 self.set_lineno(node)
594 # setup list
595 self.emit('BUILD_SET', 0)
596
597 stack = []
598 for i, for_ in zip(range(len(node.quals)), node.quals):
599 start, anchor = self.visit(for_)
600 cont = None
601 for if_ in for_.ifs:
602 if cont is None:
603 cont = self.newBlock()
604 self.visit(if_, cont)
605 stack.insert(0, (start, cont, anchor))
606
607 self.visit(node.expr)
608 self.emit('SET_ADD', len(node.quals) + 1)
609
610 for start, cont, anchor in stack:
611 if cont:
612 self.nextBlock(cont)
613 self.emit('JUMP_ABSOLUTE', start)
614 self.startBlock(anchor)
615
616 def visitDictComp(self, node):
617 self.set_lineno(node)
618 # setup list
619 self.emit('BUILD_MAP', 0)
620
621 stack = []
622 for i, for_ in zip(range(len(node.quals)), node.quals):
623 start, anchor = self.visit(for_)
624 cont = None
625 for if_ in for_.ifs:
626 if cont is None:
627 cont = self.newBlock()
628 self.visit(if_, cont)
629 stack.insert(0, (start, cont, anchor))
630
631 self.visit(node.value)
632 self.visit(node.key)
633 self.emit('MAP_ADD', len(node.quals) + 1)
634
635 for start, cont, anchor in stack:
636 if cont:
637 self.nextBlock(cont)
638 self.emit('JUMP_ABSOLUTE', start)
639 self.startBlock(anchor)
640
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000641 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000642 start = self.newBlock()
643 anchor = self.newBlock()
644
645 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000646 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000647 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000648 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000649 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000650 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000651 self.visit(node.assign)
652 return start, anchor
653
654 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000655 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000656 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000657 self.emit('POP_JUMP_IF_FALSE', branch)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000658 self.newBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000659
Neil Schemenauer06ded092006-08-04 16:20:30 +0000660 def _makeClosure(self, gen, args):
661 frees = gen.scope.get_free_vars()
662 if frees:
663 for name in frees:
664 self.emit('LOAD_CLOSURE', name)
665 self.emit('BUILD_TUPLE', len(frees))
666 self.emit('LOAD_CONST', gen)
667 self.emit('MAKE_CLOSURE', args)
668 else:
669 self.emit('LOAD_CONST', gen)
670 self.emit('MAKE_FUNCTION', args)
671
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672 def visitGenExpr(self, node):
673 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
674 self.get_module())
675 walk(node.code, gen)
676 gen.finish()
677 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000678 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000679 # precomputation of outmost iterable
680 self.visit(node.code.quals[0].iter)
681 self.emit('GET_ITER')
682 self.emit('CALL_FUNCTION', 1)
683
684 def visitGenExprInner(self, node):
685 self.set_lineno(node)
686 # setup list
687
688 stack = []
689 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000690 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000691 cont = None
692 for if_ in for_.ifs:
693 if cont is None:
694 cont = self.newBlock()
695 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000696 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000697
698 self.visit(node.expr)
699 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000700 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000701
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000702 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000703 if cont:
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000704 self.nextBlock(cont)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000705 self.emit('JUMP_ABSOLUTE', start)
706 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000707 self.emit('POP_BLOCK')
708 self.setups.pop()
Neil Schemenauer4db626f2009-02-06 21:08:52 +0000709 self.nextBlock(end)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000710
Raymond Hettinger354433a2004-05-19 08:20:33 +0000711 self.emit('LOAD_CONST', None)
712
713 def visitGenExprFor(self, node):
714 start = self.newBlock()
715 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000716 end = self.newBlock()
717
718 self.setups.push((LOOP, start))
719 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000720
Raymond Hettinger354433a2004-05-19 08:20:33 +0000721 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000722 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000723 else:
724 self.visit(node.iter)
725 self.emit('GET_ITER')
726
727 self.nextBlock(start)
728 self.set_lineno(node, force=True)
729 self.emit('FOR_ITER', anchor)
730 self.nextBlock()
731 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000732 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000733
734 def visitGenExprIf(self, node, branch):
735 self.set_lineno(node, force=True)
736 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000737 self.emit('POP_JUMP_IF_FALSE', branch)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000738 self.newBlock()
Raymond Hettinger354433a2004-05-19 08:20:33 +0000739
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000740 # exception related
741
742 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000743 # XXX would be interesting to implement this via a
744 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000745 if __debug__:
746 end = self.newBlock()
747 self.set_lineno(node)
748 # XXX AssertionError appears to be special case -- it is always
749 # loaded as a global even if there is a local name. I guess this
750 # is a sort of renaming op.
751 self.nextBlock()
752 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000753 self.emit('POP_JUMP_IF_TRUE', end)
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000754 self.nextBlock()
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000755 self.emit('LOAD_GLOBAL', 'AssertionError')
756 if node.fail:
757 self.visit(node.fail)
758 self.emit('RAISE_VARARGS', 2)
759 else:
760 self.emit('RAISE_VARARGS', 1)
761 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000762
763 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000764 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000765 n = 0
766 if node.expr1:
767 self.visit(node.expr1)
768 n = n + 1
769 if node.expr2:
770 self.visit(node.expr2)
771 n = n + 1
772 if node.expr3:
773 self.visit(node.expr3)
774 n = n + 1
775 self.emit('RAISE_VARARGS', n)
776
777 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000778 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000779 handlers = self.newBlock()
780 end = self.newBlock()
781 if node.else_:
782 lElse = self.newBlock()
783 else:
784 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000785 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000786 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000787 self.nextBlock(body)
788 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000789 self.visit(node.body)
790 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000791 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000792 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000793 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000794
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000795 last = len(node.handlers) - 1
796 for i in range(len(node.handlers)):
797 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000798 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000799 if expr:
800 self.emit('DUP_TOP')
801 self.visit(expr)
802 self.emit('COMPARE_OP', 'exception match')
803 next = self.newBlock()
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000804 self.emit('POP_JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000805 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000806 self.emit('POP_TOP')
807 if target:
808 self.visit(target)
809 else:
810 self.emit('POP_TOP')
811 self.emit('POP_TOP')
812 self.visit(body)
813 self.emit('JUMP_FORWARD', end)
814 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000815 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000816 else:
817 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000818 self.emit('END_FINALLY')
819 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000820 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000821 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000822 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000823
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000824 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000825 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000826 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000827 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000828 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000829 self.nextBlock(body)
830 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000831 self.visit(node.body)
832 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000833 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000834 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000835 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000836 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000837 self.visit(node.final)
838 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000839 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000840
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000841 __with_count = 0
842
843 def visitWith(self, node):
844 body = self.newBlock()
845 final = self.newBlock()
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000846 self.__with_count += 1
Neil Schemenauer98c3b852009-02-07 00:13:39 +0000847 valuevar = "_[%d]" % self.__with_count
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000848 self.set_lineno(node)
849 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000850 self.emit('DUP_TOP')
851 self.emit('LOAD_ATTR', '__exit__')
Nick Coghlan7af53be2008-03-07 14:13:28 +0000852 self.emit('ROT_TWO')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000853 self.emit('LOAD_ATTR', '__enter__')
854 self.emit('CALL_FUNCTION', 0)
855 if node.vars is None:
856 self.emit('POP_TOP')
857 else:
858 self._implicitNameOp('STORE', valuevar)
859 self.emit('SETUP_FINALLY', final)
860 self.nextBlock(body)
861 self.setups.push((TRY_FINALLY, body))
862 if node.vars is not None:
863 self._implicitNameOp('LOAD', valuevar)
864 self._implicitNameOp('DELETE', valuevar)
865 self.visit(node.vars)
866 self.visit(node.body)
867 self.emit('POP_BLOCK')
868 self.setups.pop()
869 self.emit('LOAD_CONST', None)
870 self.nextBlock(final)
871 self.setups.push((END_FINALLY, final))
872 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000873 self.emit('END_FINALLY')
874 self.setups.pop()
875 self.__with_count -= 1
876
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000877 # misc
878
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000879 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000880 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000881 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000882 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000883
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000884 def visitConst(self, node):
885 self.emit('LOAD_CONST', node.value)
886
887 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000888 self.emit('LOAD_CONST', node.name)
889 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000890
891 def visitGlobal(self, node):
892 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000893 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000894
895 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000896 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000897 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000898
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000899 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000900 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000901
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000902 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000903 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000904 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000905 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000906 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000907 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000908 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000909 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000910 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000911 if alias:
912 self._resolveDots(name)
913 self.storeName(alias)
914 else:
915 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000916
917 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000918 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000919 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000920 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000921 level = -1
Antoine Pitroub9d49632010-01-04 23:22:44 +0000922 fromlist = tuple(name for (name, alias) in node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000923 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000924 self.emit('LOAD_CONST', level)
Antoine Pitroub9d49632010-01-04 23:22:44 +0000925 self.emit('LOAD_CONST', fromlist)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000926 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000927 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000928 if VERSION > 1:
929 if name == '*':
930 self.namespace = 0
931 self.emit('IMPORT_STAR')
932 # There can only be one name w/ from ... import *
933 assert len(node.names) == 1
934 return
935 else:
936 self.emit('IMPORT_FROM', name)
937 self._resolveDots(name)
938 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000939 else:
940 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000941 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000942
Jeremy Hylton20516082000-09-01 20:33:26 +0000943 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000944 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000945 if len(elts) == 1:
946 return
947 for elt in elts[1:]:
948 self.emit('LOAD_ATTR', elt)
949
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000950 def visitGetattr(self, node):
951 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000952 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953
954 # next five implement assignments
955
956 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000957 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000958 self.visit(node.expr)
959 dups = len(node.nodes) - 1
960 for i in range(len(node.nodes)):
961 elt = node.nodes[i]
962 if i < dups:
963 self.emit('DUP_TOP')
964 if isinstance(elt, ast.Node):
965 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000966
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000967 def visitAssName(self, node):
968 if node.flags == 'OP_ASSIGN':
969 self.storeName(node.name)
970 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000971 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000972 self.delName(node.name)
973 else:
974 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000975
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000976 def visitAssAttr(self, node):
977 self.visit(node.expr)
978 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000979 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000980 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000981 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000982 else:
983 print "warning: unexpected flags:", node.flags
984 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000985
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000986 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000987 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000988 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000989 for child in node.nodes:
990 self.visit(child)
991
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000992 if VERSION > 1:
993 visitAssTuple = _visitAssSequence
994 visitAssList = _visitAssSequence
995 else:
996 def visitAssTuple(self, node):
997 self._visitAssSequence(node, 'UNPACK_TUPLE')
998
999 def visitAssList(self, node):
1000 self._visitAssSequence(node, 'UNPACK_LIST')
1001
1002 # augmented assignment
1003
1004 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +00001005 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001006 aug_node = wrap_aug(node.node)
1007 self.visit(aug_node, "load")
1008 self.visit(node.expr)
1009 self.emit(self._augmented_opcode[node.op])
1010 self.visit(aug_node, "store")
1011
1012 _augmented_opcode = {
1013 '+=' : 'INPLACE_ADD',
1014 '-=' : 'INPLACE_SUBTRACT',
1015 '*=' : 'INPLACE_MULTIPLY',
1016 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001017 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001018 '%=' : 'INPLACE_MODULO',
1019 '**=': 'INPLACE_POWER',
1020 '>>=': 'INPLACE_RSHIFT',
1021 '<<=': 'INPLACE_LSHIFT',
1022 '&=' : 'INPLACE_AND',
1023 '^=' : 'INPLACE_XOR',
1024 '|=' : 'INPLACE_OR',
1025 }
1026
1027 def visitAugName(self, node, mode):
1028 if mode == "load":
1029 self.loadName(node.name)
1030 elif mode == "store":
1031 self.storeName(node.name)
1032
1033 def visitAugGetattr(self, node, mode):
1034 if mode == "load":
1035 self.visit(node.expr)
1036 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001037 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001038 elif mode == "store":
1039 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001040 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001041
1042 def visitAugSlice(self, node, mode):
1043 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001044 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001045 elif mode == "store":
1046 slice = 0
1047 if node.lower:
1048 slice = slice | 1
1049 if node.upper:
1050 slice = slice | 2
1051 if slice == 0:
1052 self.emit('ROT_TWO')
1053 elif slice == 3:
1054 self.emit('ROT_FOUR')
1055 else:
1056 self.emit('ROT_THREE')
1057 self.emit('STORE_SLICE+%d' % slice)
1058
1059 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001060 if mode == "load":
1061 self.visitSubscript(node, 1)
1062 elif mode == "store":
1063 self.emit('ROT_THREE')
1064 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001065
1066 def visitExec(self, node):
1067 self.visit(node.expr)
1068 if node.locals is None:
1069 self.emit('LOAD_CONST', None)
1070 else:
1071 self.visit(node.locals)
1072 if node.globals is None:
1073 self.emit('DUP_TOP')
1074 else:
1075 self.visit(node.globals)
1076 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001077
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001078 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001079 pos = 0
1080 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001081 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001082 self.visit(node.node)
1083 for arg in node.args:
1084 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001085 if isinstance(arg, ast.Keyword):
1086 kw = kw + 1
1087 else:
1088 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001089 if node.star_args is not None:
1090 self.visit(node.star_args)
1091 if node.dstar_args is not None:
1092 self.visit(node.dstar_args)
1093 have_star = node.star_args is not None
1094 have_dstar = node.dstar_args is not None
1095 opcode = callfunc_opcode_info[have_star, have_dstar]
1096 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001097
Jeremy Hylton2afff322001-08-27 21:51:52 +00001098 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001099 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001100 if node.dest:
1101 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001102 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001103 if node.dest:
1104 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001105 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001106 if node.dest:
1107 self.emit('ROT_TWO')
1108 self.emit('PRINT_ITEM_TO')
1109 else:
1110 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001111 if node.dest and not newline:
1112 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001113
1114 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001115 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001116 if node.dest:
1117 self.emit('PRINT_NEWLINE_TO')
1118 else:
1119 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001120
1121 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001122 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001123 self.visit(node.value)
1124 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001125
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001126 def visitYield(self, node):
1127 self.set_lineno(node)
1128 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001129 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001130
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001131 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001133 def visitSlice(self, node, aug_flag=None):
1134 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001135 self.visit(node.expr)
1136 slice = 0
1137 if node.lower:
1138 self.visit(node.lower)
1139 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001140 if node.upper:
1141 self.visit(node.upper)
1142 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001143 if aug_flag:
1144 if slice == 0:
1145 self.emit('DUP_TOP')
1146 elif slice == 3:
1147 self.emit('DUP_TOPX', 3)
1148 else:
1149 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001150 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001151 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001152 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001153 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001154 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001155 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001156 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001157 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001158 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001159
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001160 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001161 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001162 for sub in node.subs:
1163 self.visit(sub)
1164 if len(node.subs) > 1:
1165 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001166 if aug_flag:
1167 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001168 if node.flags == 'OP_APPLY':
1169 self.emit('BINARY_SUBSCR')
1170 elif node.flags == 'OP_ASSIGN':
1171 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001172 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001173 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001174
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001175 # binary ops
1176
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001177 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 self.visit(node.left)
1179 self.visit(node.right)
1180 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001181
1182 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001183 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001184
1185 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001186 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001187
1188 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001189 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001190
1191 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001192 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001193
Jeremy Hylton94afe322001-08-29 18:14:39 +00001194 def visitFloorDiv(self, node):
1195 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1196
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001197 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001198 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001199
Jeremy Hylton126960b2000-02-14 21:33:10 +00001200 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001201 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001202
1203 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001204 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001205
1206 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001207 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001208
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001209 # unary ops
1210
1211 def unaryOp(self, node, op):
1212 self.visit(node.expr)
1213 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001214
Jeremy Hylton126960b2000-02-14 21:33:10 +00001215 def visitInvert(self, node):
1216 return self.unaryOp(node, 'UNARY_INVERT')
1217
Jeremy Hylton40245602000-02-08 21:15:48 +00001218 def visitUnarySub(self, node):
1219 return self.unaryOp(node, 'UNARY_NEGATIVE')
1220
1221 def visitUnaryAdd(self, node):
1222 return self.unaryOp(node, 'UNARY_POSITIVE')
1223
1224 def visitUnaryInvert(self, node):
1225 return self.unaryOp(node, 'UNARY_INVERT')
1226
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001227 def visitNot(self, node):
1228 return self.unaryOp(node, 'UNARY_NOT')
1229
Jeremy Hylton40245602000-02-08 21:15:48 +00001230 def visitBackquote(self, node):
1231 return self.unaryOp(node, 'UNARY_CONVERT')
1232
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001233 # bit ops
1234
Jeremy Hyltona5058122000-02-14 14:14:29 +00001235 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001236 self.visit(nodes[0])
1237 for node in nodes[1:]:
1238 self.visit(node)
1239 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001240
1241 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001242 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001243
1244 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001245 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246
1247 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001248 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001249
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001250 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001251
Jeremy Hyltona5058122000-02-14 14:14:29 +00001252 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001253 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001254
Jeremy Hylton40245602000-02-08 21:15:48 +00001255 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001256 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001257 for elt in node.nodes:
1258 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001259 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001260
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001261 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001262 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001263 for elt in node.nodes:
1264 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001265 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001266
Alexandre Vassalottiee936a22010-01-09 23:35:54 +00001267 def visitSet(self, node):
1268 self.set_lineno(node)
1269 for elt in node.nodes:
1270 self.visit(elt)
1271 self.emit('BUILD_SET', len(node.nodes))
1272
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001273 def visitSliceobj(self, node):
1274 for child in node.nodes:
1275 self.visit(child)
1276 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001277
Jeremy Hyltona5058122000-02-14 14:14:29 +00001278 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001279 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001280 self.emit('BUILD_MAP', 0)
1281 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001282 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001283 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001284 self.visit(v)
1285 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001286 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001287
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001288class NestedScopeMixin:
1289 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001290 def initClass(self):
1291 self.__class__.NameFinder = LocalNameFinder
1292 self.__class__.FunctionGen = FunctionCodeGenerator
1293 self.__class__.ClassGen = ClassCodeGenerator
1294
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001295class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001296 __super_init = CodeGenerator.__init__
1297
1298 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001299
Jeremy Hylton37c93512001-09-17 18:03:55 +00001300 def __init__(self, tree):
1301 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001302 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001303 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001304 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001305
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001306 def get_module(self):
1307 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001308
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001309class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1310 __super_init = CodeGenerator.__init__
1311
1312 scopes = None
1313 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001314
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001315 def __init__(self, tree):
1316 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1317 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001318 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001319
1320 def get_module(self):
1321 return self
1322
1323class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1324
1325 __super_init = CodeGenerator.__init__
1326
1327 scopes = None
1328 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001329
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001330 def __init__(self, tree):
1331 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1332 self.__super_init()
1333 self.set_lineno(tree)
1334 walk(tree, self)
1335 self.emit('RETURN_VALUE')
1336
1337 def get_module(self):
1338 return self
Tim Peterse4418602002-02-16 07:34:19 +00001339
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001340 def visitDiscard(self, node):
1341 # XXX Discard means it's an expression. Perhaps this is a bad
1342 # name.
1343 self.visit(node.expr)
1344 self.emit('PRINT_EXPR')
1345
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001346class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001347 optimized = 1
1348 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001349
Jeremy Hylton37c93512001-09-17 18:03:55 +00001350 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001351 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001352 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001353 if isLambda:
1354 klass = FunctionCodeGenerator
1355 name = "<lambda.%d>" % klass.lambdaCount
1356 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001357 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001358 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001359
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001360 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001361 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1362 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001363 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001364 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001365
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001366 if not isLambda and func.doc:
1367 self.setDocstring(func.doc)
1368
Jeremy Hylton2afff322001-08-27 21:51:52 +00001369 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001370 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001371 if func.varargs:
1372 self.graph.setFlag(CO_VARARGS)
1373 if func.kwargs:
1374 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001375 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001376 if hasTupleArg:
1377 self.generateArgUnpack(func.argnames)
1378
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001379 def get_module(self):
1380 return self.module
1381
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001382 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001383 self.graph.startExitBlock()
1384 if not self.isLambda:
1385 self.emit('LOAD_CONST', None)
1386 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001387
1388 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001389 for i in range(len(args)):
1390 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001391 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001392 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001393 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001394
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001395 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001396 if VERSION > 1:
1397 self.emit('UNPACK_SEQUENCE', len(tup))
1398 else:
1399 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001400 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001401 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001402 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001403 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001404 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001405
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001406 unpackTuple = unpackSequence
1407
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001408class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001409 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001410 super_init = CodeGenerator.__init__ # call be other init
1411 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001412
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001413 __super_init = AbstractFunctionCode.__init__
1414
Jeremy Hylton37c93512001-09-17 18:03:55 +00001415 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001416 self.scopes = scopes
1417 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001418 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001419 self.graph.setFreeVars(self.scope.get_free_vars())
1420 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001421 if self.scope.generator is not None:
1422 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001423
Raymond Hettinger354433a2004-05-19 08:20:33 +00001424class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1425 CodeGenerator):
1426 super_init = CodeGenerator.__init__ # call be other init
1427 scopes = None
1428
1429 __super_init = AbstractFunctionCode.__init__
1430
1431 def __init__(self, gexp, scopes, class_name, mod):
1432 self.scopes = scopes
1433 self.scope = scopes[gexp]
1434 self.__super_init(gexp, scopes, 1, class_name, mod)
1435 self.graph.setFreeVars(self.scope.get_free_vars())
1436 self.graph.setCellVars(self.scope.get_cell_vars())
1437 self.graph.setFlag(CO_GENERATOR)
1438
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001439class AbstractClassCode:
1440
Jeremy Hylton37c93512001-09-17 18:03:55 +00001441 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001442 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001443 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001444 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001445 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001446 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001447 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001448 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001449 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001450 if klass.doc:
1451 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001452
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001453 def get_module(self):
1454 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001455
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001456 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001457 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001458 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001459 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001460
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001461class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001462 super_init = CodeGenerator.__init__
1463 scopes = None
1464
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001465 __super_init = AbstractClassCode.__init__
1466
Jeremy Hylton37c93512001-09-17 18:03:55 +00001467 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001468 self.scopes = scopes
1469 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001470 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001471 self.graph.setFreeVars(self.scope.get_free_vars())
1472 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001473 self.set_lineno(klass)
1474 self.emit("LOAD_GLOBAL", "__name__")
1475 self.storeName("__module__")
1476 if klass.doc:
1477 self.emit("LOAD_CONST", klass.doc)
1478 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001479
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001480def generateArgList(arglist):
1481 """Generate an arg list marking TupleArgs"""
1482 args = []
1483 extra = []
1484 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001485 for i in range(len(arglist)):
1486 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001487 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001488 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001489 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001490 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001491 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001492 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001493 else:
1494 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001495 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001496
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001497def findOp(node):
1498 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1499 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001500 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001501 return v.op
1502
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001503class OpFinder:
1504 def __init__(self):
1505 self.op = None
1506 def visitAssName(self, node):
1507 if self.op is None:
1508 self.op = node.flags
1509 elif self.op != node.flags:
1510 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001511 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001512 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001513
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001514class Delegator:
1515 """Base class to support delegation for augmented assignment nodes
1516
1517 To generator code for augmented assignments, we use the following
1518 wrapper classes. In visitAugAssign, the left-hand expression node
1519 is visited twice. The first time the visit uses the normal method
1520 for that node . The second time the visit uses a different method
1521 that generates the appropriate code to perform the assignment.
1522 These delegator classes wrap the original AST nodes in order to
1523 support the variant visit methods.
1524 """
1525 def __init__(self, obj):
1526 self.obj = obj
1527
1528 def __getattr__(self, attr):
1529 return getattr(self.obj, attr)
1530
1531class AugGetattr(Delegator):
1532 pass
1533
1534class AugName(Delegator):
1535 pass
1536
1537class AugSlice(Delegator):
1538 pass
1539
1540class AugSubscript(Delegator):
1541 pass
1542
1543wrapper = {
1544 ast.Getattr: AugGetattr,
1545 ast.Name: AugName,
1546 ast.Slice: AugSlice,
1547 ast.Subscript: AugSubscript,
1548 }
1549
1550def wrap_aug(node):
1551 return wrapper[node.__class__](node)
1552
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001553if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001554 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001555 compileFile(file)