blob: db2251e6f879afe37572b773f0e3d99692820846 [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,
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000013 CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT)
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 Hylton53187f32000-02-08 19:01:29 +0000209
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000210 # XXX set flags based on future features
211 futures = self.get_module().futures
212 for feature in futures:
213 if feature == "division":
214 self.graph.setFlag(CO_FUTURE_DIVISION)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000215 elif feature == "absolute_import":
216 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
217 elif feature == "with_statement":
218 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000219
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000220 def initClass(self):
221 """This method is called once for each class"""
222
223 def checkClass(self):
224 """Verify that class is constructed correctly"""
225 try:
226 assert hasattr(self, 'graph')
227 assert getattr(self, 'NameFinder')
228 assert getattr(self, 'FunctionGen')
229 assert getattr(self, 'ClassGen')
230 except AssertionError, msg:
231 intro = "Bad class construction for %s" % self.__class__.__name__
232 raise AssertionError, intro
233
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000234 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000235 self.emit = self.graph.emit
236 self.newBlock = self.graph.newBlock
237 self.startBlock = self.graph.startBlock
238 self.nextBlock = self.graph.nextBlock
239 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000240
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000241 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000242 """Return a code object"""
243 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000244
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000245 def mangle(self, name):
246 if self.class_name is not None:
247 return misc.mangle(name, self.class_name)
248 else:
249 return name
250
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000251 def parseSymbols(self, tree):
252 s = symbols.SymbolVisitor()
253 walk(tree, s)
254 return s.scopes
255
256 def get_module(self):
257 raise RuntimeError, "should be implemented by subclasses"
258
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000259 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000260
Jeremy Hylton40245602000-02-08 21:15:48 +0000261 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000262 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000263
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000264 def storeName(self, name):
265 self._nameOp('STORE', name)
266
267 def loadName(self, name):
268 self._nameOp('LOAD', name)
269
270 def delName(self, name):
271 self._nameOp('DELETE', name)
272
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000273 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000274 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000275 scope = self.scope.check_name(name)
276 if scope == SC_LOCAL:
277 if not self.optimized:
278 self.emit(prefix + '_NAME', name)
279 else:
280 self.emit(prefix + '_FAST', name)
281 elif scope == SC_GLOBAL:
282 if not self.optimized:
283 self.emit(prefix + '_NAME', name)
284 else:
285 self.emit(prefix + '_GLOBAL', name)
286 elif scope == SC_FREE or scope == SC_CELL:
287 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000288 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000289 raise RuntimeError, "unsupported scope for var %s: %d" % \
290 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000291
Jeremy Hylton13d70942001-04-12 21:04:43 +0000292 def _implicitNameOp(self, prefix, name):
293 """Emit name ops for names generated implicitly by for loops
294
295 The interpreter generates names that start with a period or
296 dollar sign. The symbol table ignores these names because
297 they aren't present in the program text.
298 """
299 if self.optimized:
300 self.emit(prefix + '_FAST', name)
301 else:
302 self.emit(prefix + '_NAME', name)
303
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000304 # The set_lineno() function and the explicit emit() calls for
305 # SET_LINENO below are only used to generate the line number table.
306 # As of Python 2.3, the interpreter does not have a SET_LINENO
307 # instruction. pyassem treats SET_LINENO opcodes as a special case.
308
309 def set_lineno(self, node, force=False):
310 """Emit SET_LINENO if necessary.
311
312 The instruction is considered necessary if the node has a
313 lineno attribute and it is different than the last lineno
314 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000315
316 Returns true if SET_LINENO was emitted.
317
318 There are no rules for when an AST node should have a lineno
319 attribute. The transformer and AST code need to be reviewed
320 and a consistent policy implemented and documented. Until
321 then, this method works around missing line numbers.
322 """
323 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000324 if lineno is not None and (lineno != self.last_lineno
325 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000326 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000327 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000328 return True
329 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000330
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000331 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000332 # code objects. They use class attributes to determine what
333 # specialized code generators to use.
334
335 NameFinder = LocalNameFinder
336 FunctionGen = None
337 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000338
339 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000340 self.scopes = self.parseSymbols(node)
341 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000342 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000343 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000344 self.emit('LOAD_CONST', node.doc)
345 self.storeName('__doc__')
346 lnf = walk(node.node, self.NameFinder(), verbose=0)
347 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000348 self.visit(node.node)
349 self.emit('LOAD_CONST', None)
350 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000351
Barry Warsaw52acb492001-12-21 20:04:22 +0000352 def visitExpression(self, node):
353 self.set_lineno(node)
354 self.scopes = self.parseSymbols(node)
355 self.scope = self.scopes[node]
356 self.visit(node.node)
357 self.emit('RETURN_VALUE')
358
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000359 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000360 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000361 if node.doc:
362 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000363 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000364
365 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000366 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000367
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000368 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000369 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000370 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000371 self.visit(decorator)
372 ndecorators = len(node.decorators.nodes)
373 else:
374 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000375
Jeremy Hylton37c93512001-09-17 18:03:55 +0000376 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000377 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000378 walk(node.code, gen)
379 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000380 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000381 for default in node.defaults:
382 self.visit(default)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000383 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000384 for i in range(ndecorators):
385 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000386
387 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000388 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000389 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000390 walk(node.code, gen)
391 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000392 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000393 self.emit('LOAD_CONST', node.name)
394 for base in node.bases:
395 self.visit(base)
396 self.emit('BUILD_TUPLE', len(node.bases))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000397 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000398 self.emit('CALL_FUNCTION', 0)
399 self.emit('BUILD_CLASS')
400 self.storeName(node.name)
401
402 # The rest are standard visitor methods
403
404 # The next few implement control-flow statements
405
406 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000407 end = self.newBlock()
408 numtests = len(node.tests)
409 for i in range(numtests):
410 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000411 if is_constant_false(test):
412 # XXX will need to check generator stuff here
413 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000414 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000415 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000416 nextTest = self.newBlock()
417 self.emit('JUMP_IF_FALSE', nextTest)
418 self.nextBlock()
419 self.emit('POP_TOP')
420 self.visit(suite)
421 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000422 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000423 self.emit('POP_TOP')
424 if node.else_:
425 self.visit(node.else_)
426 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000427
428 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000429 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000430
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000431 loop = self.newBlock()
432 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000433
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000434 after = self.newBlock()
435 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000436
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000437 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000438 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000439
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000440 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000441 self.visit(node.test)
442 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000444 self.nextBlock()
445 self.emit('POP_TOP')
446 self.visit(node.body)
447 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000448
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000449 self.startBlock(else_) # or just the POPs if not else clause
450 self.emit('POP_TOP')
451 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000452 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000453 if node.else_:
454 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000455 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000456
457 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000458 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000459 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000461 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000462
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000463 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000465 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000466 self.emit('GET_ITER')
467
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000468 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000469 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000470 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000471 self.visit(node.assign)
472 self.visit(node.body)
473 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000474 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000476 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000477 if node.else_:
478 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000479 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000480
481 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000482 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000483 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000484 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000485 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000486 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000487
488 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000489 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000490 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000491 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000492 kind, block = self.setups.top()
493 if kind == LOOP:
494 self.set_lineno(node)
495 self.emit('JUMP_ABSOLUTE', block)
496 self.nextBlock()
497 elif kind == EXCEPT or kind == TRY_FINALLY:
498 self.set_lineno(node)
499 # find the block that starts the loop
500 top = len(self.setups)
501 while top > 0:
502 top = top - 1
503 kind, loop_block = self.setups[top]
504 if kind == LOOP:
505 break
506 if kind != LOOP:
507 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000508 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000509 self.emit('CONTINUE_LOOP', loop_block)
510 self.nextBlock()
511 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000512 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000513 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000514
515 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000516 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000517 for child in node.nodes[:-1]:
518 self.visit(child)
519 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000520 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000521 self.emit('POP_TOP')
522 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000523 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000524
525 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000526 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000527
528 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000529 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000530
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000531 def visitIfExp(self, node):
532 endblock = self.newBlock()
533 elseblock = self.newBlock()
534 self.visit(node.test)
535 self.emit('JUMP_IF_FALSE', elseblock)
536 self.emit('POP_TOP')
537 self.visit(node.then)
538 self.emit('JUMP_FORWARD', endblock)
539 self.nextBlock(elseblock)
540 self.emit('POP_TOP')
541 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)
552 self.emit('JUMP_IF_FALSE', cleanup)
553 self.nextBlock()
554 self.emit('POP_TOP')
555 # now do the last comparison
556 if node.ops:
557 op, code = node.ops[-1]
558 self.visit(code)
559 self.emit('COMPARE_OP', op)
560 if len(node.ops) > 1:
561 end = self.newBlock()
562 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000563 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000564 self.emit('ROT_TWO')
565 self.emit('POP_TOP')
566 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000567
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000568 # list comprehensions
569 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000570
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000571 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000572 self.set_lineno(node)
573 # setup list
574 append = "$append%d" % self.__list_count
575 self.__list_count = self.__list_count + 1
576 self.emit('BUILD_LIST', 0)
577 self.emit('DUP_TOP')
578 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000579 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000580
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000581 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000582 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000583 start, anchor = self.visit(for_)
584 cont = None
585 for if_ in for_.ifs:
586 if cont is None:
587 cont = self.newBlock()
588 self.visit(if_, cont)
589 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000590
Jeremy Hylton13d70942001-04-12 21:04:43 +0000591 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000592 self.visit(node.expr)
593 self.emit('CALL_FUNCTION', 1)
594 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000595
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000596 for start, cont, anchor in stack:
597 if cont:
598 skip_one = self.newBlock()
599 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000600 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000601 self.emit('POP_TOP')
602 self.nextBlock(skip_one)
603 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000604 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000605 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000606
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000607 self.__list_count = self.__list_count - 1
608
609 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610 start = self.newBlock()
611 anchor = self.newBlock()
612
613 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000614 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000615 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000616 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000617 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000618 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000619 self.visit(node.assign)
620 return start, anchor
621
622 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000623 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000624 self.visit(node.test)
625 self.emit('JUMP_IF_FALSE', branch)
626 self.newBlock()
627 self.emit('POP_TOP')
628
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000629 def _makeClosure(self, gen, args):
630 frees = gen.scope.get_free_vars()
631 if frees:
632 for name in frees:
633 self.emit('LOAD_CLOSURE', name)
634 self.emit('BUILD_TUPLE', len(frees))
635 self.emit('LOAD_CONST', gen)
636 self.emit('MAKE_CLOSURE', args)
637 else:
638 self.emit('LOAD_CONST', gen)
639 self.emit('MAKE_FUNCTION', args)
640
Raymond Hettinger354433a2004-05-19 08:20:33 +0000641 def visitGenExpr(self, node):
642 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
643 self.get_module())
644 walk(node.code, gen)
645 gen.finish()
646 self.set_lineno(node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000647 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000648 # precomputation of outmost iterable
649 self.visit(node.code.quals[0].iter)
650 self.emit('GET_ITER')
651 self.emit('CALL_FUNCTION', 1)
652
653 def visitGenExprInner(self, node):
654 self.set_lineno(node)
655 # setup list
656
657 stack = []
658 for i, for_ in zip(range(len(node.quals)), node.quals):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000659 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000660 cont = None
661 for if_ in for_.ifs:
662 if cont is None:
663 cont = self.newBlock()
664 self.visit(if_, cont)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000665 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000666
667 self.visit(node.expr)
668 self.emit('YIELD_VALUE')
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000669 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000670
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000671 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672 if cont:
673 skip_one = self.newBlock()
674 self.emit('JUMP_FORWARD', skip_one)
675 self.startBlock(cont)
676 self.emit('POP_TOP')
677 self.nextBlock(skip_one)
678 self.emit('JUMP_ABSOLUTE', start)
679 self.startBlock(anchor)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000680 self.emit('POP_BLOCK')
681 self.setups.pop()
682 self.startBlock(end)
683
Raymond Hettinger354433a2004-05-19 08:20:33 +0000684 self.emit('LOAD_CONST', None)
685
686 def visitGenExprFor(self, node):
687 start = self.newBlock()
688 anchor = self.newBlock()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000689 end = self.newBlock()
690
691 self.setups.push((LOOP, start))
692 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000693
Raymond Hettinger354433a2004-05-19 08:20:33 +0000694 if node.is_outmost:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000695 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000696 else:
697 self.visit(node.iter)
698 self.emit('GET_ITER')
699
700 self.nextBlock(start)
701 self.set_lineno(node, force=True)
702 self.emit('FOR_ITER', anchor)
703 self.nextBlock()
704 self.visit(node.assign)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000705 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000706
707 def visitGenExprIf(self, node, branch):
708 self.set_lineno(node, force=True)
709 self.visit(node.test)
710 self.emit('JUMP_IF_FALSE', branch)
711 self.newBlock()
712 self.emit('POP_TOP')
713
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000714 # exception related
715
716 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000717 # XXX would be interesting to implement this via a
718 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000719 if __debug__:
720 end = self.newBlock()
721 self.set_lineno(node)
722 # XXX AssertionError appears to be special case -- it is always
723 # loaded as a global even if there is a local name. I guess this
724 # is a sort of renaming op.
725 self.nextBlock()
726 self.visit(node.test)
727 self.emit('JUMP_IF_TRUE', end)
728 self.nextBlock()
729 self.emit('POP_TOP')
730 self.emit('LOAD_GLOBAL', 'AssertionError')
731 if node.fail:
732 self.visit(node.fail)
733 self.emit('RAISE_VARARGS', 2)
734 else:
735 self.emit('RAISE_VARARGS', 1)
736 self.nextBlock(end)
737 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000738
739 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000740 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000741 n = 0
742 if node.expr1:
743 self.visit(node.expr1)
744 n = n + 1
745 if node.expr2:
746 self.visit(node.expr2)
747 n = n + 1
748 if node.expr3:
749 self.visit(node.expr3)
750 n = n + 1
751 self.emit('RAISE_VARARGS', n)
752
753 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000754 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000755 handlers = self.newBlock()
756 end = self.newBlock()
757 if node.else_:
758 lElse = self.newBlock()
759 else:
760 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000761 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000762 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000763 self.nextBlock(body)
764 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000765 self.visit(node.body)
766 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000767 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000768 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000769 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000770
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000771 last = len(node.handlers) - 1
772 for i in range(len(node.handlers)):
773 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000774 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 if expr:
776 self.emit('DUP_TOP')
777 self.visit(expr)
778 self.emit('COMPARE_OP', 'exception match')
779 next = self.newBlock()
780 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000781 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000782 self.emit('POP_TOP')
783 self.emit('POP_TOP')
784 if target:
785 self.visit(target)
786 else:
787 self.emit('POP_TOP')
788 self.emit('POP_TOP')
789 self.visit(body)
790 self.emit('JUMP_FORWARD', end)
791 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000792 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000793 else:
794 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000795 if expr: # XXX
796 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000797 self.emit('END_FINALLY')
798 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000799 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000801 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000802
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000804 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000806 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000807 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 self.nextBlock(body)
809 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000810 self.visit(node.body)
811 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000812 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000813 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000814 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000815 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000816 self.visit(node.final)
817 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000818 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000819
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000820 __with_count = 0
821
822 def visitWith(self, node):
823 body = self.newBlock()
824 final = self.newBlock()
825 exitvar = "$exit%d" % self.__with_count
826 valuevar = "$value%d" % self.__with_count
827 self.__with_count += 1
828 self.set_lineno(node)
829 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000830 self.emit('DUP_TOP')
831 self.emit('LOAD_ATTR', '__exit__')
832 self._implicitNameOp('STORE', exitvar)
833 self.emit('LOAD_ATTR', '__enter__')
834 self.emit('CALL_FUNCTION', 0)
835 if node.vars is None:
836 self.emit('POP_TOP')
837 else:
838 self._implicitNameOp('STORE', valuevar)
839 self.emit('SETUP_FINALLY', final)
840 self.nextBlock(body)
841 self.setups.push((TRY_FINALLY, body))
842 if node.vars is not None:
843 self._implicitNameOp('LOAD', valuevar)
844 self._implicitNameOp('DELETE', valuevar)
845 self.visit(node.vars)
846 self.visit(node.body)
847 self.emit('POP_BLOCK')
848 self.setups.pop()
849 self.emit('LOAD_CONST', None)
850 self.nextBlock(final)
851 self.setups.push((END_FINALLY, final))
852 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000853 self.emit('END_FINALLY')
854 self.setups.pop()
855 self.__with_count -= 1
856
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000857 # misc
858
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000859 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000860 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000861 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000862 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000863
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000864 def visitConst(self, node):
865 self.emit('LOAD_CONST', node.value)
866
867 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000868 self.emit('LOAD_CONST', node.name)
869 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000870
871 def visitGlobal(self, node):
872 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000873 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000874
875 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000876 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000877 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000878
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000879 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000880 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000881
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000882 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000883 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000884 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000885 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000886 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000887 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000888 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000889 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000890 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000891 if alias:
892 self._resolveDots(name)
893 self.storeName(alias)
894 else:
895 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000896
897 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000898 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000899 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000900 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000901 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000902 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000903 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000904 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000905 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000906 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000907 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000908 if VERSION > 1:
909 if name == '*':
910 self.namespace = 0
911 self.emit('IMPORT_STAR')
912 # There can only be one name w/ from ... import *
913 assert len(node.names) == 1
914 return
915 else:
916 self.emit('IMPORT_FROM', name)
917 self._resolveDots(name)
918 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000919 else:
920 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000921 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000922
Jeremy Hylton20516082000-09-01 20:33:26 +0000923 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000924 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000925 if len(elts) == 1:
926 return
927 for elt in elts[1:]:
928 self.emit('LOAD_ATTR', elt)
929
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000930 def visitGetattr(self, node):
931 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000932 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000933
934 # next five implement assignments
935
936 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000937 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000938 self.visit(node.expr)
939 dups = len(node.nodes) - 1
940 for i in range(len(node.nodes)):
941 elt = node.nodes[i]
942 if i < dups:
943 self.emit('DUP_TOP')
944 if isinstance(elt, ast.Node):
945 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000946
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000947 def visitAssName(self, node):
948 if node.flags == 'OP_ASSIGN':
949 self.storeName(node.name)
950 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000951 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000952 self.delName(node.name)
953 else:
954 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000955
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000956 def visitAssAttr(self, node):
957 self.visit(node.expr)
958 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000959 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000960 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000961 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000962 else:
963 print "warning: unexpected flags:", node.flags
964 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000965
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000966 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000967 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000968 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000969 for child in node.nodes:
970 self.visit(child)
971
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000972 if VERSION > 1:
973 visitAssTuple = _visitAssSequence
974 visitAssList = _visitAssSequence
975 else:
976 def visitAssTuple(self, node):
977 self._visitAssSequence(node, 'UNPACK_TUPLE')
978
979 def visitAssList(self, node):
980 self._visitAssSequence(node, 'UNPACK_LIST')
981
982 # augmented assignment
983
984 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000985 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000986 aug_node = wrap_aug(node.node)
987 self.visit(aug_node, "load")
988 self.visit(node.expr)
989 self.emit(self._augmented_opcode[node.op])
990 self.visit(aug_node, "store")
991
992 _augmented_opcode = {
993 '+=' : 'INPLACE_ADD',
994 '-=' : 'INPLACE_SUBTRACT',
995 '*=' : 'INPLACE_MULTIPLY',
Neal Norwitze7086d42006-03-17 08:59:09 +0000996 '/=' : 'INPLACE_TRUE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000997 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000998 '%=' : 'INPLACE_MODULO',
999 '**=': 'INPLACE_POWER',
1000 '>>=': 'INPLACE_RSHIFT',
1001 '<<=': 'INPLACE_LSHIFT',
1002 '&=' : 'INPLACE_AND',
1003 '^=' : 'INPLACE_XOR',
1004 '|=' : 'INPLACE_OR',
1005 }
1006
1007 def visitAugName(self, node, mode):
1008 if mode == "load":
1009 self.loadName(node.name)
1010 elif mode == "store":
1011 self.storeName(node.name)
1012
1013 def visitAugGetattr(self, node, mode):
1014 if mode == "load":
1015 self.visit(node.expr)
1016 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001017 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001018 elif mode == "store":
1019 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001020 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001021
1022 def visitAugSlice(self, node, mode):
1023 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001024 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001025 elif mode == "store":
1026 slice = 0
1027 if node.lower:
1028 slice = slice | 1
1029 if node.upper:
1030 slice = slice | 2
1031 if slice == 0:
1032 self.emit('ROT_TWO')
1033 elif slice == 3:
1034 self.emit('ROT_FOUR')
1035 else:
1036 self.emit('ROT_THREE')
1037 self.emit('STORE_SLICE+%d' % slice)
1038
1039 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001040 if mode == "load":
1041 self.visitSubscript(node, 1)
1042 elif mode == "store":
1043 self.emit('ROT_THREE')
1044 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001045
1046 def visitExec(self, node):
1047 self.visit(node.expr)
1048 if node.locals is None:
1049 self.emit('LOAD_CONST', None)
1050 else:
1051 self.visit(node.locals)
1052 if node.globals is None:
1053 self.emit('DUP_TOP')
1054 else:
1055 self.visit(node.globals)
1056 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001057
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001058 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001059 pos = 0
1060 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001061 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001062 self.visit(node.node)
1063 for arg in node.args:
1064 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001065 if isinstance(arg, ast.Keyword):
1066 kw = kw + 1
1067 else:
1068 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001069 if node.star_args is not None:
1070 self.visit(node.star_args)
1071 if node.dstar_args is not None:
1072 self.visit(node.dstar_args)
1073 have_star = node.star_args is not None
1074 have_dstar = node.dstar_args is not None
1075 opcode = callfunc_opcode_info[have_star, have_dstar]
1076 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001077
Jeremy Hylton2afff322001-08-27 21:51:52 +00001078 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001079 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001080 if node.dest:
1081 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001082 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001083 if node.dest:
1084 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001085 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001086 if node.dest:
1087 self.emit('ROT_TWO')
1088 self.emit('PRINT_ITEM_TO')
1089 else:
1090 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001091 if node.dest and not newline:
1092 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001093
1094 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001095 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001096 if node.dest:
1097 self.emit('PRINT_NEWLINE_TO')
1098 else:
1099 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001100
1101 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001102 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001103 self.visit(node.value)
1104 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001105
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001106 def visitYield(self, node):
1107 self.set_lineno(node)
1108 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001109 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001110
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001111 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001112
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001113 def visitSlice(self, node, aug_flag=None):
1114 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001115 self.visit(node.expr)
1116 slice = 0
1117 if node.lower:
1118 self.visit(node.lower)
1119 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001120 if node.upper:
1121 self.visit(node.upper)
1122 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001123 if aug_flag:
1124 if slice == 0:
1125 self.emit('DUP_TOP')
1126 elif slice == 3:
1127 self.emit('DUP_TOPX', 3)
1128 else:
1129 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001130 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001131 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001133 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001134 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001135 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001136 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001137 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001138 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001139
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001140 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001141 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001142 for sub in node.subs:
1143 self.visit(sub)
1144 if len(node.subs) > 1:
1145 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001146 if aug_flag:
1147 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001148 if node.flags == 'OP_APPLY':
1149 self.emit('BINARY_SUBSCR')
1150 elif node.flags == 'OP_ASSIGN':
1151 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001152 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001153 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001154
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001155 # binary ops
1156
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001157 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001158 self.visit(node.left)
1159 self.visit(node.right)
1160 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001161
1162 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001163 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001164
1165 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001166 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001167
1168 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001169 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001170
1171 def visitDiv(self, node):
Neal Norwitzc6d210c2006-03-16 06:02:10 +00001172 return self.binaryOp(node, 'BINARY_TRUE_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001173
Jeremy Hylton94afe322001-08-29 18:14:39 +00001174 def visitFloorDiv(self, node):
1175 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1176
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001177 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001179
Jeremy Hylton126960b2000-02-14 21:33:10 +00001180 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001181 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001182
1183 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001184 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001185
1186 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001187 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001188
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001189 # unary ops
1190
1191 def unaryOp(self, node, op):
1192 self.visit(node.expr)
1193 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001194
Jeremy Hylton126960b2000-02-14 21:33:10 +00001195 def visitInvert(self, node):
1196 return self.unaryOp(node, 'UNARY_INVERT')
1197
Jeremy Hylton40245602000-02-08 21:15:48 +00001198 def visitUnarySub(self, node):
1199 return self.unaryOp(node, 'UNARY_NEGATIVE')
1200
1201 def visitUnaryAdd(self, node):
1202 return self.unaryOp(node, 'UNARY_POSITIVE')
1203
1204 def visitUnaryInvert(self, node):
1205 return self.unaryOp(node, 'UNARY_INVERT')
1206
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001207 def visitNot(self, node):
1208 return self.unaryOp(node, 'UNARY_NOT')
1209
Jeremy Hylton40245602000-02-08 21:15:48 +00001210 def visitBackquote(self, node):
1211 return self.unaryOp(node, 'UNARY_CONVERT')
1212
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001213 # bit ops
1214
Jeremy Hyltona5058122000-02-14 14:14:29 +00001215 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001216 self.visit(nodes[0])
1217 for node in nodes[1:]:
1218 self.visit(node)
1219 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001220
1221 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001222 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001223
1224 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001225 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001226
1227 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001228 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001229
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001230 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001231
Jeremy Hyltona5058122000-02-14 14:14:29 +00001232 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001233 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001234
Jeremy Hylton40245602000-02-08 21:15:48 +00001235 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001236 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001237 for elt in node.nodes:
1238 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001239 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001240
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001241 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001242 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001243 for elt in node.nodes:
1244 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001245 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001246
1247 def visitSliceobj(self, node):
1248 for child in node.nodes:
1249 self.visit(child)
1250 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001251
Jeremy Hyltona5058122000-02-14 14:14:29 +00001252 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001253 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001254 self.emit('BUILD_MAP', 0)
1255 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001256 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001257 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001258 self.visit(v)
1259 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001260 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001261
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001262class NestedScopeMixin:
1263 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001264 def initClass(self):
1265 self.__class__.NameFinder = LocalNameFinder
1266 self.__class__.FunctionGen = FunctionCodeGenerator
1267 self.__class__.ClassGen = ClassCodeGenerator
1268
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001269class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001270 __super_init = CodeGenerator.__init__
1271
1272 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001273
Jeremy Hylton37c93512001-09-17 18:03:55 +00001274 def __init__(self, tree):
1275 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001276 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001277 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001278 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001279
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001280 def get_module(self):
1281 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001282
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001283class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1284 __super_init = CodeGenerator.__init__
1285
1286 scopes = None
1287 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001288
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001289 def __init__(self, tree):
1290 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1291 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001292 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001293
1294 def get_module(self):
1295 return self
1296
1297class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1298
1299 __super_init = CodeGenerator.__init__
1300
1301 scopes = None
1302 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001303
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001304 def __init__(self, tree):
1305 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1306 self.__super_init()
1307 self.set_lineno(tree)
1308 walk(tree, self)
1309 self.emit('RETURN_VALUE')
1310
1311 def get_module(self):
1312 return self
Tim Peterse4418602002-02-16 07:34:19 +00001313
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001314 def visitDiscard(self, node):
1315 # XXX Discard means it's an expression. Perhaps this is a bad
1316 # name.
1317 self.visit(node.expr)
1318 self.emit('PRINT_EXPR')
1319
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001320class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001321 optimized = 1
1322 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001323
Jeremy Hylton37c93512001-09-17 18:03:55 +00001324 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001325 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001326 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001327 if isLambda:
1328 klass = FunctionCodeGenerator
1329 name = "<lambda.%d>" % klass.lambdaCount
1330 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001331 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001332 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001333
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001334 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001335 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1336 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001337 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001338 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001339
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001340 if not isLambda and func.doc:
1341 self.setDocstring(func.doc)
1342
Jeremy Hylton2afff322001-08-27 21:51:52 +00001343 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001344 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001345 if func.varargs:
1346 self.graph.setFlag(CO_VARARGS)
1347 if func.kwargs:
1348 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001349 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001350 if hasTupleArg:
1351 self.generateArgUnpack(func.argnames)
1352
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001353 def get_module(self):
1354 return self.module
1355
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001356 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001357 self.graph.startExitBlock()
1358 if not self.isLambda:
1359 self.emit('LOAD_CONST', None)
1360 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001361
1362 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001363 for i in range(len(args)):
1364 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001365 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001366 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001367 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001368
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001369 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001370 if VERSION > 1:
1371 self.emit('UNPACK_SEQUENCE', len(tup))
1372 else:
1373 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001374 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001375 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001376 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001377 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001378 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001379
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001380 unpackTuple = unpackSequence
1381
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001382class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001383 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001384 super_init = CodeGenerator.__init__ # call be other init
1385 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001386
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001387 __super_init = AbstractFunctionCode.__init__
1388
Jeremy Hylton37c93512001-09-17 18:03:55 +00001389 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001390 self.scopes = scopes
1391 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001392 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001393 self.graph.setFreeVars(self.scope.get_free_vars())
1394 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001395 if self.scope.generator is not None:
1396 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001397
Raymond Hettinger354433a2004-05-19 08:20:33 +00001398class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1399 CodeGenerator):
1400 super_init = CodeGenerator.__init__ # call be other init
1401 scopes = None
1402
1403 __super_init = AbstractFunctionCode.__init__
1404
1405 def __init__(self, gexp, scopes, class_name, mod):
1406 self.scopes = scopes
1407 self.scope = scopes[gexp]
1408 self.__super_init(gexp, scopes, 1, class_name, mod)
1409 self.graph.setFreeVars(self.scope.get_free_vars())
1410 self.graph.setCellVars(self.scope.get_cell_vars())
1411 self.graph.setFlag(CO_GENERATOR)
1412
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001413class AbstractClassCode:
1414
Jeremy Hylton37c93512001-09-17 18:03:55 +00001415 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001416 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001417 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001418 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001419 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001420 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001421 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001422 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001423 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001424 if klass.doc:
1425 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001426
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001427 def get_module(self):
1428 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001429
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001430 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001431 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001432 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001433 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001434
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001435class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001436 super_init = CodeGenerator.__init__
1437 scopes = None
1438
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001439 __super_init = AbstractClassCode.__init__
1440
Jeremy Hylton37c93512001-09-17 18:03:55 +00001441 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001442 self.scopes = scopes
1443 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001444 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001445 self.graph.setFreeVars(self.scope.get_free_vars())
1446 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001447 self.set_lineno(klass)
1448 self.emit("LOAD_GLOBAL", "__name__")
1449 self.storeName("__module__")
1450 if klass.doc:
1451 self.emit("LOAD_CONST", klass.doc)
1452 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001453
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001454def generateArgList(arglist):
1455 """Generate an arg list marking TupleArgs"""
1456 args = []
1457 extra = []
1458 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001459 for i in range(len(arglist)):
1460 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001461 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001462 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001463 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001464 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001465 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001466 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001467 else:
1468 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001469 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001470
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001471def findOp(node):
1472 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1473 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001474 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001475 return v.op
1476
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001477class OpFinder:
1478 def __init__(self):
1479 self.op = None
1480 def visitAssName(self, node):
1481 if self.op is None:
1482 self.op = node.flags
1483 elif self.op != node.flags:
1484 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001485 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001486 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001487
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001488class Delegator:
1489 """Base class to support delegation for augmented assignment nodes
1490
1491 To generator code for augmented assignments, we use the following
1492 wrapper classes. In visitAugAssign, the left-hand expression node
1493 is visited twice. The first time the visit uses the normal method
1494 for that node . The second time the visit uses a different method
1495 that generates the appropriate code to perform the assignment.
1496 These delegator classes wrap the original AST nodes in order to
1497 support the variant visit methods.
1498 """
1499 def __init__(self, obj):
1500 self.obj = obj
1501
1502 def __getattr__(self, attr):
1503 return getattr(self.obj, attr)
1504
1505class AugGetattr(Delegator):
1506 pass
1507
1508class AugName(Delegator):
1509 pass
1510
1511class AugSlice(Delegator):
1512 pass
1513
1514class AugSubscript(Delegator):
1515 pass
1516
1517wrapper = {
1518 ast.Getattr: AugGetattr,
1519 ast.Name: AugName,
1520 ast.Slice: AugSlice,
1521 ast.Subscript: AugSubscript,
1522 }
1523
1524def wrap_aug(node):
1525 return wrapper[node.__class__](node)
1526
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001527if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001528 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001529 compileFile(file)