blob: b08a307b8a75bf87a8a595f25209a21d1b8358e7 [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)
Guido van Rossum4f72a782006-10-27 23:31:49 +0000381 for keyword in node.kwonlyargs:
382 default = keyword.expr
383 if isinstance(default, ast.EmptyNode):
384 continue
385 self.emit('LOAD_CONST', keyword.name)
386 self.visit(default)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000387 for default in node.defaults:
388 self.visit(default)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000389 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000390 for i in range(ndecorators):
391 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000392
393 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000394 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000395 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000396 walk(node.code, gen)
397 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000398 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000399 self.emit('LOAD_CONST', node.name)
400 for base in node.bases:
401 self.visit(base)
402 self.emit('BUILD_TUPLE', len(node.bases))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000403 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000404 self.emit('CALL_FUNCTION', 0)
405 self.emit('BUILD_CLASS')
406 self.storeName(node.name)
407
408 # The rest are standard visitor methods
409
410 # The next few implement control-flow statements
411
412 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000413 end = self.newBlock()
414 numtests = len(node.tests)
415 for i in range(numtests):
416 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000417 if is_constant_false(test):
418 # XXX will need to check generator stuff here
419 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000420 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000421 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000422 nextTest = self.newBlock()
423 self.emit('JUMP_IF_FALSE', nextTest)
424 self.nextBlock()
425 self.emit('POP_TOP')
426 self.visit(suite)
427 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000428 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000429 self.emit('POP_TOP')
430 if node.else_:
431 self.visit(node.else_)
432 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000433
434 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000435 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000436
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000437 loop = self.newBlock()
438 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000439
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000440 after = self.newBlock()
441 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000442
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000443 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000444 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000445
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000446 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000447 self.visit(node.test)
448 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000449
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000450 self.nextBlock()
451 self.emit('POP_TOP')
452 self.visit(node.body)
453 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000454
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000455 self.startBlock(else_) # or just the POPs if not else clause
456 self.emit('POP_TOP')
457 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000458 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000459 if node.else_:
460 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000461 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000462
463 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000465 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000466 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000467 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000468
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000469 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000470 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000471 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000472 self.emit('GET_ITER')
473
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000474 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000475 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000476 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000477 self.visit(node.assign)
478 self.visit(node.body)
479 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000480 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000482 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000483 if node.else_:
484 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000485 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000486
487 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000488 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000489 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000490 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000491 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000492 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000493
494 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000495 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000496 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000497 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000498 kind, block = self.setups.top()
499 if kind == LOOP:
500 self.set_lineno(node)
501 self.emit('JUMP_ABSOLUTE', block)
502 self.nextBlock()
503 elif kind == EXCEPT or kind == TRY_FINALLY:
504 self.set_lineno(node)
505 # find the block that starts the loop
506 top = len(self.setups)
507 while top > 0:
508 top = top - 1
509 kind, loop_block = self.setups[top]
510 if kind == LOOP:
511 break
512 if kind != LOOP:
513 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000514 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000515 self.emit('CONTINUE_LOOP', loop_block)
516 self.nextBlock()
517 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000518 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000519 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000520
521 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000522 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000523 for child in node.nodes[:-1]:
524 self.visit(child)
525 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000526 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000527 self.emit('POP_TOP')
528 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000529 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000530
531 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000532 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000533
534 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000535 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000536
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000537 def visitIfExp(self, node):
538 endblock = self.newBlock()
539 elseblock = self.newBlock()
540 self.visit(node.test)
541 self.emit('JUMP_IF_FALSE', elseblock)
542 self.emit('POP_TOP')
543 self.visit(node.then)
544 self.emit('JUMP_FORWARD', endblock)
545 self.nextBlock(elseblock)
546 self.emit('POP_TOP')
547 self.visit(node.else_)
548 self.nextBlock(endblock)
549
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000550 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000551 self.visit(node.expr)
552 cleanup = self.newBlock()
553 for op, code in node.ops[:-1]:
554 self.visit(code)
555 self.emit('DUP_TOP')
556 self.emit('ROT_THREE')
557 self.emit('COMPARE_OP', op)
558 self.emit('JUMP_IF_FALSE', cleanup)
559 self.nextBlock()
560 self.emit('POP_TOP')
561 # now do the last comparison
562 if node.ops:
563 op, code = node.ops[-1]
564 self.visit(code)
565 self.emit('COMPARE_OP', op)
566 if len(node.ops) > 1:
567 end = self.newBlock()
568 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000569 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000570 self.emit('ROT_TWO')
571 self.emit('POP_TOP')
572 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000573
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000574 # list comprehensions
575 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000576
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000577 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000578 self.set_lineno(node)
579 # setup list
580 append = "$append%d" % self.__list_count
581 self.__list_count = self.__list_count + 1
582 self.emit('BUILD_LIST', 0)
583 self.emit('DUP_TOP')
584 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000585 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000586
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000587 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000588 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000589 start, anchor = self.visit(for_)
590 cont = None
591 for if_ in for_.ifs:
592 if cont is None:
593 cont = self.newBlock()
594 self.visit(if_, cont)
595 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000596
Jeremy Hylton13d70942001-04-12 21:04:43 +0000597 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000598 self.visit(node.expr)
599 self.emit('CALL_FUNCTION', 1)
600 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000601
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000602 for start, cont, anchor in stack:
603 if cont:
604 skip_one = self.newBlock()
605 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000606 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000607 self.emit('POP_TOP')
608 self.nextBlock(skip_one)
609 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000610 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000611 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000612
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000613 self.__list_count = self.__list_count - 1
614
615 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000616 start = self.newBlock()
617 anchor = self.newBlock()
618
619 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000620 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000621 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000622 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000623 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000624 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000625 self.visit(node.assign)
626 return start, anchor
627
628 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000629 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000630 self.visit(node.test)
631 self.emit('JUMP_IF_FALSE', branch)
632 self.newBlock()
633 self.emit('POP_TOP')
634
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000635 def _makeClosure(self, gen, args):
636 frees = gen.scope.get_free_vars()
637 if frees:
638 for name in frees:
639 self.emit('LOAD_CLOSURE', name)
640 self.emit('BUILD_TUPLE', len(frees))
641 self.emit('LOAD_CONST', gen)
642 self.emit('MAKE_CLOSURE', args)
643 else:
644 self.emit('LOAD_CONST', gen)
645 self.emit('MAKE_FUNCTION', args)
646
Raymond Hettinger354433a2004-05-19 08:20:33 +0000647 def visitGenExpr(self, node):
648 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
649 self.get_module())
650 walk(node.code, gen)
651 gen.finish()
652 self.set_lineno(node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000653 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000654 # precomputation of outmost iterable
655 self.visit(node.code.quals[0].iter)
656 self.emit('GET_ITER')
657 self.emit('CALL_FUNCTION', 1)
658
659 def visitGenExprInner(self, node):
660 self.set_lineno(node)
661 # setup list
662
663 stack = []
664 for i, for_ in zip(range(len(node.quals)), node.quals):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000665 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000666 cont = None
667 for if_ in for_.ifs:
668 if cont is None:
669 cont = self.newBlock()
670 self.visit(if_, cont)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000671 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672
673 self.visit(node.expr)
674 self.emit('YIELD_VALUE')
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000675 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000676
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000677 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000678 if cont:
679 skip_one = self.newBlock()
680 self.emit('JUMP_FORWARD', skip_one)
681 self.startBlock(cont)
682 self.emit('POP_TOP')
683 self.nextBlock(skip_one)
684 self.emit('JUMP_ABSOLUTE', start)
685 self.startBlock(anchor)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000686 self.emit('POP_BLOCK')
687 self.setups.pop()
688 self.startBlock(end)
689
Raymond Hettinger354433a2004-05-19 08:20:33 +0000690 self.emit('LOAD_CONST', None)
691
692 def visitGenExprFor(self, node):
693 start = self.newBlock()
694 anchor = self.newBlock()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000695 end = self.newBlock()
696
697 self.setups.push((LOOP, start))
698 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000699
Raymond Hettinger354433a2004-05-19 08:20:33 +0000700 if node.is_outmost:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000701 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000702 else:
703 self.visit(node.iter)
704 self.emit('GET_ITER')
705
706 self.nextBlock(start)
707 self.set_lineno(node, force=True)
708 self.emit('FOR_ITER', anchor)
709 self.nextBlock()
710 self.visit(node.assign)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000711 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000712
713 def visitGenExprIf(self, node, branch):
714 self.set_lineno(node, force=True)
715 self.visit(node.test)
716 self.emit('JUMP_IF_FALSE', branch)
717 self.newBlock()
718 self.emit('POP_TOP')
719
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000720 # exception related
721
722 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000723 # XXX would be interesting to implement this via a
724 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000725 if __debug__:
726 end = self.newBlock()
727 self.set_lineno(node)
728 # XXX AssertionError appears to be special case -- it is always
729 # loaded as a global even if there is a local name. I guess this
730 # is a sort of renaming op.
731 self.nextBlock()
732 self.visit(node.test)
733 self.emit('JUMP_IF_TRUE', end)
734 self.nextBlock()
735 self.emit('POP_TOP')
736 self.emit('LOAD_GLOBAL', 'AssertionError')
737 if node.fail:
738 self.visit(node.fail)
739 self.emit('RAISE_VARARGS', 2)
740 else:
741 self.emit('RAISE_VARARGS', 1)
742 self.nextBlock(end)
743 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000744
745 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000746 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000747 n = 0
748 if node.expr1:
749 self.visit(node.expr1)
750 n = n + 1
751 if node.expr2:
752 self.visit(node.expr2)
753 n = n + 1
754 if node.expr3:
755 self.visit(node.expr3)
756 n = n + 1
757 self.emit('RAISE_VARARGS', n)
758
759 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000760 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000761 handlers = self.newBlock()
762 end = self.newBlock()
763 if node.else_:
764 lElse = self.newBlock()
765 else:
766 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000767 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000768 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000769 self.nextBlock(body)
770 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000771 self.visit(node.body)
772 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000773 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000774 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000775 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000776
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000777 last = len(node.handlers) - 1
778 for i in range(len(node.handlers)):
779 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000780 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000781 if expr:
782 self.emit('DUP_TOP')
783 self.visit(expr)
784 self.emit('COMPARE_OP', 'exception match')
785 next = self.newBlock()
786 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000787 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000788 self.emit('POP_TOP')
789 self.emit('POP_TOP')
790 if target:
791 self.visit(target)
792 else:
793 self.emit('POP_TOP')
794 self.emit('POP_TOP')
795 self.visit(body)
796 self.emit('JUMP_FORWARD', end)
797 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000798 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000799 else:
800 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000801 if expr: # XXX
802 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 self.emit('END_FINALLY')
804 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000805 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000806 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000807 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000808
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000810 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000812 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000813 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000814 self.nextBlock(body)
815 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000816 self.visit(node.body)
817 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000818 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000819 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000820 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000821 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000822 self.visit(node.final)
823 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000824 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000825
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000826 __with_count = 0
827
828 def visitWith(self, node):
829 body = self.newBlock()
830 final = self.newBlock()
831 exitvar = "$exit%d" % self.__with_count
832 valuevar = "$value%d" % self.__with_count
833 self.__with_count += 1
834 self.set_lineno(node)
835 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000836 self.emit('DUP_TOP')
837 self.emit('LOAD_ATTR', '__exit__')
838 self._implicitNameOp('STORE', exitvar)
839 self.emit('LOAD_ATTR', '__enter__')
840 self.emit('CALL_FUNCTION', 0)
841 if node.vars is None:
842 self.emit('POP_TOP')
843 else:
844 self._implicitNameOp('STORE', valuevar)
845 self.emit('SETUP_FINALLY', final)
846 self.nextBlock(body)
847 self.setups.push((TRY_FINALLY, body))
848 if node.vars is not None:
849 self._implicitNameOp('LOAD', valuevar)
850 self._implicitNameOp('DELETE', valuevar)
851 self.visit(node.vars)
852 self.visit(node.body)
853 self.emit('POP_BLOCK')
854 self.setups.pop()
855 self.emit('LOAD_CONST', None)
856 self.nextBlock(final)
857 self.setups.push((END_FINALLY, final))
858 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000859 self.emit('END_FINALLY')
860 self.setups.pop()
861 self.__with_count -= 1
862
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000863 # misc
864
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000865 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000866 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000867 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000868 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000869
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000870 def visitConst(self, node):
871 self.emit('LOAD_CONST', node.value)
872
873 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000874 self.emit('LOAD_CONST', node.name)
875 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000876
877 def visitGlobal(self, node):
878 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000879 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000880
881 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000882 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000883 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000884
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000885 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000886 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000887
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000888 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000889 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000890 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000891 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000892 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000893 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000894 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000895 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000896 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000897 if alias:
898 self._resolveDots(name)
899 self.storeName(alias)
900 else:
901 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000902
903 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000904 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000905 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000906 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000907 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000908 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000909 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000910 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000911 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000912 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000913 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000914 if VERSION > 1:
915 if name == '*':
916 self.namespace = 0
917 self.emit('IMPORT_STAR')
918 # There can only be one name w/ from ... import *
919 assert len(node.names) == 1
920 return
921 else:
922 self.emit('IMPORT_FROM', name)
923 self._resolveDots(name)
924 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000925 else:
926 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000927 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000928
Jeremy Hylton20516082000-09-01 20:33:26 +0000929 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000930 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000931 if len(elts) == 1:
932 return
933 for elt in elts[1:]:
934 self.emit('LOAD_ATTR', elt)
935
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000936 def visitGetattr(self, node):
937 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000938 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000939
940 # next five implement assignments
941
942 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000943 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000944 self.visit(node.expr)
945 dups = len(node.nodes) - 1
946 for i in range(len(node.nodes)):
947 elt = node.nodes[i]
948 if i < dups:
949 self.emit('DUP_TOP')
950 if isinstance(elt, ast.Node):
951 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000952
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953 def visitAssName(self, node):
954 if node.flags == 'OP_ASSIGN':
955 self.storeName(node.name)
956 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000957 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000958 self.delName(node.name)
959 else:
960 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000961
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000962 def visitAssAttr(self, node):
963 self.visit(node.expr)
964 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000965 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000966 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000967 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000968 else:
969 print "warning: unexpected flags:", node.flags
970 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000971
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000972 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000973 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000974 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000975 for child in node.nodes:
976 self.visit(child)
977
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000978 if VERSION > 1:
979 visitAssTuple = _visitAssSequence
980 visitAssList = _visitAssSequence
981 else:
982 def visitAssTuple(self, node):
983 self._visitAssSequence(node, 'UNPACK_TUPLE')
984
985 def visitAssList(self, node):
986 self._visitAssSequence(node, 'UNPACK_LIST')
987
988 # augmented assignment
989
990 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000991 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000992 aug_node = wrap_aug(node.node)
993 self.visit(aug_node, "load")
994 self.visit(node.expr)
995 self.emit(self._augmented_opcode[node.op])
996 self.visit(aug_node, "store")
997
998 _augmented_opcode = {
999 '+=' : 'INPLACE_ADD',
1000 '-=' : 'INPLACE_SUBTRACT',
1001 '*=' : 'INPLACE_MULTIPLY',
Neal Norwitze7086d42006-03-17 08:59:09 +00001002 '/=' : 'INPLACE_TRUE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001003 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001004 '%=' : 'INPLACE_MODULO',
1005 '**=': 'INPLACE_POWER',
1006 '>>=': 'INPLACE_RSHIFT',
1007 '<<=': 'INPLACE_LSHIFT',
1008 '&=' : 'INPLACE_AND',
1009 '^=' : 'INPLACE_XOR',
1010 '|=' : 'INPLACE_OR',
1011 }
1012
1013 def visitAugName(self, node, mode):
1014 if mode == "load":
1015 self.loadName(node.name)
1016 elif mode == "store":
1017 self.storeName(node.name)
1018
1019 def visitAugGetattr(self, node, mode):
1020 if mode == "load":
1021 self.visit(node.expr)
1022 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001023 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001024 elif mode == "store":
1025 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001026 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001027
1028 def visitAugSlice(self, node, mode):
1029 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001030 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001031 elif mode == "store":
1032 slice = 0
1033 if node.lower:
1034 slice = slice | 1
1035 if node.upper:
1036 slice = slice | 2
1037 if slice == 0:
1038 self.emit('ROT_TWO')
1039 elif slice == 3:
1040 self.emit('ROT_FOUR')
1041 else:
1042 self.emit('ROT_THREE')
1043 self.emit('STORE_SLICE+%d' % slice)
1044
1045 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001046 if mode == "load":
1047 self.visitSubscript(node, 1)
1048 elif mode == "store":
1049 self.emit('ROT_THREE')
1050 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001051
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001052 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001053 pos = 0
1054 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001055 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001056 self.visit(node.node)
1057 for arg in node.args:
1058 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001059 if isinstance(arg, ast.Keyword):
1060 kw = kw + 1
1061 else:
1062 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001063 if node.star_args is not None:
1064 self.visit(node.star_args)
1065 if node.dstar_args is not None:
1066 self.visit(node.dstar_args)
1067 have_star = node.star_args is not None
1068 have_dstar = node.dstar_args is not None
1069 opcode = callfunc_opcode_info[have_star, have_dstar]
1070 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001071
Jeremy Hylton2afff322001-08-27 21:51:52 +00001072 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001073 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001074 if node.dest:
1075 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001076 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001077 if node.dest:
1078 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001079 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001080 if node.dest:
1081 self.emit('ROT_TWO')
1082 self.emit('PRINT_ITEM_TO')
1083 else:
1084 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001085 if node.dest and not newline:
1086 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001087
1088 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001089 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001090 if node.dest:
1091 self.emit('PRINT_NEWLINE_TO')
1092 else:
1093 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001094
1095 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001096 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001097 self.visit(node.value)
1098 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001099
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001100 def visitYield(self, node):
1101 self.set_lineno(node)
1102 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001103 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001104
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001105 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001106
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001107 def visitSlice(self, node, aug_flag=None):
1108 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001109 self.visit(node.expr)
1110 slice = 0
1111 if node.lower:
1112 self.visit(node.lower)
1113 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001114 if node.upper:
1115 self.visit(node.upper)
1116 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001117 if aug_flag:
1118 if slice == 0:
1119 self.emit('DUP_TOP')
1120 elif slice == 3:
1121 self.emit('DUP_TOPX', 3)
1122 else:
1123 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001124 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001125 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001126 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001127 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001128 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001129 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001130 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001131 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001133
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001134 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001135 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001136 for sub in node.subs:
1137 self.visit(sub)
1138 if len(node.subs) > 1:
1139 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001140 if aug_flag:
1141 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001142 if node.flags == 'OP_APPLY':
1143 self.emit('BINARY_SUBSCR')
1144 elif node.flags == 'OP_ASSIGN':
1145 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001146 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001147 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001148
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001149 # binary ops
1150
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001151 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001152 self.visit(node.left)
1153 self.visit(node.right)
1154 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001155
1156 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001157 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001158
1159 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001160 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001161
1162 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001163 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001164
1165 def visitDiv(self, node):
Neal Norwitzc6d210c2006-03-16 06:02:10 +00001166 return self.binaryOp(node, 'BINARY_TRUE_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001167
Jeremy Hylton94afe322001-08-29 18:14:39 +00001168 def visitFloorDiv(self, node):
1169 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1170
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001171 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001173
Jeremy Hylton126960b2000-02-14 21:33:10 +00001174 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001175 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001176
1177 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001179
1180 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001181 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001182
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001183 # unary ops
1184
1185 def unaryOp(self, node, op):
1186 self.visit(node.expr)
1187 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001188
Jeremy Hylton126960b2000-02-14 21:33:10 +00001189 def visitInvert(self, node):
1190 return self.unaryOp(node, 'UNARY_INVERT')
1191
Jeremy Hylton40245602000-02-08 21:15:48 +00001192 def visitUnarySub(self, node):
1193 return self.unaryOp(node, 'UNARY_NEGATIVE')
1194
1195 def visitUnaryAdd(self, node):
1196 return self.unaryOp(node, 'UNARY_POSITIVE')
1197
1198 def visitUnaryInvert(self, node):
1199 return self.unaryOp(node, 'UNARY_INVERT')
1200
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001201 def visitNot(self, node):
1202 return self.unaryOp(node, 'UNARY_NOT')
1203
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001204 # bit ops
1205
Jeremy Hyltona5058122000-02-14 14:14:29 +00001206 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001207 self.visit(nodes[0])
1208 for node in nodes[1:]:
1209 self.visit(node)
1210 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001211
1212 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001213 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001214
1215 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001216 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001217
1218 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001219 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001220
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001221 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001222
1223 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001224 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001225 for elt in node.nodes:
1226 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001227 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001228
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001229 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001230 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001231 for elt in node.nodes:
1232 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001233 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001234
Guido van Rossum86e58e22006-08-28 15:27:34 +00001235 def visitSet(self, node):
1236 self.set_lineno(node)
1237 for elt in node.items:
1238 self.visit(elt)
1239 self.emit('BUILD_SET', len(node.items))
1240
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001241 def visitSliceobj(self, node):
1242 for child in node.nodes:
1243 self.visit(child)
1244 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001245
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001247 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001248 self.emit('BUILD_MAP', 0)
1249 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001250 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001251 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001252 self.visit(v)
1253 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001254 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001255
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001256class NestedScopeMixin:
1257 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001258 def initClass(self):
1259 self.__class__.NameFinder = LocalNameFinder
1260 self.__class__.FunctionGen = FunctionCodeGenerator
1261 self.__class__.ClassGen = ClassCodeGenerator
1262
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001263class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001264 __super_init = CodeGenerator.__init__
1265
1266 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001267
Jeremy Hylton37c93512001-09-17 18:03:55 +00001268 def __init__(self, tree):
1269 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001270 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001271 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001272 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001273
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001274 def get_module(self):
1275 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001276
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001277class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1278 __super_init = CodeGenerator.__init__
1279
1280 scopes = None
1281 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001282
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001283 def __init__(self, tree):
1284 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1285 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001286 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001287
1288 def get_module(self):
1289 return self
1290
1291class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1292
1293 __super_init = CodeGenerator.__init__
1294
1295 scopes = None
1296 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001297
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001298 def __init__(self, tree):
1299 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1300 self.__super_init()
1301 self.set_lineno(tree)
1302 walk(tree, self)
1303 self.emit('RETURN_VALUE')
1304
1305 def get_module(self):
1306 return self
Tim Peterse4418602002-02-16 07:34:19 +00001307
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001308 def visitDiscard(self, node):
1309 # XXX Discard means it's an expression. Perhaps this is a bad
1310 # name.
1311 self.visit(node.expr)
1312 self.emit('PRINT_EXPR')
1313
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001314class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001315 optimized = 1
1316 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001317
Jeremy Hylton37c93512001-09-17 18:03:55 +00001318 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001319 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001320 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001321 if isLambda:
1322 klass = FunctionCodeGenerator
1323 name = "<lambda.%d>" % klass.lambdaCount
1324 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001325 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001326 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001327
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001328 args, hasTupleArg = generateArgList(func.argnames)
Guido van Rossum4f72a782006-10-27 23:31:49 +00001329 kwonlyargs = generateKwonlyArgList(func.kwonlyargs)
Tim Peterse0c446b2001-10-18 21:57:37 +00001330 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
Guido van Rossum4f72a782006-10-27 23:31:49 +00001331 kwonlyargs=kwonlyargs,
Tim Peterse0c446b2001-10-18 21:57:37 +00001332 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001333 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001334 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001335
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001336 if not isLambda and func.doc:
1337 self.setDocstring(func.doc)
1338
Jeremy Hylton2afff322001-08-27 21:51:52 +00001339 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001340 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001341 if func.varargs:
1342 self.graph.setFlag(CO_VARARGS)
1343 if func.kwargs:
1344 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001345 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001346 if hasTupleArg:
1347 self.generateArgUnpack(func.argnames)
1348
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001349 def get_module(self):
1350 return self.module
1351
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001352 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001353 self.graph.startExitBlock()
1354 if not self.isLambda:
1355 self.emit('LOAD_CONST', None)
1356 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001357
1358 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001359 for i in range(len(args)):
1360 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001361 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001362 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001363 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001364
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001365 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001366 if VERSION > 1:
1367 self.emit('UNPACK_SEQUENCE', len(tup))
1368 else:
1369 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001370 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001371 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001372 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001373 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001374 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001375
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001376 unpackTuple = unpackSequence
1377
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001378class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001379 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001380 super_init = CodeGenerator.__init__ # call be other init
1381 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001382
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001383 __super_init = AbstractFunctionCode.__init__
1384
Jeremy Hylton37c93512001-09-17 18:03:55 +00001385 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001386 self.scopes = scopes
1387 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001388 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001389 self.graph.setFreeVars(self.scope.get_free_vars())
1390 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001391 if self.scope.generator is not None:
1392 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001393
Raymond Hettinger354433a2004-05-19 08:20:33 +00001394class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1395 CodeGenerator):
1396 super_init = CodeGenerator.__init__ # call be other init
1397 scopes = None
1398
1399 __super_init = AbstractFunctionCode.__init__
1400
1401 def __init__(self, gexp, scopes, class_name, mod):
1402 self.scopes = scopes
1403 self.scope = scopes[gexp]
1404 self.__super_init(gexp, scopes, 1, class_name, mod)
1405 self.graph.setFreeVars(self.scope.get_free_vars())
1406 self.graph.setCellVars(self.scope.get_cell_vars())
1407 self.graph.setFlag(CO_GENERATOR)
1408
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001409class AbstractClassCode:
1410
Jeremy Hylton37c93512001-09-17 18:03:55 +00001411 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001412 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001413 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001414 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001415 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001416 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001417 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001418 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001419 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001420 if klass.doc:
1421 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001422
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001423 def get_module(self):
1424 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001425
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001426 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001427 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001428 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001429 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001430
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001431class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001432 super_init = CodeGenerator.__init__
1433 scopes = None
1434
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001435 __super_init = AbstractClassCode.__init__
1436
Jeremy Hylton37c93512001-09-17 18:03:55 +00001437 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001438 self.scopes = scopes
1439 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001440 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001441 self.graph.setFreeVars(self.scope.get_free_vars())
1442 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001443 self.set_lineno(klass)
1444 self.emit("LOAD_GLOBAL", "__name__")
1445 self.storeName("__module__")
1446 if klass.doc:
1447 self.emit("LOAD_CONST", klass.doc)
1448 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001449
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001450def generateArgList(arglist):
1451 """Generate an arg list marking TupleArgs"""
1452 args = []
1453 extra = []
1454 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001455 for i in range(len(arglist)):
1456 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001457 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001458 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001459 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001460 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001461 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001462 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001463 else:
1464 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001465 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001466
Guido van Rossum4f72a782006-10-27 23:31:49 +00001467def generateKwonlyArgList(keywordOnlyArgs):
1468 kwonlyargs = {}
1469 for elt in keywordOnlyArgs:
1470 assert isinstance(elt, ast.Keyword)
1471 kwonlyargs[elt.name] = elt.expr
1472 return kwonlyargs
1473
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001474def findOp(node):
1475 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1476 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001477 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001478 return v.op
1479
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001480class OpFinder:
1481 def __init__(self):
1482 self.op = None
1483 def visitAssName(self, node):
1484 if self.op is None:
1485 self.op = node.flags
1486 elif self.op != node.flags:
1487 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001488 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001489 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001490
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001491class Delegator:
1492 """Base class to support delegation for augmented assignment nodes
1493
1494 To generator code for augmented assignments, we use the following
1495 wrapper classes. In visitAugAssign, the left-hand expression node
1496 is visited twice. The first time the visit uses the normal method
1497 for that node . The second time the visit uses a different method
1498 that generates the appropriate code to perform the assignment.
1499 These delegator classes wrap the original AST nodes in order to
1500 support the variant visit methods.
1501 """
1502 def __init__(self, obj):
1503 self.obj = obj
1504
1505 def __getattr__(self, attr):
1506 return getattr(self.obj, attr)
1507
1508class AugGetattr(Delegator):
1509 pass
1510
1511class AugName(Delegator):
1512 pass
1513
1514class AugSlice(Delegator):
1515 pass
1516
1517class AugSubscript(Delegator):
1518 pass
1519
1520wrapper = {
1521 ast.Getattr: AugGetattr,
1522 ast.Name: AugName,
1523 ast.Slice: AugSlice,
1524 ast.Subscript: AugSubscript,
1525 }
1526
1527def wrap_aug(node):
1528 return wrapper[node.__class__](node)
1529
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001530if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001531 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001532 compileFile(file)