blob: 61b9fe9bb6edc62375886b334cadfcd96e8a4e63 [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
10from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000011from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
Neal Norwitzeaed39f2006-03-03 19:12:58 +000012 CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
Eric Smith5d5c63f2008-03-19 02:11:30 +000013 CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton71ebc332001-08-30 20:25:55 +000014from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000015
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000016# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000017# Do we have Python 1.x or Python 2.x?
18try:
19 VERSION = sys.version_info[0]
20except AttributeError:
21 VERSION = 1
22
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000023callfunc_opcode_info = {
24 # (Have *args, Have **args) : opcode
25 (0,0) : "CALL_FUNCTION",
26 (1,0) : "CALL_FUNCTION_VAR",
27 (0,1) : "CALL_FUNCTION_KW",
28 (1,1) : "CALL_FUNCTION_VAR_KW",
29}
30
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000031LOOP = 1
32EXCEPT = 2
33TRY_FINALLY = 3
34END_FINALLY = 4
35
Jeremy Hylton9dca3642001-09-17 21:02:51 +000036def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000037 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000038 buf = f.read()
39 f.close()
40 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000041 try:
42 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000043 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000044 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000045 else:
46 f = open(filename + "c", "wb")
47 mod.dump(f)
48 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000049
Jeremy Hylton9dca3642001-09-17 21:02:51 +000050def compile(source, filename, mode, flags=None, dont_inherit=None):
51 """Replacement for builtin compile() function"""
52 if flags is not None or dont_inherit is not None:
53 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000054
Jeremy Hylton9dca3642001-09-17 21:02:51 +000055 if mode == "single":
56 gen = Interactive(source, filename)
57 elif mode == "exec":
58 gen = Module(source, filename)
59 elif mode == "eval":
60 gen = Expression(source, filename)
61 else:
62 raise ValueError("compile() 3rd arg must be 'exec' or "
63 "'eval' or 'single'")
64 gen.compile()
65 return gen.code
66
67class AbstractCompileMode:
68
69 mode = None # defined by subclass
70
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000071 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000072 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000073 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000074 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000075
Jeremy Hylton9dca3642001-09-17 21:02:51 +000076 def _get_tree(self):
77 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000078 misc.set_filename(self.filename, tree)
79 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000080 return tree
81
82 def compile(self):
83 pass # implemented by subclass
84
85 def getCode(self):
86 return self.code
87
88class Expression(AbstractCompileMode):
89
90 mode = "eval"
91
92 def compile(self):
93 tree = self._get_tree()
94 gen = ExpressionCodeGenerator(tree)
95 self.code = gen.getCode()
96
97class Interactive(AbstractCompileMode):
98
99 mode = "single"
100
101 def compile(self):
102 tree = self._get_tree()
103 gen = InteractiveCodeGenerator(tree)
104 self.code = gen.getCode()
105
106class Module(AbstractCompileMode):
107
108 mode = "exec"
109
110 def compile(self, display=0):
111 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000112 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000113 if display:
114 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000115 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000116 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000117
118 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000119 f.write(self.getPycHeader())
120 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000121
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000122 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000123
124 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000125 # compile.c uses marshal to write a long directly, with
126 # calling the interface that would also generate a 1-byte code
127 # to indicate the type of the value. simplest way to get the
128 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000129 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000130 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000131 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000132
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000133class LocalNameFinder:
134 """Find local names in scope"""
135 def __init__(self, names=()):
136 self.names = misc.Set()
137 self.globals = misc.Set()
138 for name in names:
139 self.names.add(name)
140
141 # XXX list comprehensions and for loops
142
143 def getLocals(self):
144 for elt in self.globals.elements():
145 if self.names.has_elt(elt):
146 self.names.remove(elt)
147 return self.names
148
149 def visitDict(self, node):
150 pass
151
152 def visitGlobal(self, node):
153 for name in node.names:
154 self.globals.add(name)
155
156 def visitFunction(self, node):
157 self.names.add(node.name)
158
159 def visitLambda(self, node):
160 pass
161
162 def visitImport(self, node):
163 for name, alias in node.names:
164 self.names.add(alias or name)
165
166 def visitFrom(self, node):
167 for name, alias in node.names:
168 self.names.add(alias or name)
169
170 def visitClass(self, node):
171 self.names.add(node.name)
172
173 def visitAssName(self, node):
174 self.names.add(node.name)
175
Jeremy Hylton2afff322001-08-27 21:51:52 +0000176def is_constant_false(node):
177 if isinstance(node, ast.Const):
178 if not node.value:
179 return 1
180 return 0
181
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000182class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000183 """Defines basic code generator for Python bytecode
184
185 This class is an abstract base class. Concrete subclasses must
186 define an __init__() that defines self.graph and then calls the
187 __init__() defined in this class.
188
189 The concrete class must also define the class attributes
190 NameFinder, FunctionGen, and ClassGen. These attributes can be
191 defined in the initClass() method, which is a hook for
192 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000193 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000194 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000195
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000196 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000197 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000198 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000199
Jeremy Hylton37c93512001-09-17 18:03:55 +0000200 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000201 if self.__initialized is None:
202 self.initClass()
203 self.__class__.__initialized = 1
204 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000205 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000206 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000207 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000208 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000209 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000210
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000211 # XXX set flags based on future features
212 futures = self.get_module().futures
213 for feature in futures:
214 if feature == "division":
215 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000216 self._div_op = "BINARY_TRUE_DIVIDE"
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000217 elif feature == "absolute_import":
218 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
219 elif feature == "with_statement":
220 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Eric Smith5d5c63f2008-03-19 02:11:30 +0000221 elif feature == "print_function":
222 self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000223
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000224 def initClass(self):
225 """This method is called once for each class"""
226
227 def checkClass(self):
228 """Verify that class is constructed correctly"""
229 try:
230 assert hasattr(self, 'graph')
231 assert getattr(self, 'NameFinder')
232 assert getattr(self, 'FunctionGen')
233 assert getattr(self, 'ClassGen')
234 except AssertionError, msg:
235 intro = "Bad class construction for %s" % self.__class__.__name__
236 raise AssertionError, intro
237
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000238 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000239 self.emit = self.graph.emit
240 self.newBlock = self.graph.newBlock
241 self.startBlock = self.graph.startBlock
242 self.nextBlock = self.graph.nextBlock
243 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000244
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000245 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000246 """Return a code object"""
247 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000248
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000249 def mangle(self, name):
250 if self.class_name is not None:
251 return misc.mangle(name, self.class_name)
252 else:
253 return name
254
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000255 def parseSymbols(self, tree):
256 s = symbols.SymbolVisitor()
257 walk(tree, s)
258 return s.scopes
259
260 def get_module(self):
261 raise RuntimeError, "should be implemented by subclasses"
262
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000263 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000264
Jeremy Hylton40245602000-02-08 21:15:48 +0000265 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000266 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000267
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000268 def storeName(self, name):
269 self._nameOp('STORE', name)
270
271 def loadName(self, name):
272 self._nameOp('LOAD', name)
273
274 def delName(self, name):
275 self._nameOp('DELETE', name)
276
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000277 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000278 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000279 scope = self.scope.check_name(name)
280 if scope == SC_LOCAL:
281 if not self.optimized:
282 self.emit(prefix + '_NAME', name)
283 else:
284 self.emit(prefix + '_FAST', name)
285 elif scope == SC_GLOBAL:
286 if not self.optimized:
287 self.emit(prefix + '_NAME', name)
288 else:
289 self.emit(prefix + '_GLOBAL', name)
290 elif scope == SC_FREE or scope == SC_CELL:
291 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000292 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000293 raise RuntimeError, "unsupported scope for var %s: %d" % \
294 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000295
Jeremy Hylton13d70942001-04-12 21:04:43 +0000296 def _implicitNameOp(self, prefix, name):
297 """Emit name ops for names generated implicitly by for loops
298
299 The interpreter generates names that start with a period or
300 dollar sign. The symbol table ignores these names because
301 they aren't present in the program text.
302 """
303 if self.optimized:
304 self.emit(prefix + '_FAST', name)
305 else:
306 self.emit(prefix + '_NAME', name)
307
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000308 # The set_lineno() function and the explicit emit() calls for
309 # SET_LINENO below are only used to generate the line number table.
310 # As of Python 2.3, the interpreter does not have a SET_LINENO
311 # instruction. pyassem treats SET_LINENO opcodes as a special case.
312
313 def set_lineno(self, node, force=False):
314 """Emit SET_LINENO if necessary.
315
316 The instruction is considered necessary if the node has a
317 lineno attribute and it is different than the last lineno
318 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000319
320 Returns true if SET_LINENO was emitted.
321
322 There are no rules for when an AST node should have a lineno
323 attribute. The transformer and AST code need to be reviewed
324 and a consistent policy implemented and documented. Until
325 then, this method works around missing line numbers.
326 """
327 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000328 if lineno is not None and (lineno != self.last_lineno
329 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000330 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000331 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000332 return True
333 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000334
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000335 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000336 # code objects. They use class attributes to determine what
337 # specialized code generators to use.
338
339 NameFinder = LocalNameFinder
340 FunctionGen = None
341 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000342
343 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000344 self.scopes = self.parseSymbols(node)
345 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000346 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000347 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000348 self.emit('LOAD_CONST', node.doc)
349 self.storeName('__doc__')
350 lnf = walk(node.node, self.NameFinder(), verbose=0)
351 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000352 self.visit(node.node)
353 self.emit('LOAD_CONST', None)
354 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000355
Barry Warsaw52acb492001-12-21 20:04:22 +0000356 def visitExpression(self, node):
357 self.set_lineno(node)
358 self.scopes = self.parseSymbols(node)
359 self.scope = self.scopes[node]
360 self.visit(node.node)
361 self.emit('RETURN_VALUE')
362
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000363 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000364 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000365 if node.doc:
366 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000367 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000368
369 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000370 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000371
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000372 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000373 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000374 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000375 self.visit(decorator)
376 ndecorators = len(node.decorators.nodes)
377 else:
378 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000379
Jeremy Hylton37c93512001-09-17 18:03:55 +0000380 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000381 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000382 walk(node.code, gen)
383 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000384 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000385 for default in node.defaults:
386 self.visit(default)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000387 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000388 for i in range(ndecorators):
389 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000390
391 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000392 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000393 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000394 walk(node.code, gen)
395 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000396 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000397 self.emit('LOAD_CONST', node.name)
398 for base in node.bases:
399 self.visit(base)
400 self.emit('BUILD_TUPLE', len(node.bases))
Neil Schemenauer06ded092006-08-04 16:20:30 +0000401 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000402 self.emit('CALL_FUNCTION', 0)
403 self.emit('BUILD_CLASS')
404 self.storeName(node.name)
405
406 # The rest are standard visitor methods
407
408 # The next few implement control-flow statements
409
410 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000411 end = self.newBlock()
412 numtests = len(node.tests)
413 for i in range(numtests):
414 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000415 if is_constant_false(test):
416 # XXX will need to check generator stuff here
417 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000418 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000419 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000420 nextTest = self.newBlock()
421 self.emit('JUMP_IF_FALSE', nextTest)
422 self.nextBlock()
423 self.emit('POP_TOP')
424 self.visit(suite)
425 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000426 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000427 self.emit('POP_TOP')
428 if node.else_:
429 self.visit(node.else_)
430 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000431
432 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000433 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000434
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000435 loop = self.newBlock()
436 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000437
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000438 after = self.newBlock()
439 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000440
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000441 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000442 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000444 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000445 self.visit(node.test)
446 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000447
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000448 self.nextBlock()
449 self.emit('POP_TOP')
450 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
454 self.emit('POP_TOP')
455 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000456 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 if node.else_:
458 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000459 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000460
461 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000462 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000463 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000465 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000466
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000467 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000468 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000469 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000470 self.emit('GET_ITER')
471
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000472 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000473 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000474 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475 self.visit(node.assign)
476 self.visit(node.body)
477 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000478 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000479 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000480 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481 if node.else_:
482 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000483 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000484
485 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000486 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000487 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000488 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000489 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000490 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000491
492 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000493 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000494 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000495 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000496 kind, block = self.setups.top()
497 if kind == LOOP:
498 self.set_lineno(node)
499 self.emit('JUMP_ABSOLUTE', block)
500 self.nextBlock()
501 elif kind == EXCEPT or kind == TRY_FINALLY:
502 self.set_lineno(node)
503 # find the block that starts the loop
504 top = len(self.setups)
505 while top > 0:
506 top = top - 1
507 kind, loop_block = self.setups[top]
508 if kind == LOOP:
509 break
510 if kind != LOOP:
511 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000512 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000513 self.emit('CONTINUE_LOOP', loop_block)
514 self.nextBlock()
515 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000516 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000517 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000518
519 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000520 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000521 for child in node.nodes[:-1]:
522 self.visit(child)
523 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000524 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000525 self.emit('POP_TOP')
526 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000527 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000528
529 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000530 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000531
532 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000533 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000534
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000535 def visitIfExp(self, node):
536 endblock = self.newBlock()
537 elseblock = self.newBlock()
538 self.visit(node.test)
539 self.emit('JUMP_IF_FALSE', elseblock)
540 self.emit('POP_TOP')
541 self.visit(node.then)
542 self.emit('JUMP_FORWARD', endblock)
543 self.nextBlock(elseblock)
544 self.emit('POP_TOP')
545 self.visit(node.else_)
546 self.nextBlock(endblock)
547
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000548 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000549 self.visit(node.expr)
550 cleanup = self.newBlock()
551 for op, code in node.ops[:-1]:
552 self.visit(code)
553 self.emit('DUP_TOP')
554 self.emit('ROT_THREE')
555 self.emit('COMPARE_OP', op)
556 self.emit('JUMP_IF_FALSE', cleanup)
557 self.nextBlock()
558 self.emit('POP_TOP')
559 # now do the last comparison
560 if node.ops:
561 op, code = node.ops[-1]
562 self.visit(code)
563 self.emit('COMPARE_OP', op)
564 if len(node.ops) > 1:
565 end = self.newBlock()
566 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000567 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000568 self.emit('ROT_TWO')
569 self.emit('POP_TOP')
570 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000571
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000572 # list comprehensions
573 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000574
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000575 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000576 self.set_lineno(node)
577 # setup list
Georg Brandl5addf702006-10-29 08:53:06 +0000578 tmpname = "$list%d" % self.__list_count
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000579 self.__list_count = self.__list_count + 1
580 self.emit('BUILD_LIST', 0)
581 self.emit('DUP_TOP')
Georg Brandl5addf702006-10-29 08:53:06 +0000582 self._implicitNameOp('STORE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000583
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000584 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000585 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000586 start, anchor = self.visit(for_)
587 cont = None
588 for if_ in for_.ifs:
589 if cont is None:
590 cont = self.newBlock()
591 self.visit(if_, cont)
592 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000593
Georg Brandl5addf702006-10-29 08:53:06 +0000594 self._implicitNameOp('LOAD', tmpname)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000595 self.visit(node.expr)
Georg Brandlfe9c71b2006-10-29 09:01:01 +0000596 self.emit('LIST_APPEND')
Tim Peterse0c446b2001-10-18 21:57:37 +0000597
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000598 for start, cont, anchor in stack:
599 if cont:
600 skip_one = self.newBlock()
601 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000602 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000603 self.emit('POP_TOP')
604 self.nextBlock(skip_one)
605 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000606 self.startBlock(anchor)
Georg Brandl5addf702006-10-29 08:53:06 +0000607 self._implicitNameOp('DELETE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000608
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000609 self.__list_count = self.__list_count - 1
610
611 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000612 start = self.newBlock()
613 anchor = self.newBlock()
614
615 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000616 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000618 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000619 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000620 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000621 self.visit(node.assign)
622 return start, anchor
623
624 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000625 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000626 self.visit(node.test)
627 self.emit('JUMP_IF_FALSE', branch)
628 self.newBlock()
629 self.emit('POP_TOP')
630
Neil Schemenauer06ded092006-08-04 16:20:30 +0000631 def _makeClosure(self, gen, args):
632 frees = gen.scope.get_free_vars()
633 if frees:
634 for name in frees:
635 self.emit('LOAD_CLOSURE', name)
636 self.emit('BUILD_TUPLE', len(frees))
637 self.emit('LOAD_CONST', gen)
638 self.emit('MAKE_CLOSURE', args)
639 else:
640 self.emit('LOAD_CONST', gen)
641 self.emit('MAKE_FUNCTION', args)
642
Raymond Hettinger354433a2004-05-19 08:20:33 +0000643 def visitGenExpr(self, node):
644 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
645 self.get_module())
646 walk(node.code, gen)
647 gen.finish()
648 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000649 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000650 # precomputation of outmost iterable
651 self.visit(node.code.quals[0].iter)
652 self.emit('GET_ITER')
653 self.emit('CALL_FUNCTION', 1)
654
655 def visitGenExprInner(self, node):
656 self.set_lineno(node)
657 # setup list
658
659 stack = []
660 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000661 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000662 cont = None
663 for if_ in for_.ifs:
664 if cont is None:
665 cont = self.newBlock()
666 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000667 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000668
669 self.visit(node.expr)
670 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000671 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000673 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000674 if cont:
675 skip_one = self.newBlock()
676 self.emit('JUMP_FORWARD', skip_one)
677 self.startBlock(cont)
678 self.emit('POP_TOP')
679 self.nextBlock(skip_one)
680 self.emit('JUMP_ABSOLUTE', start)
681 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000682 self.emit('POP_BLOCK')
683 self.setups.pop()
684 self.startBlock(end)
685
Raymond Hettinger354433a2004-05-19 08:20:33 +0000686 self.emit('LOAD_CONST', None)
687
688 def visitGenExprFor(self, node):
689 start = self.newBlock()
690 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000691 end = self.newBlock()
692
693 self.setups.push((LOOP, start))
694 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000695
Raymond Hettinger354433a2004-05-19 08:20:33 +0000696 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000697 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000698 else:
699 self.visit(node.iter)
700 self.emit('GET_ITER')
701
702 self.nextBlock(start)
703 self.set_lineno(node, force=True)
704 self.emit('FOR_ITER', anchor)
705 self.nextBlock()
706 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000707 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000708
709 def visitGenExprIf(self, node, branch):
710 self.set_lineno(node, force=True)
711 self.visit(node.test)
712 self.emit('JUMP_IF_FALSE', branch)
713 self.newBlock()
714 self.emit('POP_TOP')
715
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000716 # exception related
717
718 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000719 # XXX would be interesting to implement this via a
720 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000721 if __debug__:
722 end = self.newBlock()
723 self.set_lineno(node)
724 # XXX AssertionError appears to be special case -- it is always
725 # loaded as a global even if there is a local name. I guess this
726 # is a sort of renaming op.
727 self.nextBlock()
728 self.visit(node.test)
729 self.emit('JUMP_IF_TRUE', end)
730 self.nextBlock()
731 self.emit('POP_TOP')
732 self.emit('LOAD_GLOBAL', 'AssertionError')
733 if node.fail:
734 self.visit(node.fail)
735 self.emit('RAISE_VARARGS', 2)
736 else:
737 self.emit('RAISE_VARARGS', 1)
738 self.nextBlock(end)
739 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000740
741 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000742 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000743 n = 0
744 if node.expr1:
745 self.visit(node.expr1)
746 n = n + 1
747 if node.expr2:
748 self.visit(node.expr2)
749 n = n + 1
750 if node.expr3:
751 self.visit(node.expr3)
752 n = n + 1
753 self.emit('RAISE_VARARGS', n)
754
755 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000756 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000757 handlers = self.newBlock()
758 end = self.newBlock()
759 if node.else_:
760 lElse = self.newBlock()
761 else:
762 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000763 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000764 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000765 self.nextBlock(body)
766 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000767 self.visit(node.body)
768 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000769 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000770 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000771 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000772
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000773 last = len(node.handlers) - 1
774 for i in range(len(node.handlers)):
775 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000776 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000777 if expr:
778 self.emit('DUP_TOP')
779 self.visit(expr)
780 self.emit('COMPARE_OP', 'exception match')
781 next = self.newBlock()
782 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000783 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000784 self.emit('POP_TOP')
785 self.emit('POP_TOP')
786 if target:
787 self.visit(target)
788 else:
789 self.emit('POP_TOP')
790 self.emit('POP_TOP')
791 self.visit(body)
792 self.emit('JUMP_FORWARD', end)
793 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000794 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000795 else:
796 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000797 if expr: # XXX
798 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000799 self.emit('END_FINALLY')
800 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000801 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000802 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000803 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000804
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000806 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000807 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000808 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000810 self.nextBlock(body)
811 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000812 self.visit(node.body)
813 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000814 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000815 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000816 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000817 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000818 self.visit(node.final)
819 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000820 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000821
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000822 __with_count = 0
823
824 def visitWith(self, node):
825 body = self.newBlock()
826 final = self.newBlock()
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000827 valuevar = "$value%d" % self.__with_count
828 self.__with_count += 1
829 self.set_lineno(node)
830 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000831 self.emit('DUP_TOP')
832 self.emit('LOAD_ATTR', '__exit__')
Nick Coghlan7af53be2008-03-07 14:13:28 +0000833 self.emit('ROT_TWO')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000834 self.emit('LOAD_ATTR', '__enter__')
835 self.emit('CALL_FUNCTION', 0)
836 if node.vars is None:
837 self.emit('POP_TOP')
838 else:
839 self._implicitNameOp('STORE', valuevar)
840 self.emit('SETUP_FINALLY', final)
841 self.nextBlock(body)
842 self.setups.push((TRY_FINALLY, body))
843 if node.vars is not None:
844 self._implicitNameOp('LOAD', valuevar)
845 self._implicitNameOp('DELETE', valuevar)
846 self.visit(node.vars)
847 self.visit(node.body)
848 self.emit('POP_BLOCK')
849 self.setups.pop()
850 self.emit('LOAD_CONST', None)
851 self.nextBlock(final)
852 self.setups.push((END_FINALLY, final))
853 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000854 self.emit('END_FINALLY')
855 self.setups.pop()
856 self.__with_count -= 1
857
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000858 # misc
859
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000860 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000861 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000862 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000863 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000864
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000865 def visitConst(self, node):
866 self.emit('LOAD_CONST', node.value)
867
868 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000869 self.emit('LOAD_CONST', node.name)
870 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000871
872 def visitGlobal(self, node):
873 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000874 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000875
876 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000877 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000878 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000879
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000880 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000881 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000882
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000883 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000884 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000885 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000886 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000887 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000888 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000889 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000890 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000891 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000892 if alias:
893 self._resolveDots(name)
894 self.storeName(alias)
895 else:
896 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000897
898 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000899 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000900 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000901 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000902 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000903 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000904 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000905 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000906 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000907 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000908 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000909 if VERSION > 1:
910 if name == '*':
911 self.namespace = 0
912 self.emit('IMPORT_STAR')
913 # There can only be one name w/ from ... import *
914 assert len(node.names) == 1
915 return
916 else:
917 self.emit('IMPORT_FROM', name)
918 self._resolveDots(name)
919 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000920 else:
921 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000922 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000923
Jeremy Hylton20516082000-09-01 20:33:26 +0000924 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000925 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000926 if len(elts) == 1:
927 return
928 for elt in elts[1:]:
929 self.emit('LOAD_ATTR', elt)
930
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000931 def visitGetattr(self, node):
932 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000933 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000934
935 # next five implement assignments
936
937 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000938 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000939 self.visit(node.expr)
940 dups = len(node.nodes) - 1
941 for i in range(len(node.nodes)):
942 elt = node.nodes[i]
943 if i < dups:
944 self.emit('DUP_TOP')
945 if isinstance(elt, ast.Node):
946 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000947
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000948 def visitAssName(self, node):
949 if node.flags == 'OP_ASSIGN':
950 self.storeName(node.name)
951 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000952 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953 self.delName(node.name)
954 else:
955 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000956
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000957 def visitAssAttr(self, node):
958 self.visit(node.expr)
959 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000960 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000961 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000962 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000963 else:
964 print "warning: unexpected flags:", node.flags
965 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000966
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000967 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000968 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000969 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000970 for child in node.nodes:
971 self.visit(child)
972
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000973 if VERSION > 1:
974 visitAssTuple = _visitAssSequence
975 visitAssList = _visitAssSequence
976 else:
977 def visitAssTuple(self, node):
978 self._visitAssSequence(node, 'UNPACK_TUPLE')
979
980 def visitAssList(self, node):
981 self._visitAssSequence(node, 'UNPACK_LIST')
982
983 # augmented assignment
984
985 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000986 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000987 aug_node = wrap_aug(node.node)
988 self.visit(aug_node, "load")
989 self.visit(node.expr)
990 self.emit(self._augmented_opcode[node.op])
991 self.visit(aug_node, "store")
992
993 _augmented_opcode = {
994 '+=' : 'INPLACE_ADD',
995 '-=' : 'INPLACE_SUBTRACT',
996 '*=' : 'INPLACE_MULTIPLY',
997 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000998 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000999 '%=' : 'INPLACE_MODULO',
1000 '**=': 'INPLACE_POWER',
1001 '>>=': 'INPLACE_RSHIFT',
1002 '<<=': 'INPLACE_LSHIFT',
1003 '&=' : 'INPLACE_AND',
1004 '^=' : 'INPLACE_XOR',
1005 '|=' : 'INPLACE_OR',
1006 }
1007
1008 def visitAugName(self, node, mode):
1009 if mode == "load":
1010 self.loadName(node.name)
1011 elif mode == "store":
1012 self.storeName(node.name)
1013
1014 def visitAugGetattr(self, node, mode):
1015 if mode == "load":
1016 self.visit(node.expr)
1017 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001018 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001019 elif mode == "store":
1020 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001021 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001022
1023 def visitAugSlice(self, node, mode):
1024 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001025 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001026 elif mode == "store":
1027 slice = 0
1028 if node.lower:
1029 slice = slice | 1
1030 if node.upper:
1031 slice = slice | 2
1032 if slice == 0:
1033 self.emit('ROT_TWO')
1034 elif slice == 3:
1035 self.emit('ROT_FOUR')
1036 else:
1037 self.emit('ROT_THREE')
1038 self.emit('STORE_SLICE+%d' % slice)
1039
1040 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001041 if mode == "load":
1042 self.visitSubscript(node, 1)
1043 elif mode == "store":
1044 self.emit('ROT_THREE')
1045 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001046
1047 def visitExec(self, node):
1048 self.visit(node.expr)
1049 if node.locals is None:
1050 self.emit('LOAD_CONST', None)
1051 else:
1052 self.visit(node.locals)
1053 if node.globals is None:
1054 self.emit('DUP_TOP')
1055 else:
1056 self.visit(node.globals)
1057 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001058
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001059 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001060 pos = 0
1061 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001062 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001063 self.visit(node.node)
1064 for arg in node.args:
1065 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001066 if isinstance(arg, ast.Keyword):
1067 kw = kw + 1
1068 else:
1069 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001070 if node.star_args is not None:
1071 self.visit(node.star_args)
1072 if node.dstar_args is not None:
1073 self.visit(node.dstar_args)
1074 have_star = node.star_args is not None
1075 have_dstar = node.dstar_args is not None
1076 opcode = callfunc_opcode_info[have_star, have_dstar]
1077 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001078
Jeremy Hylton2afff322001-08-27 21:51:52 +00001079 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001080 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001081 if node.dest:
1082 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001083 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001084 if node.dest:
1085 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001086 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001087 if node.dest:
1088 self.emit('ROT_TWO')
1089 self.emit('PRINT_ITEM_TO')
1090 else:
1091 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001092 if node.dest and not newline:
1093 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001094
1095 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001096 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001097 if node.dest:
1098 self.emit('PRINT_NEWLINE_TO')
1099 else:
1100 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001101
1102 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001103 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001104 self.visit(node.value)
1105 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001106
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001107 def visitYield(self, node):
1108 self.set_lineno(node)
1109 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001110 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001111
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001112 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001113
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001114 def visitSlice(self, node, aug_flag=None):
1115 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001116 self.visit(node.expr)
1117 slice = 0
1118 if node.lower:
1119 self.visit(node.lower)
1120 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001121 if node.upper:
1122 self.visit(node.upper)
1123 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001124 if aug_flag:
1125 if slice == 0:
1126 self.emit('DUP_TOP')
1127 elif slice == 3:
1128 self.emit('DUP_TOPX', 3)
1129 else:
1130 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001131 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001132 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001133 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001134 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001135 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001136 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001137 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001138 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001139 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001140
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001141 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001142 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001143 for sub in node.subs:
1144 self.visit(sub)
1145 if len(node.subs) > 1:
1146 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001147 if aug_flag:
1148 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001149 if node.flags == 'OP_APPLY':
1150 self.emit('BINARY_SUBSCR')
1151 elif node.flags == 'OP_ASSIGN':
1152 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001153 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001154 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001155
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001156 # binary ops
1157
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001158 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001159 self.visit(node.left)
1160 self.visit(node.right)
1161 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001162
1163 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001164 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001165
1166 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001167 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001168
1169 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001170 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001171
1172 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001173 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001174
Jeremy Hylton94afe322001-08-29 18:14:39 +00001175 def visitFloorDiv(self, node):
1176 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1177
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001178 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001179 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001180
Jeremy Hylton126960b2000-02-14 21:33:10 +00001181 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001182 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001183
1184 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001185 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001186
1187 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001188 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001189
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001190 # unary ops
1191
1192 def unaryOp(self, node, op):
1193 self.visit(node.expr)
1194 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001195
Jeremy Hylton126960b2000-02-14 21:33:10 +00001196 def visitInvert(self, node):
1197 return self.unaryOp(node, 'UNARY_INVERT')
1198
Jeremy Hylton40245602000-02-08 21:15:48 +00001199 def visitUnarySub(self, node):
1200 return self.unaryOp(node, 'UNARY_NEGATIVE')
1201
1202 def visitUnaryAdd(self, node):
1203 return self.unaryOp(node, 'UNARY_POSITIVE')
1204
1205 def visitUnaryInvert(self, node):
1206 return self.unaryOp(node, 'UNARY_INVERT')
1207
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001208 def visitNot(self, node):
1209 return self.unaryOp(node, 'UNARY_NOT')
1210
Jeremy Hylton40245602000-02-08 21:15:48 +00001211 def visitBackquote(self, node):
1212 return self.unaryOp(node, 'UNARY_CONVERT')
1213
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001214 # bit ops
1215
Jeremy Hyltona5058122000-02-14 14:14:29 +00001216 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001217 self.visit(nodes[0])
1218 for node in nodes[1:]:
1219 self.visit(node)
1220 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001221
1222 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001223 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001224
1225 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001226 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001227
1228 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001229 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001230
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001231 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001232
Jeremy Hyltona5058122000-02-14 14:14:29 +00001233 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001234 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001235
Jeremy Hylton40245602000-02-08 21:15:48 +00001236 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001237 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001238 for elt in node.nodes:
1239 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001240 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001241
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001242 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001243 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001244 for elt in node.nodes:
1245 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001247
1248 def visitSliceobj(self, node):
1249 for child in node.nodes:
1250 self.visit(child)
1251 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001252
Jeremy Hyltona5058122000-02-14 14:14:29 +00001253 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001254 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001255 self.emit('BUILD_MAP', 0)
1256 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001257 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001258 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001259 self.visit(v)
1260 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001261 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001262
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001263class NestedScopeMixin:
1264 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001265 def initClass(self):
1266 self.__class__.NameFinder = LocalNameFinder
1267 self.__class__.FunctionGen = FunctionCodeGenerator
1268 self.__class__.ClassGen = ClassCodeGenerator
1269
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001270class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001271 __super_init = CodeGenerator.__init__
1272
1273 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001274
Jeremy Hylton37c93512001-09-17 18:03:55 +00001275 def __init__(self, tree):
1276 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001277 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001278 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001279 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001280
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001281 def get_module(self):
1282 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001283
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001284class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1285 __super_init = CodeGenerator.__init__
1286
1287 scopes = None
1288 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001289
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001290 def __init__(self, tree):
1291 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1292 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001293 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001294
1295 def get_module(self):
1296 return self
1297
1298class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1299
1300 __super_init = CodeGenerator.__init__
1301
1302 scopes = None
1303 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001304
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001305 def __init__(self, tree):
1306 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1307 self.__super_init()
1308 self.set_lineno(tree)
1309 walk(tree, self)
1310 self.emit('RETURN_VALUE')
1311
1312 def get_module(self):
1313 return self
Tim Peterse4418602002-02-16 07:34:19 +00001314
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001315 def visitDiscard(self, node):
1316 # XXX Discard means it's an expression. Perhaps this is a bad
1317 # name.
1318 self.visit(node.expr)
1319 self.emit('PRINT_EXPR')
1320
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001321class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001322 optimized = 1
1323 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001324
Jeremy Hylton37c93512001-09-17 18:03:55 +00001325 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001326 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001327 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001328 if isLambda:
1329 klass = FunctionCodeGenerator
1330 name = "<lambda.%d>" % klass.lambdaCount
1331 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001332 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001333 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001334
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001335 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001336 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1337 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001338 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001339 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001340
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001341 if not isLambda and func.doc:
1342 self.setDocstring(func.doc)
1343
Jeremy Hylton2afff322001-08-27 21:51:52 +00001344 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001345 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001346 if func.varargs:
1347 self.graph.setFlag(CO_VARARGS)
1348 if func.kwargs:
1349 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001350 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001351 if hasTupleArg:
1352 self.generateArgUnpack(func.argnames)
1353
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001354 def get_module(self):
1355 return self.module
1356
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001357 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001358 self.graph.startExitBlock()
1359 if not self.isLambda:
1360 self.emit('LOAD_CONST', None)
1361 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001362
1363 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001364 for i in range(len(args)):
1365 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001366 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001367 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001368 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001369
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001370 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001371 if VERSION > 1:
1372 self.emit('UNPACK_SEQUENCE', len(tup))
1373 else:
1374 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001375 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001376 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001377 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001378 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001379 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001380
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001381 unpackTuple = unpackSequence
1382
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001383class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001384 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001385 super_init = CodeGenerator.__init__ # call be other init
1386 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001387
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001388 __super_init = AbstractFunctionCode.__init__
1389
Jeremy Hylton37c93512001-09-17 18:03:55 +00001390 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001391 self.scopes = scopes
1392 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001393 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001394 self.graph.setFreeVars(self.scope.get_free_vars())
1395 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001396 if self.scope.generator is not None:
1397 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001398
Raymond Hettinger354433a2004-05-19 08:20:33 +00001399class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1400 CodeGenerator):
1401 super_init = CodeGenerator.__init__ # call be other init
1402 scopes = None
1403
1404 __super_init = AbstractFunctionCode.__init__
1405
1406 def __init__(self, gexp, scopes, class_name, mod):
1407 self.scopes = scopes
1408 self.scope = scopes[gexp]
1409 self.__super_init(gexp, scopes, 1, class_name, mod)
1410 self.graph.setFreeVars(self.scope.get_free_vars())
1411 self.graph.setCellVars(self.scope.get_cell_vars())
1412 self.graph.setFlag(CO_GENERATOR)
1413
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001414class AbstractClassCode:
1415
Jeremy Hylton37c93512001-09-17 18:03:55 +00001416 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001417 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001418 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001419 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001420 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001421 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001422 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001423 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001424 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001425 if klass.doc:
1426 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001427
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001428 def get_module(self):
1429 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001430
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001431 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001432 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001433 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001434 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001435
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001436class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001437 super_init = CodeGenerator.__init__
1438 scopes = None
1439
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001440 __super_init = AbstractClassCode.__init__
1441
Jeremy Hylton37c93512001-09-17 18:03:55 +00001442 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001443 self.scopes = scopes
1444 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001445 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001446 self.graph.setFreeVars(self.scope.get_free_vars())
1447 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001448 self.set_lineno(klass)
1449 self.emit("LOAD_GLOBAL", "__name__")
1450 self.storeName("__module__")
1451 if klass.doc:
1452 self.emit("LOAD_CONST", klass.doc)
1453 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001454
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001455def generateArgList(arglist):
1456 """Generate an arg list marking TupleArgs"""
1457 args = []
1458 extra = []
1459 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001460 for i in range(len(arglist)):
1461 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001462 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001463 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001464 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001465 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001466 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001467 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001468 else:
1469 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001470 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001471
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001472def findOp(node):
1473 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1474 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001475 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001476 return v.op
1477
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001478class OpFinder:
1479 def __init__(self):
1480 self.op = None
1481 def visitAssName(self, node):
1482 if self.op is None:
1483 self.op = node.flags
1484 elif self.op != node.flags:
1485 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001486 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001487 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001488
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001489class Delegator:
1490 """Base class to support delegation for augmented assignment nodes
1491
1492 To generator code for augmented assignments, we use the following
1493 wrapper classes. In visitAugAssign, the left-hand expression node
1494 is visited twice. The first time the visit uses the normal method
1495 for that node . The second time the visit uses a different method
1496 that generates the appropriate code to perform the assignment.
1497 These delegator classes wrap the original AST nodes in order to
1498 support the variant visit methods.
1499 """
1500 def __init__(self, obj):
1501 self.obj = obj
1502
1503 def __getattr__(self, attr):
1504 return getattr(self.obj, attr)
1505
1506class AugGetattr(Delegator):
1507 pass
1508
1509class AugName(Delegator):
1510 pass
1511
1512class AugSlice(Delegator):
1513 pass
1514
1515class AugSubscript(Delegator):
1516 pass
1517
1518wrapper = {
1519 ast.Getattr: AugGetattr,
1520 ast.Name: AugName,
1521 ast.Slice: AugSlice,
1522 ast.Subscript: AugSubscript,
1523 }
1524
1525def wrap_aug(node):
1526 return wrapper[node.__class__](node)
1527
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001528if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001529 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001530 compileFile(file)