blob: e3667b594d3bd45260d0ac1cdec81a8925579a55 [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 Hyltonaee0bfe2001-09-17 16:41:02 +0000209 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000210
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000211 # XXX set flags based on future features
212 futures = self.get_module().futures
213 for feature in futures:
214 if feature == "division":
215 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000216 self._div_op = "BINARY_TRUE_DIVIDE"
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000217 elif feature == "absolute_import":
218 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
219 elif feature == "with_statement":
220 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000221
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000222 def initClass(self):
223 """This method is called once for each class"""
224
225 def checkClass(self):
226 """Verify that class is constructed correctly"""
227 try:
228 assert hasattr(self, 'graph')
229 assert getattr(self, 'NameFinder')
230 assert getattr(self, 'FunctionGen')
231 assert getattr(self, 'ClassGen')
232 except AssertionError, msg:
233 intro = "Bad class construction for %s" % self.__class__.__name__
234 raise AssertionError, intro
235
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000236 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000237 self.emit = self.graph.emit
238 self.newBlock = self.graph.newBlock
239 self.startBlock = self.graph.startBlock
240 self.nextBlock = self.graph.nextBlock
241 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000242
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000243 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000244 """Return a code object"""
245 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000246
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000247 def mangle(self, name):
248 if self.class_name is not None:
249 return misc.mangle(name, self.class_name)
250 else:
251 return name
252
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000253 def parseSymbols(self, tree):
254 s = symbols.SymbolVisitor()
255 walk(tree, s)
256 return s.scopes
257
258 def get_module(self):
259 raise RuntimeError, "should be implemented by subclasses"
260
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000261 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000262
Jeremy Hylton40245602000-02-08 21:15:48 +0000263 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000264 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000265
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000266 def storeName(self, name):
267 self._nameOp('STORE', name)
268
269 def loadName(self, name):
270 self._nameOp('LOAD', name)
271
272 def delName(self, name):
273 self._nameOp('DELETE', name)
274
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000275 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000276 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000277 scope = self.scope.check_name(name)
278 if scope == SC_LOCAL:
279 if not self.optimized:
280 self.emit(prefix + '_NAME', name)
281 else:
282 self.emit(prefix + '_FAST', name)
283 elif scope == SC_GLOBAL:
284 if not self.optimized:
285 self.emit(prefix + '_NAME', name)
286 else:
287 self.emit(prefix + '_GLOBAL', name)
288 elif scope == SC_FREE or scope == SC_CELL:
289 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000290 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000291 raise RuntimeError, "unsupported scope for var %s: %d" % \
292 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000293
Jeremy Hylton13d70942001-04-12 21:04:43 +0000294 def _implicitNameOp(self, prefix, name):
295 """Emit name ops for names generated implicitly by for loops
296
297 The interpreter generates names that start with a period or
298 dollar sign. The symbol table ignores these names because
299 they aren't present in the program text.
300 """
301 if self.optimized:
302 self.emit(prefix + '_FAST', name)
303 else:
304 self.emit(prefix + '_NAME', name)
305
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000306 # The set_lineno() function and the explicit emit() calls for
307 # SET_LINENO below are only used to generate the line number table.
308 # As of Python 2.3, the interpreter does not have a SET_LINENO
309 # instruction. pyassem treats SET_LINENO opcodes as a special case.
310
311 def set_lineno(self, node, force=False):
312 """Emit SET_LINENO if necessary.
313
314 The instruction is considered necessary if the node has a
315 lineno attribute and it is different than the last lineno
316 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000317
318 Returns true if SET_LINENO was emitted.
319
320 There are no rules for when an AST node should have a lineno
321 attribute. The transformer and AST code need to be reviewed
322 and a consistent policy implemented and documented. Until
323 then, this method works around missing line numbers.
324 """
325 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000326 if lineno is not None and (lineno != self.last_lineno
327 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000328 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000329 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000330 return True
331 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000332
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000333 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000334 # code objects. They use class attributes to determine what
335 # specialized code generators to use.
336
337 NameFinder = LocalNameFinder
338 FunctionGen = None
339 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000340
341 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000342 self.scopes = self.parseSymbols(node)
343 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000344 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000345 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000346 self.emit('LOAD_CONST', node.doc)
347 self.storeName('__doc__')
348 lnf = walk(node.node, self.NameFinder(), verbose=0)
349 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000350 self.visit(node.node)
351 self.emit('LOAD_CONST', None)
352 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000353
Barry Warsaw52acb492001-12-21 20:04:22 +0000354 def visitExpression(self, node):
355 self.set_lineno(node)
356 self.scopes = self.parseSymbols(node)
357 self.scope = self.scopes[node]
358 self.visit(node.node)
359 self.emit('RETURN_VALUE')
360
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000361 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000362 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000363 if node.doc:
364 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000365 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000366
367 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000368 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000369
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000370 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000371 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000372 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000373 self.visit(decorator)
374 ndecorators = len(node.decorators.nodes)
375 else:
376 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000377
Jeremy Hylton37c93512001-09-17 18:03:55 +0000378 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000379 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000380 walk(node.code, gen)
381 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000382 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000383 for default in node.defaults:
384 self.visit(default)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000385 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000386 for i in range(ndecorators):
387 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000388
389 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000390 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000391 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000392 walk(node.code, gen)
393 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000394 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000395 self.emit('LOAD_CONST', node.name)
396 for base in node.bases:
397 self.visit(base)
398 self.emit('BUILD_TUPLE', len(node.bases))
Neil Schemenauer06ded092006-08-04 16:20:30 +0000399 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000400 self.emit('CALL_FUNCTION', 0)
401 self.emit('BUILD_CLASS')
402 self.storeName(node.name)
403
404 # The rest are standard visitor methods
405
406 # The next few implement control-flow statements
407
408 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000409 end = self.newBlock()
410 numtests = len(node.tests)
411 for i in range(numtests):
412 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000413 if is_constant_false(test):
414 # XXX will need to check generator stuff here
415 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000416 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000417 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000418 nextTest = self.newBlock()
419 self.emit('JUMP_IF_FALSE', nextTest)
420 self.nextBlock()
421 self.emit('POP_TOP')
422 self.visit(suite)
423 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000424 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000425 self.emit('POP_TOP')
426 if node.else_:
427 self.visit(node.else_)
428 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000429
430 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000431 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000432
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000433 loop = self.newBlock()
434 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000435
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000436 after = self.newBlock()
437 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000438
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000439 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000440 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000441
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000442 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000443 self.visit(node.test)
444 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000445
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000446 self.nextBlock()
447 self.emit('POP_TOP')
448 self.visit(node.body)
449 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000450
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000451 self.startBlock(else_) # or just the POPs if not else clause
452 self.emit('POP_TOP')
453 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000454 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000455 if node.else_:
456 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000458
459 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000461 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000462 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000463 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000464
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000465 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000466 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000467 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000468 self.emit('GET_ITER')
469
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000470 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000471 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000472 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000473 self.visit(node.assign)
474 self.visit(node.body)
475 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000476 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000477 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000478 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000479 if node.else_:
480 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000481 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000482
483 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000484 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000485 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000486 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000487 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000488 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000489
490 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000491 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000492 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000493 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000494 kind, block = self.setups.top()
495 if kind == LOOP:
496 self.set_lineno(node)
497 self.emit('JUMP_ABSOLUTE', block)
498 self.nextBlock()
499 elif kind == EXCEPT or kind == TRY_FINALLY:
500 self.set_lineno(node)
501 # find the block that starts the loop
502 top = len(self.setups)
503 while top > 0:
504 top = top - 1
505 kind, loop_block = self.setups[top]
506 if kind == LOOP:
507 break
508 if kind != LOOP:
509 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000510 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000511 self.emit('CONTINUE_LOOP', loop_block)
512 self.nextBlock()
513 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000514 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000515 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000516
517 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000518 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000519 for child in node.nodes[:-1]:
520 self.visit(child)
521 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000522 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000523 self.emit('POP_TOP')
524 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000525 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000526
527 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000528 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000529
530 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000531 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000533 def visitIfExp(self, node):
534 endblock = self.newBlock()
535 elseblock = self.newBlock()
536 self.visit(node.test)
537 self.emit('JUMP_IF_FALSE', elseblock)
538 self.emit('POP_TOP')
539 self.visit(node.then)
540 self.emit('JUMP_FORWARD', endblock)
541 self.nextBlock(elseblock)
542 self.emit('POP_TOP')
543 self.visit(node.else_)
544 self.nextBlock(endblock)
545
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000546 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000547 self.visit(node.expr)
548 cleanup = self.newBlock()
549 for op, code in node.ops[:-1]:
550 self.visit(code)
551 self.emit('DUP_TOP')
552 self.emit('ROT_THREE')
553 self.emit('COMPARE_OP', op)
554 self.emit('JUMP_IF_FALSE', cleanup)
555 self.nextBlock()
556 self.emit('POP_TOP')
557 # now do the last comparison
558 if node.ops:
559 op, code = node.ops[-1]
560 self.visit(code)
561 self.emit('COMPARE_OP', op)
562 if len(node.ops) > 1:
563 end = self.newBlock()
564 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000565 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000566 self.emit('ROT_TWO')
567 self.emit('POP_TOP')
568 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000569
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000570 # list comprehensions
571 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000572
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000573 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000574 self.set_lineno(node)
575 # setup list
576 append = "$append%d" % self.__list_count
577 self.__list_count = self.__list_count + 1
578 self.emit('BUILD_LIST', 0)
579 self.emit('DUP_TOP')
580 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000581 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000582
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000583 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000584 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000585 start, anchor = self.visit(for_)
586 cont = None
587 for if_ in for_.ifs:
588 if cont is None:
589 cont = self.newBlock()
590 self.visit(if_, cont)
591 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000592
Jeremy Hylton13d70942001-04-12 21:04:43 +0000593 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000594 self.visit(node.expr)
595 self.emit('CALL_FUNCTION', 1)
596 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000597
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000598 for start, cont, anchor in stack:
599 if cont:
600 skip_one = self.newBlock()
601 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000602 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000603 self.emit('POP_TOP')
604 self.nextBlock(skip_one)
605 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000606 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000607 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000608
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000609 self.__list_count = self.__list_count - 1
610
611 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000612 start = self.newBlock()
613 anchor = self.newBlock()
614
615 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000616 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000618 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000619 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000620 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000621 self.visit(node.assign)
622 return start, anchor
623
624 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000625 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000626 self.visit(node.test)
627 self.emit('JUMP_IF_FALSE', branch)
628 self.newBlock()
629 self.emit('POP_TOP')
630
Neil Schemenauer06ded092006-08-04 16:20:30 +0000631 def _makeClosure(self, gen, args):
632 frees = gen.scope.get_free_vars()
633 if frees:
634 for name in frees:
635 self.emit('LOAD_CLOSURE', name)
636 self.emit('BUILD_TUPLE', len(frees))
637 self.emit('LOAD_CONST', gen)
638 self.emit('MAKE_CLOSURE', args)
639 else:
640 self.emit('LOAD_CONST', gen)
641 self.emit('MAKE_FUNCTION', args)
642
Raymond Hettinger354433a2004-05-19 08:20:33 +0000643 def visitGenExpr(self, node):
644 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
645 self.get_module())
646 walk(node.code, gen)
647 gen.finish()
648 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000649 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000650 # precomputation of outmost iterable
651 self.visit(node.code.quals[0].iter)
652 self.emit('GET_ITER')
653 self.emit('CALL_FUNCTION', 1)
654
655 def visitGenExprInner(self, node):
656 self.set_lineno(node)
657 # setup list
658
659 stack = []
660 for i, for_ in zip(range(len(node.quals)), node.quals):
661 start, anchor = self.visit(for_)
662 cont = None
663 for if_ in for_.ifs:
664 if cont is None:
665 cont = self.newBlock()
666 self.visit(if_, cont)
667 stack.insert(0, (start, cont, anchor))
668
669 self.visit(node.expr)
670 self.emit('YIELD_VALUE')
671
672 for start, cont, anchor in stack:
673 if cont:
674 skip_one = self.newBlock()
675 self.emit('JUMP_FORWARD', skip_one)
676 self.startBlock(cont)
677 self.emit('POP_TOP')
678 self.nextBlock(skip_one)
679 self.emit('JUMP_ABSOLUTE', start)
680 self.startBlock(anchor)
681 self.emit('LOAD_CONST', None)
682
683 def visitGenExprFor(self, node):
684 start = self.newBlock()
685 anchor = self.newBlock()
Tim Peters4e0e1b62004-07-07 20:54:48 +0000686
Raymond Hettinger354433a2004-05-19 08:20:33 +0000687 if node.is_outmost:
688 self.loadName('[outmost-iterable]')
689 else:
690 self.visit(node.iter)
691 self.emit('GET_ITER')
692
693 self.nextBlock(start)
694 self.set_lineno(node, force=True)
695 self.emit('FOR_ITER', anchor)
696 self.nextBlock()
697 self.visit(node.assign)
698 return start, anchor
699
700 def visitGenExprIf(self, node, branch):
701 self.set_lineno(node, force=True)
702 self.visit(node.test)
703 self.emit('JUMP_IF_FALSE', branch)
704 self.newBlock()
705 self.emit('POP_TOP')
706
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000707 # exception related
708
709 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000710 # XXX would be interesting to implement this via a
711 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000712 if __debug__:
713 end = self.newBlock()
714 self.set_lineno(node)
715 # XXX AssertionError appears to be special case -- it is always
716 # loaded as a global even if there is a local name. I guess this
717 # is a sort of renaming op.
718 self.nextBlock()
719 self.visit(node.test)
720 self.emit('JUMP_IF_TRUE', end)
721 self.nextBlock()
722 self.emit('POP_TOP')
723 self.emit('LOAD_GLOBAL', 'AssertionError')
724 if node.fail:
725 self.visit(node.fail)
726 self.emit('RAISE_VARARGS', 2)
727 else:
728 self.emit('RAISE_VARARGS', 1)
729 self.nextBlock(end)
730 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000731
732 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000733 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000734 n = 0
735 if node.expr1:
736 self.visit(node.expr1)
737 n = n + 1
738 if node.expr2:
739 self.visit(node.expr2)
740 n = n + 1
741 if node.expr3:
742 self.visit(node.expr3)
743 n = n + 1
744 self.emit('RAISE_VARARGS', n)
745
746 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000747 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000748 handlers = self.newBlock()
749 end = self.newBlock()
750 if node.else_:
751 lElse = self.newBlock()
752 else:
753 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000754 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000755 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000756 self.nextBlock(body)
757 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000758 self.visit(node.body)
759 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000760 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000761 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000762 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000763
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000764 last = len(node.handlers) - 1
765 for i in range(len(node.handlers)):
766 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000767 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000768 if expr:
769 self.emit('DUP_TOP')
770 self.visit(expr)
771 self.emit('COMPARE_OP', 'exception match')
772 next = self.newBlock()
773 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000774 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 self.emit('POP_TOP')
776 self.emit('POP_TOP')
777 if target:
778 self.visit(target)
779 else:
780 self.emit('POP_TOP')
781 self.emit('POP_TOP')
782 self.visit(body)
783 self.emit('JUMP_FORWARD', end)
784 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000785 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000786 else:
787 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000788 if expr: # XXX
789 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000790 self.emit('END_FINALLY')
791 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000792 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000793 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000794 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000795
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000796 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000797 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000798 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000799 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000801 self.nextBlock(body)
802 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 self.visit(node.body)
804 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000805 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000806 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000807 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809 self.visit(node.final)
810 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000811 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000812
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000813 __with_count = 0
814
815 def visitWith(self, node):
816 body = self.newBlock()
817 final = self.newBlock()
818 exitvar = "$exit%d" % self.__with_count
819 valuevar = "$value%d" % self.__with_count
820 self.__with_count += 1
821 self.set_lineno(node)
822 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000823 self.emit('DUP_TOP')
824 self.emit('LOAD_ATTR', '__exit__')
825 self._implicitNameOp('STORE', exitvar)
826 self.emit('LOAD_ATTR', '__enter__')
827 self.emit('CALL_FUNCTION', 0)
828 if node.vars is None:
829 self.emit('POP_TOP')
830 else:
831 self._implicitNameOp('STORE', valuevar)
832 self.emit('SETUP_FINALLY', final)
833 self.nextBlock(body)
834 self.setups.push((TRY_FINALLY, body))
835 if node.vars is not None:
836 self._implicitNameOp('LOAD', valuevar)
837 self._implicitNameOp('DELETE', valuevar)
838 self.visit(node.vars)
839 self.visit(node.body)
840 self.emit('POP_BLOCK')
841 self.setups.pop()
842 self.emit('LOAD_CONST', None)
843 self.nextBlock(final)
844 self.setups.push((END_FINALLY, final))
845 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000846 self.emit('END_FINALLY')
847 self.setups.pop()
848 self.__with_count -= 1
849
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000850 # misc
851
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000852 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000853 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000854 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000855 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000856
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000857 def visitConst(self, node):
858 self.emit('LOAD_CONST', node.value)
859
860 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000861 self.emit('LOAD_CONST', node.name)
862 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000863
864 def visitGlobal(self, node):
865 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000866 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000867
868 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000869 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000870 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000871
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000872 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000873 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000874
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000875 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000876 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000877 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000878 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000879 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000880 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000881 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000882 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000883 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000884 if alias:
885 self._resolveDots(name)
886 self.storeName(alias)
887 else:
888 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000889
890 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000891 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000892 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000893 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000894 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000895 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000896 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000897 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000898 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000899 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000900 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000901 if VERSION > 1:
902 if name == '*':
903 self.namespace = 0
904 self.emit('IMPORT_STAR')
905 # There can only be one name w/ from ... import *
906 assert len(node.names) == 1
907 return
908 else:
909 self.emit('IMPORT_FROM', name)
910 self._resolveDots(name)
911 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000912 else:
913 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000914 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000915
Jeremy Hylton20516082000-09-01 20:33:26 +0000916 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000917 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000918 if len(elts) == 1:
919 return
920 for elt in elts[1:]:
921 self.emit('LOAD_ATTR', elt)
922
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000923 def visitGetattr(self, node):
924 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000925 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000926
927 # next five implement assignments
928
929 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000930 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000931 self.visit(node.expr)
932 dups = len(node.nodes) - 1
933 for i in range(len(node.nodes)):
934 elt = node.nodes[i]
935 if i < dups:
936 self.emit('DUP_TOP')
937 if isinstance(elt, ast.Node):
938 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000939
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000940 def visitAssName(self, node):
941 if node.flags == 'OP_ASSIGN':
942 self.storeName(node.name)
943 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000944 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000945 self.delName(node.name)
946 else:
947 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000948
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000949 def visitAssAttr(self, node):
950 self.visit(node.expr)
951 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000952 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000954 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000955 else:
956 print "warning: unexpected flags:", node.flags
957 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000958
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000959 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000960 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000961 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000962 for child in node.nodes:
963 self.visit(child)
964
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000965 if VERSION > 1:
966 visitAssTuple = _visitAssSequence
967 visitAssList = _visitAssSequence
968 else:
969 def visitAssTuple(self, node):
970 self._visitAssSequence(node, 'UNPACK_TUPLE')
971
972 def visitAssList(self, node):
973 self._visitAssSequence(node, 'UNPACK_LIST')
974
975 # augmented assignment
976
977 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000978 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000979 aug_node = wrap_aug(node.node)
980 self.visit(aug_node, "load")
981 self.visit(node.expr)
982 self.emit(self._augmented_opcode[node.op])
983 self.visit(aug_node, "store")
984
985 _augmented_opcode = {
986 '+=' : 'INPLACE_ADD',
987 '-=' : 'INPLACE_SUBTRACT',
988 '*=' : 'INPLACE_MULTIPLY',
989 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000990 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000991 '%=' : 'INPLACE_MODULO',
992 '**=': 'INPLACE_POWER',
993 '>>=': 'INPLACE_RSHIFT',
994 '<<=': 'INPLACE_LSHIFT',
995 '&=' : 'INPLACE_AND',
996 '^=' : 'INPLACE_XOR',
997 '|=' : 'INPLACE_OR',
998 }
999
1000 def visitAugName(self, node, mode):
1001 if mode == "load":
1002 self.loadName(node.name)
1003 elif mode == "store":
1004 self.storeName(node.name)
1005
1006 def visitAugGetattr(self, node, mode):
1007 if mode == "load":
1008 self.visit(node.expr)
1009 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001010 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001011 elif mode == "store":
1012 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001013 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001014
1015 def visitAugSlice(self, node, mode):
1016 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001017 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001018 elif mode == "store":
1019 slice = 0
1020 if node.lower:
1021 slice = slice | 1
1022 if node.upper:
1023 slice = slice | 2
1024 if slice == 0:
1025 self.emit('ROT_TWO')
1026 elif slice == 3:
1027 self.emit('ROT_FOUR')
1028 else:
1029 self.emit('ROT_THREE')
1030 self.emit('STORE_SLICE+%d' % slice)
1031
1032 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001033 if mode == "load":
1034 self.visitSubscript(node, 1)
1035 elif mode == "store":
1036 self.emit('ROT_THREE')
1037 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001038
1039 def visitExec(self, node):
1040 self.visit(node.expr)
1041 if node.locals is None:
1042 self.emit('LOAD_CONST', None)
1043 else:
1044 self.visit(node.locals)
1045 if node.globals is None:
1046 self.emit('DUP_TOP')
1047 else:
1048 self.visit(node.globals)
1049 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001050
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001051 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001052 pos = 0
1053 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001054 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001055 self.visit(node.node)
1056 for arg in node.args:
1057 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001058 if isinstance(arg, ast.Keyword):
1059 kw = kw + 1
1060 else:
1061 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001062 if node.star_args is not None:
1063 self.visit(node.star_args)
1064 if node.dstar_args is not None:
1065 self.visit(node.dstar_args)
1066 have_star = node.star_args is not None
1067 have_dstar = node.dstar_args is not None
1068 opcode = callfunc_opcode_info[have_star, have_dstar]
1069 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001070
Jeremy Hylton2afff322001-08-27 21:51:52 +00001071 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001072 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001073 if node.dest:
1074 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001075 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001076 if node.dest:
1077 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001078 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001079 if node.dest:
1080 self.emit('ROT_TWO')
1081 self.emit('PRINT_ITEM_TO')
1082 else:
1083 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001084 if node.dest and not newline:
1085 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001086
1087 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001088 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001089 if node.dest:
1090 self.emit('PRINT_NEWLINE_TO')
1091 else:
1092 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001093
1094 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001095 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001096 self.visit(node.value)
1097 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001098
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001099 def visitYield(self, node):
1100 self.set_lineno(node)
1101 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001102 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001103
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001104 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001105
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001106 def visitSlice(self, node, aug_flag=None):
1107 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001108 self.visit(node.expr)
1109 slice = 0
1110 if node.lower:
1111 self.visit(node.lower)
1112 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001113 if node.upper:
1114 self.visit(node.upper)
1115 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001116 if aug_flag:
1117 if slice == 0:
1118 self.emit('DUP_TOP')
1119 elif slice == 3:
1120 self.emit('DUP_TOPX', 3)
1121 else:
1122 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001123 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001124 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001125 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001126 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001127 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001128 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001129 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001130 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001131 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001133 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001134 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001135 for sub in node.subs:
1136 self.visit(sub)
1137 if len(node.subs) > 1:
1138 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001139 if aug_flag:
1140 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001141 if node.flags == 'OP_APPLY':
1142 self.emit('BINARY_SUBSCR')
1143 elif node.flags == 'OP_ASSIGN':
1144 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001145 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001146 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001147
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001148 # binary ops
1149
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001150 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001151 self.visit(node.left)
1152 self.visit(node.right)
1153 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001154
1155 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001156 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001157
1158 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001159 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001160
1161 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001162 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001163
1164 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001165 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001166
Jeremy Hylton94afe322001-08-29 18:14:39 +00001167 def visitFloorDiv(self, node):
1168 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1169
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001170 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001171 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001172
Jeremy Hylton126960b2000-02-14 21:33:10 +00001173 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001174 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001175
1176 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001177 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001178
1179 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001180 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001181
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001182 # unary ops
1183
1184 def unaryOp(self, node, op):
1185 self.visit(node.expr)
1186 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001187
Jeremy Hylton126960b2000-02-14 21:33:10 +00001188 def visitInvert(self, node):
1189 return self.unaryOp(node, 'UNARY_INVERT')
1190
Jeremy Hylton40245602000-02-08 21:15:48 +00001191 def visitUnarySub(self, node):
1192 return self.unaryOp(node, 'UNARY_NEGATIVE')
1193
1194 def visitUnaryAdd(self, node):
1195 return self.unaryOp(node, 'UNARY_POSITIVE')
1196
1197 def visitUnaryInvert(self, node):
1198 return self.unaryOp(node, 'UNARY_INVERT')
1199
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001200 def visitNot(self, node):
1201 return self.unaryOp(node, 'UNARY_NOT')
1202
Jeremy Hylton40245602000-02-08 21:15:48 +00001203 def visitBackquote(self, node):
1204 return self.unaryOp(node, 'UNARY_CONVERT')
1205
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001206 # bit ops
1207
Jeremy Hyltona5058122000-02-14 14:14:29 +00001208 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001209 self.visit(nodes[0])
1210 for node in nodes[1:]:
1211 self.visit(node)
1212 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001213
1214 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001215 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001216
1217 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001218 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001219
1220 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001221 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001222
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001223 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001224
Jeremy Hyltona5058122000-02-14 14:14:29 +00001225 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001226 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001227
Jeremy Hylton40245602000-02-08 21:15:48 +00001228 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001229 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001230 for elt in node.nodes:
1231 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001232 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001233
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001234 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001235 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001236 for elt in node.nodes:
1237 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001238 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001239
1240 def visitSliceobj(self, node):
1241 for child in node.nodes:
1242 self.visit(child)
1243 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001244
Jeremy Hyltona5058122000-02-14 14:14:29 +00001245 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001246 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001247 self.emit('BUILD_MAP', 0)
1248 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001249 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001250 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001251 self.visit(v)
1252 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001253 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001254
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001255class NestedScopeMixin:
1256 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001257 def initClass(self):
1258 self.__class__.NameFinder = LocalNameFinder
1259 self.__class__.FunctionGen = FunctionCodeGenerator
1260 self.__class__.ClassGen = ClassCodeGenerator
1261
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001262class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001263 __super_init = CodeGenerator.__init__
1264
1265 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001266
Jeremy Hylton37c93512001-09-17 18:03:55 +00001267 def __init__(self, tree):
1268 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001269 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001270 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001271 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001272
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001273 def get_module(self):
1274 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001275
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001276class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1277 __super_init = CodeGenerator.__init__
1278
1279 scopes = None
1280 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001281
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001282 def __init__(self, tree):
1283 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1284 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001285 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001286
1287 def get_module(self):
1288 return self
1289
1290class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1291
1292 __super_init = CodeGenerator.__init__
1293
1294 scopes = None
1295 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001296
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001297 def __init__(self, tree):
1298 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1299 self.__super_init()
1300 self.set_lineno(tree)
1301 walk(tree, self)
1302 self.emit('RETURN_VALUE')
1303
1304 def get_module(self):
1305 return self
Tim Peterse4418602002-02-16 07:34:19 +00001306
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001307 def visitDiscard(self, node):
1308 # XXX Discard means it's an expression. Perhaps this is a bad
1309 # name.
1310 self.visit(node.expr)
1311 self.emit('PRINT_EXPR')
1312
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001313class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001314 optimized = 1
1315 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001316
Jeremy Hylton37c93512001-09-17 18:03:55 +00001317 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001318 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001319 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001320 if isLambda:
1321 klass = FunctionCodeGenerator
1322 name = "<lambda.%d>" % klass.lambdaCount
1323 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001324 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001325 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001326
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001327 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001328 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1329 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001330 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001331 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001332
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001333 if not isLambda and func.doc:
1334 self.setDocstring(func.doc)
1335
Jeremy Hylton2afff322001-08-27 21:51:52 +00001336 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001337 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001338 if func.varargs:
1339 self.graph.setFlag(CO_VARARGS)
1340 if func.kwargs:
1341 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001342 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001343 if hasTupleArg:
1344 self.generateArgUnpack(func.argnames)
1345
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001346 def get_module(self):
1347 return self.module
1348
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001349 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001350 self.graph.startExitBlock()
1351 if not self.isLambda:
1352 self.emit('LOAD_CONST', None)
1353 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001354
1355 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001356 for i in range(len(args)):
1357 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001358 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001359 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001360 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001361
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001362 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001363 if VERSION > 1:
1364 self.emit('UNPACK_SEQUENCE', len(tup))
1365 else:
1366 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001367 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001368 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001369 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001370 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001371 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001372
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001373 unpackTuple = unpackSequence
1374
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001375class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001376 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001377 super_init = CodeGenerator.__init__ # call be other init
1378 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001379
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001380 __super_init = AbstractFunctionCode.__init__
1381
Jeremy Hylton37c93512001-09-17 18:03:55 +00001382 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001383 self.scopes = scopes
1384 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001385 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001386 self.graph.setFreeVars(self.scope.get_free_vars())
1387 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001388 if self.scope.generator is not None:
1389 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001390
Raymond Hettinger354433a2004-05-19 08:20:33 +00001391class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1392 CodeGenerator):
1393 super_init = CodeGenerator.__init__ # call be other init
1394 scopes = None
1395
1396 __super_init = AbstractFunctionCode.__init__
1397
1398 def __init__(self, gexp, scopes, class_name, mod):
1399 self.scopes = scopes
1400 self.scope = scopes[gexp]
1401 self.__super_init(gexp, scopes, 1, class_name, mod)
1402 self.graph.setFreeVars(self.scope.get_free_vars())
1403 self.graph.setCellVars(self.scope.get_cell_vars())
1404 self.graph.setFlag(CO_GENERATOR)
1405
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001406class AbstractClassCode:
1407
Jeremy Hylton37c93512001-09-17 18:03:55 +00001408 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001409 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001410 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001411 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001412 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001413 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001414 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001415 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001416 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001417 if klass.doc:
1418 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001419
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001420 def get_module(self):
1421 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001422
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001423 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001424 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001425 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001426 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001427
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001428class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001429 super_init = CodeGenerator.__init__
1430 scopes = None
1431
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001432 __super_init = AbstractClassCode.__init__
1433
Jeremy Hylton37c93512001-09-17 18:03:55 +00001434 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001435 self.scopes = scopes
1436 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001437 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001438 self.graph.setFreeVars(self.scope.get_free_vars())
1439 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001440 self.set_lineno(klass)
1441 self.emit("LOAD_GLOBAL", "__name__")
1442 self.storeName("__module__")
1443 if klass.doc:
1444 self.emit("LOAD_CONST", klass.doc)
1445 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001446
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001447def generateArgList(arglist):
1448 """Generate an arg list marking TupleArgs"""
1449 args = []
1450 extra = []
1451 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001452 for i in range(len(arglist)):
1453 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001454 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001455 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001456 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001457 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001458 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001459 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001460 else:
1461 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001462 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001463
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001464def findOp(node):
1465 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1466 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001467 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001468 return v.op
1469
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001470class OpFinder:
1471 def __init__(self):
1472 self.op = None
1473 def visitAssName(self, node):
1474 if self.op is None:
1475 self.op = node.flags
1476 elif self.op != node.flags:
1477 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001478 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001479 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001480
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001481class Delegator:
1482 """Base class to support delegation for augmented assignment nodes
1483
1484 To generator code for augmented assignments, we use the following
1485 wrapper classes. In visitAugAssign, the left-hand expression node
1486 is visited twice. The first time the visit uses the normal method
1487 for that node . The second time the visit uses a different method
1488 that generates the appropriate code to perform the assignment.
1489 These delegator classes wrap the original AST nodes in order to
1490 support the variant visit methods.
1491 """
1492 def __init__(self, obj):
1493 self.obj = obj
1494
1495 def __getattr__(self, attr):
1496 return getattr(self.obj, attr)
1497
1498class AugGetattr(Delegator):
1499 pass
1500
1501class AugName(Delegator):
1502 pass
1503
1504class AugSlice(Delegator):
1505 pass
1506
1507class AugSubscript(Delegator):
1508 pass
1509
1510wrapper = {
1511 ast.Getattr: AugGetattr,
1512 ast.Name: AugName,
1513 ast.Slice: AugSlice,
1514 ast.Subscript: AugSubscript,
1515 }
1516
1517def wrap_aug(node):
1518 return wrapper[node.__class__](node)
1519
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001520if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001521 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001522 compileFile(file)