blob: 960c4fce29bd19c4f3ae55beee4ceb2655887c13 [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
592 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000593 start = self.newBlock()
594 anchor = self.newBlock()
595
596 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000597 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000598 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000599 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000600 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000601 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000602 self.visit(node.assign)
603 return start, anchor
604
605 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000606 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000607 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000608 self.emit('POP_JUMP_IF_FALSE', branch)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000609 self.newBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610
Neil Schemenauer06ded092006-08-04 16:20:30 +0000611 def _makeClosure(self, gen, args):
612 frees = gen.scope.get_free_vars()
613 if frees:
614 for name in frees:
615 self.emit('LOAD_CLOSURE', name)
616 self.emit('BUILD_TUPLE', len(frees))
617 self.emit('LOAD_CONST', gen)
618 self.emit('MAKE_CLOSURE', args)
619 else:
620 self.emit('LOAD_CONST', gen)
621 self.emit('MAKE_FUNCTION', args)
622
Raymond Hettinger354433a2004-05-19 08:20:33 +0000623 def visitGenExpr(self, node):
624 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
625 self.get_module())
626 walk(node.code, gen)
627 gen.finish()
628 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000629 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000630 # precomputation of outmost iterable
631 self.visit(node.code.quals[0].iter)
632 self.emit('GET_ITER')
633 self.emit('CALL_FUNCTION', 1)
634
635 def visitGenExprInner(self, node):
636 self.set_lineno(node)
637 # setup list
638
639 stack = []
640 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000641 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000642 cont = None
643 for if_ in for_.ifs:
644 if cont is None:
645 cont = self.newBlock()
646 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000647 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000648
649 self.visit(node.expr)
650 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000651 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000652
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000653 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000654 if cont:
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000655 self.nextBlock(cont)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000656 self.emit('JUMP_ABSOLUTE', start)
657 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000658 self.emit('POP_BLOCK')
659 self.setups.pop()
Neil Schemenauer4db626f2009-02-06 21:08:52 +0000660 self.nextBlock(end)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000661
Raymond Hettinger354433a2004-05-19 08:20:33 +0000662 self.emit('LOAD_CONST', None)
663
664 def visitGenExprFor(self, node):
665 start = self.newBlock()
666 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000667 end = self.newBlock()
668
669 self.setups.push((LOOP, start))
670 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000671
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000673 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000674 else:
675 self.visit(node.iter)
676 self.emit('GET_ITER')
677
678 self.nextBlock(start)
679 self.set_lineno(node, force=True)
680 self.emit('FOR_ITER', anchor)
681 self.nextBlock()
682 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000683 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000684
685 def visitGenExprIf(self, node, branch):
686 self.set_lineno(node, force=True)
687 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000688 self.emit('POP_JUMP_IF_FALSE', branch)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000689 self.newBlock()
Raymond Hettinger354433a2004-05-19 08:20:33 +0000690
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000691 # exception related
692
693 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000694 # XXX would be interesting to implement this via a
695 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000696 if __debug__:
697 end = self.newBlock()
698 self.set_lineno(node)
699 # XXX AssertionError appears to be special case -- it is always
700 # loaded as a global even if there is a local name. I guess this
701 # is a sort of renaming op.
702 self.nextBlock()
703 self.visit(node.test)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000704 self.emit('POP_JUMP_IF_TRUE', end)
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000705 self.nextBlock()
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000706 self.emit('LOAD_GLOBAL', 'AssertionError')
707 if node.fail:
708 self.visit(node.fail)
709 self.emit('RAISE_VARARGS', 2)
710 else:
711 self.emit('RAISE_VARARGS', 1)
712 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000713
714 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000715 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000716 n = 0
717 if node.expr1:
718 self.visit(node.expr1)
719 n = n + 1
720 if node.expr2:
721 self.visit(node.expr2)
722 n = n + 1
723 if node.expr3:
724 self.visit(node.expr3)
725 n = n + 1
726 self.emit('RAISE_VARARGS', n)
727
728 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000729 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000730 handlers = self.newBlock()
731 end = self.newBlock()
732 if node.else_:
733 lElse = self.newBlock()
734 else:
735 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000736 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000737 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000738 self.nextBlock(body)
739 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000740 self.visit(node.body)
741 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000742 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000743 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000744 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000745
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000746 last = len(node.handlers) - 1
747 for i in range(len(node.handlers)):
748 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000749 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000750 if expr:
751 self.emit('DUP_TOP')
752 self.visit(expr)
753 self.emit('COMPARE_OP', 'exception match')
754 next = self.newBlock()
Jeffrey Yasskin68d68522009-02-28 19:03:21 +0000755 self.emit('POP_JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000756 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000757 self.emit('POP_TOP')
758 if target:
759 self.visit(target)
760 else:
761 self.emit('POP_TOP')
762 self.emit('POP_TOP')
763 self.visit(body)
764 self.emit('JUMP_FORWARD', end)
765 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000766 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000767 else:
768 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000769 self.emit('END_FINALLY')
770 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000771 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000772 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000773 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000774
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000776 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000777 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000778 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000779 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000780 self.nextBlock(body)
781 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000782 self.visit(node.body)
783 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000784 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000785 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000786 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000787 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000788 self.visit(node.final)
789 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000790 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000791
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000792 __with_count = 0
793
794 def visitWith(self, node):
795 body = self.newBlock()
796 final = self.newBlock()
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000797 self.__with_count += 1
Neil Schemenauer98c3b852009-02-07 00:13:39 +0000798 valuevar = "_[%d]" % self.__with_count
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000799 self.set_lineno(node)
800 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000801 self.emit('DUP_TOP')
802 self.emit('LOAD_ATTR', '__exit__')
Nick Coghlan7af53be2008-03-07 14:13:28 +0000803 self.emit('ROT_TWO')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000804 self.emit('LOAD_ATTR', '__enter__')
805 self.emit('CALL_FUNCTION', 0)
806 if node.vars is None:
807 self.emit('POP_TOP')
808 else:
809 self._implicitNameOp('STORE', valuevar)
810 self.emit('SETUP_FINALLY', final)
811 self.nextBlock(body)
812 self.setups.push((TRY_FINALLY, body))
813 if node.vars is not None:
814 self._implicitNameOp('LOAD', valuevar)
815 self._implicitNameOp('DELETE', valuevar)
816 self.visit(node.vars)
817 self.visit(node.body)
818 self.emit('POP_BLOCK')
819 self.setups.pop()
820 self.emit('LOAD_CONST', None)
821 self.nextBlock(final)
822 self.setups.push((END_FINALLY, final))
823 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000824 self.emit('END_FINALLY')
825 self.setups.pop()
826 self.__with_count -= 1
827
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000828 # misc
829
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000830 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000831 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000832 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000833 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000834
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000835 def visitConst(self, node):
836 self.emit('LOAD_CONST', node.value)
837
838 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000839 self.emit('LOAD_CONST', node.name)
840 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000841
842 def visitGlobal(self, node):
843 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000844 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000845
846 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000847 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000848 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000849
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000850 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000851 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000852
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000853 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000854 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000855 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000856 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000857 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000858 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000859 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000860 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000861 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000862 if alias:
863 self._resolveDots(name)
864 self.storeName(alias)
865 else:
866 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000867
868 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000869 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000870 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000871 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000872 level = -1
Antoine Pitroub9d49632010-01-04 23:22:44 +0000873 fromlist = tuple(name for (name, alias) in node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000874 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000875 self.emit('LOAD_CONST', level)
Antoine Pitroub9d49632010-01-04 23:22:44 +0000876 self.emit('LOAD_CONST', fromlist)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000877 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000878 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000879 if VERSION > 1:
880 if name == '*':
881 self.namespace = 0
882 self.emit('IMPORT_STAR')
883 # There can only be one name w/ from ... import *
884 assert len(node.names) == 1
885 return
886 else:
887 self.emit('IMPORT_FROM', name)
888 self._resolveDots(name)
889 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000890 else:
891 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000892 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000893
Jeremy Hylton20516082000-09-01 20:33:26 +0000894 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000895 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000896 if len(elts) == 1:
897 return
898 for elt in elts[1:]:
899 self.emit('LOAD_ATTR', elt)
900
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000901 def visitGetattr(self, node):
902 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000903 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000904
905 # next five implement assignments
906
907 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000908 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000909 self.visit(node.expr)
910 dups = len(node.nodes) - 1
911 for i in range(len(node.nodes)):
912 elt = node.nodes[i]
913 if i < dups:
914 self.emit('DUP_TOP')
915 if isinstance(elt, ast.Node):
916 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000917
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000918 def visitAssName(self, node):
919 if node.flags == 'OP_ASSIGN':
920 self.storeName(node.name)
921 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000922 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000923 self.delName(node.name)
924 else:
925 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000926
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000927 def visitAssAttr(self, node):
928 self.visit(node.expr)
929 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000930 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000931 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000932 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000933 else:
934 print "warning: unexpected flags:", node.flags
935 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000936
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000937 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000938 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000939 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000940 for child in node.nodes:
941 self.visit(child)
942
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000943 if VERSION > 1:
944 visitAssTuple = _visitAssSequence
945 visitAssList = _visitAssSequence
946 else:
947 def visitAssTuple(self, node):
948 self._visitAssSequence(node, 'UNPACK_TUPLE')
949
950 def visitAssList(self, node):
951 self._visitAssSequence(node, 'UNPACK_LIST')
952
953 # augmented assignment
954
955 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000956 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000957 aug_node = wrap_aug(node.node)
958 self.visit(aug_node, "load")
959 self.visit(node.expr)
960 self.emit(self._augmented_opcode[node.op])
961 self.visit(aug_node, "store")
962
963 _augmented_opcode = {
964 '+=' : 'INPLACE_ADD',
965 '-=' : 'INPLACE_SUBTRACT',
966 '*=' : 'INPLACE_MULTIPLY',
967 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000968 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000969 '%=' : 'INPLACE_MODULO',
970 '**=': 'INPLACE_POWER',
971 '>>=': 'INPLACE_RSHIFT',
972 '<<=': 'INPLACE_LSHIFT',
973 '&=' : 'INPLACE_AND',
974 '^=' : 'INPLACE_XOR',
975 '|=' : 'INPLACE_OR',
976 }
977
978 def visitAugName(self, node, mode):
979 if mode == "load":
980 self.loadName(node.name)
981 elif mode == "store":
982 self.storeName(node.name)
983
984 def visitAugGetattr(self, node, mode):
985 if mode == "load":
986 self.visit(node.expr)
987 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000988 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000989 elif mode == "store":
990 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000991 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000992
993 def visitAugSlice(self, node, mode):
994 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +0000995 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000996 elif mode == "store":
997 slice = 0
998 if node.lower:
999 slice = slice | 1
1000 if node.upper:
1001 slice = slice | 2
1002 if slice == 0:
1003 self.emit('ROT_TWO')
1004 elif slice == 3:
1005 self.emit('ROT_FOUR')
1006 else:
1007 self.emit('ROT_THREE')
1008 self.emit('STORE_SLICE+%d' % slice)
1009
1010 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001011 if mode == "load":
1012 self.visitSubscript(node, 1)
1013 elif mode == "store":
1014 self.emit('ROT_THREE')
1015 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001016
1017 def visitExec(self, node):
1018 self.visit(node.expr)
1019 if node.locals is None:
1020 self.emit('LOAD_CONST', None)
1021 else:
1022 self.visit(node.locals)
1023 if node.globals is None:
1024 self.emit('DUP_TOP')
1025 else:
1026 self.visit(node.globals)
1027 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001028
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001029 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001030 pos = 0
1031 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001032 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001033 self.visit(node.node)
1034 for arg in node.args:
1035 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001036 if isinstance(arg, ast.Keyword):
1037 kw = kw + 1
1038 else:
1039 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001040 if node.star_args is not None:
1041 self.visit(node.star_args)
1042 if node.dstar_args is not None:
1043 self.visit(node.dstar_args)
1044 have_star = node.star_args is not None
1045 have_dstar = node.dstar_args is not None
1046 opcode = callfunc_opcode_info[have_star, have_dstar]
1047 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001048
Jeremy Hylton2afff322001-08-27 21:51:52 +00001049 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001050 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001051 if node.dest:
1052 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001053 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001054 if node.dest:
1055 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001056 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001057 if node.dest:
1058 self.emit('ROT_TWO')
1059 self.emit('PRINT_ITEM_TO')
1060 else:
1061 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001062 if node.dest and not newline:
1063 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001064
1065 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001066 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001067 if node.dest:
1068 self.emit('PRINT_NEWLINE_TO')
1069 else:
1070 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001071
1072 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001073 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001074 self.visit(node.value)
1075 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001076
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001077 def visitYield(self, node):
1078 self.set_lineno(node)
1079 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001080 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001081
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001082 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001083
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001084 def visitSlice(self, node, aug_flag=None):
1085 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001086 self.visit(node.expr)
1087 slice = 0
1088 if node.lower:
1089 self.visit(node.lower)
1090 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001091 if node.upper:
1092 self.visit(node.upper)
1093 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001094 if aug_flag:
1095 if slice == 0:
1096 self.emit('DUP_TOP')
1097 elif slice == 3:
1098 self.emit('DUP_TOPX', 3)
1099 else:
1100 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001101 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001102 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001103 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001104 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001105 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001106 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001107 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001108 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001109 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001110
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001111 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001112 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001113 for sub in node.subs:
1114 self.visit(sub)
1115 if len(node.subs) > 1:
1116 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001117 if aug_flag:
1118 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001119 if node.flags == 'OP_APPLY':
1120 self.emit('BINARY_SUBSCR')
1121 elif node.flags == 'OP_ASSIGN':
1122 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001123 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001124 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001125
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001126 # binary ops
1127
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001128 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001129 self.visit(node.left)
1130 self.visit(node.right)
1131 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001132
1133 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001134 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001135
1136 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001137 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001138
1139 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001140 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001141
1142 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001143 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001144
Jeremy Hylton94afe322001-08-29 18:14:39 +00001145 def visitFloorDiv(self, node):
1146 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1147
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001148 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001149 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001150
Jeremy Hylton126960b2000-02-14 21:33:10 +00001151 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001152 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001153
1154 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001155 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001156
1157 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001158 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001159
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001160 # unary ops
1161
1162 def unaryOp(self, node, op):
1163 self.visit(node.expr)
1164 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001165
Jeremy Hylton126960b2000-02-14 21:33:10 +00001166 def visitInvert(self, node):
1167 return self.unaryOp(node, 'UNARY_INVERT')
1168
Jeremy Hylton40245602000-02-08 21:15:48 +00001169 def visitUnarySub(self, node):
1170 return self.unaryOp(node, 'UNARY_NEGATIVE')
1171
1172 def visitUnaryAdd(self, node):
1173 return self.unaryOp(node, 'UNARY_POSITIVE')
1174
1175 def visitUnaryInvert(self, node):
1176 return self.unaryOp(node, 'UNARY_INVERT')
1177
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001178 def visitNot(self, node):
1179 return self.unaryOp(node, 'UNARY_NOT')
1180
Jeremy Hylton40245602000-02-08 21:15:48 +00001181 def visitBackquote(self, node):
1182 return self.unaryOp(node, 'UNARY_CONVERT')
1183
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001184 # bit ops
1185
Jeremy Hyltona5058122000-02-14 14:14:29 +00001186 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001187 self.visit(nodes[0])
1188 for node in nodes[1:]:
1189 self.visit(node)
1190 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001191
1192 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001193 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001194
1195 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001196 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001197
1198 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001199 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001200
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001201 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001202
Jeremy Hyltona5058122000-02-14 14:14:29 +00001203 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001204 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001205
Jeremy Hylton40245602000-02-08 21:15:48 +00001206 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001207 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001208 for elt in node.nodes:
1209 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001210 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001211
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001212 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001213 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001214 for elt in node.nodes:
1215 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001216 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001217
1218 def visitSliceobj(self, node):
1219 for child in node.nodes:
1220 self.visit(child)
1221 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001222
Jeremy Hyltona5058122000-02-14 14:14:29 +00001223 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001224 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001225 self.emit('BUILD_MAP', 0)
1226 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001227 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001228 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001229 self.visit(v)
1230 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001231 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001232
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001233class NestedScopeMixin:
1234 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001235 def initClass(self):
1236 self.__class__.NameFinder = LocalNameFinder
1237 self.__class__.FunctionGen = FunctionCodeGenerator
1238 self.__class__.ClassGen = ClassCodeGenerator
1239
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001240class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001241 __super_init = CodeGenerator.__init__
1242
1243 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001244
Jeremy Hylton37c93512001-09-17 18:03:55 +00001245 def __init__(self, tree):
1246 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001247 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001248 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001249 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001250
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001251 def get_module(self):
1252 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001253
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001254class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1255 __super_init = CodeGenerator.__init__
1256
1257 scopes = None
1258 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001259
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001260 def __init__(self, tree):
1261 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1262 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001263 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001264
1265 def get_module(self):
1266 return self
1267
1268class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1269
1270 __super_init = CodeGenerator.__init__
1271
1272 scopes = None
1273 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001274
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001275 def __init__(self, tree):
1276 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1277 self.__super_init()
1278 self.set_lineno(tree)
1279 walk(tree, self)
1280 self.emit('RETURN_VALUE')
1281
1282 def get_module(self):
1283 return self
Tim Peterse4418602002-02-16 07:34:19 +00001284
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001285 def visitDiscard(self, node):
1286 # XXX Discard means it's an expression. Perhaps this is a bad
1287 # name.
1288 self.visit(node.expr)
1289 self.emit('PRINT_EXPR')
1290
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001291class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001292 optimized = 1
1293 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001294
Jeremy Hylton37c93512001-09-17 18:03:55 +00001295 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001296 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001297 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001298 if isLambda:
1299 klass = FunctionCodeGenerator
1300 name = "<lambda.%d>" % klass.lambdaCount
1301 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001302 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001303 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001304
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001305 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001306 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1307 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001308 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001309 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001310
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001311 if not isLambda and func.doc:
1312 self.setDocstring(func.doc)
1313
Jeremy Hylton2afff322001-08-27 21:51:52 +00001314 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001315 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001316 if func.varargs:
1317 self.graph.setFlag(CO_VARARGS)
1318 if func.kwargs:
1319 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001320 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001321 if hasTupleArg:
1322 self.generateArgUnpack(func.argnames)
1323
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001324 def get_module(self):
1325 return self.module
1326
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001327 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001328 self.graph.startExitBlock()
1329 if not self.isLambda:
1330 self.emit('LOAD_CONST', None)
1331 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001332
1333 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001334 for i in range(len(args)):
1335 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001336 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001337 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001338 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001339
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001340 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001341 if VERSION > 1:
1342 self.emit('UNPACK_SEQUENCE', len(tup))
1343 else:
1344 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001345 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001346 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001347 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001348 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001349 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001350
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001351 unpackTuple = unpackSequence
1352
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001353class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001354 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001355 super_init = CodeGenerator.__init__ # call be other init
1356 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001357
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001358 __super_init = AbstractFunctionCode.__init__
1359
Jeremy Hylton37c93512001-09-17 18:03:55 +00001360 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001361 self.scopes = scopes
1362 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001363 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001364 self.graph.setFreeVars(self.scope.get_free_vars())
1365 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001366 if self.scope.generator is not None:
1367 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001368
Raymond Hettinger354433a2004-05-19 08:20:33 +00001369class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1370 CodeGenerator):
1371 super_init = CodeGenerator.__init__ # call be other init
1372 scopes = None
1373
1374 __super_init = AbstractFunctionCode.__init__
1375
1376 def __init__(self, gexp, scopes, class_name, mod):
1377 self.scopes = scopes
1378 self.scope = scopes[gexp]
1379 self.__super_init(gexp, scopes, 1, class_name, mod)
1380 self.graph.setFreeVars(self.scope.get_free_vars())
1381 self.graph.setCellVars(self.scope.get_cell_vars())
1382 self.graph.setFlag(CO_GENERATOR)
1383
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001384class AbstractClassCode:
1385
Jeremy Hylton37c93512001-09-17 18:03:55 +00001386 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001387 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001388 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001389 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001390 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001391 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001392 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001393 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001394 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001395 if klass.doc:
1396 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001397
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001398 def get_module(self):
1399 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001400
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001401 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001402 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001403 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001404 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001405
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001406class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001407 super_init = CodeGenerator.__init__
1408 scopes = None
1409
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001410 __super_init = AbstractClassCode.__init__
1411
Jeremy Hylton37c93512001-09-17 18:03:55 +00001412 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001413 self.scopes = scopes
1414 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001415 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001416 self.graph.setFreeVars(self.scope.get_free_vars())
1417 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001418 self.set_lineno(klass)
1419 self.emit("LOAD_GLOBAL", "__name__")
1420 self.storeName("__module__")
1421 if klass.doc:
1422 self.emit("LOAD_CONST", klass.doc)
1423 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001424
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001425def generateArgList(arglist):
1426 """Generate an arg list marking TupleArgs"""
1427 args = []
1428 extra = []
1429 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001430 for i in range(len(arglist)):
1431 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001432 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001433 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001434 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001435 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001436 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001437 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001438 else:
1439 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001440 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001441
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001442def findOp(node):
1443 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1444 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001445 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001446 return v.op
1447
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001448class OpFinder:
1449 def __init__(self):
1450 self.op = None
1451 def visitAssName(self, node):
1452 if self.op is None:
1453 self.op = node.flags
1454 elif self.op != node.flags:
1455 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001456 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001457 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001458
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001459class Delegator:
1460 """Base class to support delegation for augmented assignment nodes
1461
1462 To generator code for augmented assignments, we use the following
1463 wrapper classes. In visitAugAssign, the left-hand expression node
1464 is visited twice. The first time the visit uses the normal method
1465 for that node . The second time the visit uses a different method
1466 that generates the appropriate code to perform the assignment.
1467 These delegator classes wrap the original AST nodes in order to
1468 support the variant visit methods.
1469 """
1470 def __init__(self, obj):
1471 self.obj = obj
1472
1473 def __getattr__(self, attr):
1474 return getattr(self.obj, attr)
1475
1476class AugGetattr(Delegator):
1477 pass
1478
1479class AugName(Delegator):
1480 pass
1481
1482class AugSlice(Delegator):
1483 pass
1484
1485class AugSubscript(Delegator):
1486 pass
1487
1488wrapper = {
1489 ast.Getattr: AugGetattr,
1490 ast.Name: AugName,
1491 ast.Slice: AugSlice,
1492 ast.Subscript: AugSubscript,
1493 }
1494
1495def wrap_aug(node):
1496 return wrapper[node.__class__](node)
1497
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001498if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001499 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001500 compileFile(file)