blob: 5d5dca0d99081fa51ca7170f48d02d3a488b9548 [file] [log] [blame]
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001import imp
Jeremy Hylton53187f32000-02-08 19:01:29 +00002import os
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00003import marshal
Jeremy Hylton53187f32000-02-08 19:01:29 +00004import struct
Jeremy Hylton9c048f92000-10-13 21:58:13 +00005import sys
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00006from cStringIO import StringIO
7
Jeremy Hylton37c93512001-09-17 18:03:55 +00008from compiler import ast, parse, walk, syntax
Jeremy Hylton364f9b92001-04-12 06:40:42 +00009from compiler import pyassem, misc, future, symbols
10from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000011from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
Neal Norwitzeaed39f2006-03-03 19:12:58 +000012 CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
Eric Smith5d5c63f2008-03-19 02:11:30 +000013 CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton71ebc332001-08-30 20:25:55 +000014from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000015
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000016# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000017# Do we have Python 1.x or Python 2.x?
18try:
19 VERSION = sys.version_info[0]
20except AttributeError:
21 VERSION = 1
22
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000023callfunc_opcode_info = {
24 # (Have *args, Have **args) : opcode
25 (0,0) : "CALL_FUNCTION",
26 (1,0) : "CALL_FUNCTION_VAR",
27 (0,1) : "CALL_FUNCTION_KW",
28 (1,1) : "CALL_FUNCTION_VAR_KW",
29}
30
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000031LOOP = 1
32EXCEPT = 2
33TRY_FINALLY = 3
34END_FINALLY = 4
35
Jeremy Hylton9dca3642001-09-17 21:02:51 +000036def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000037 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000038 buf = f.read()
39 f.close()
40 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000041 try:
42 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000043 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000044 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000045 else:
46 f = open(filename + "c", "wb")
47 mod.dump(f)
48 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000049
Jeremy Hylton9dca3642001-09-17 21:02:51 +000050def compile(source, filename, mode, flags=None, dont_inherit=None):
51 """Replacement for builtin compile() function"""
52 if flags is not None or dont_inherit is not None:
53 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000054
Jeremy Hylton9dca3642001-09-17 21:02:51 +000055 if mode == "single":
56 gen = Interactive(source, filename)
57 elif mode == "exec":
58 gen = Module(source, filename)
59 elif mode == "eval":
60 gen = Expression(source, filename)
61 else:
62 raise ValueError("compile() 3rd arg must be 'exec' or "
63 "'eval' or 'single'")
64 gen.compile()
65 return gen.code
66
67class AbstractCompileMode:
68
69 mode = None # defined by subclass
70
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000071 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000072 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000073 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000074 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000075
Jeremy Hylton9dca3642001-09-17 21:02:51 +000076 def _get_tree(self):
77 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000078 misc.set_filename(self.filename, tree)
79 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000080 return tree
81
82 def compile(self):
83 pass # implemented by subclass
84
85 def getCode(self):
86 return self.code
87
88class Expression(AbstractCompileMode):
89
90 mode = "eval"
91
92 def compile(self):
93 tree = self._get_tree()
94 gen = ExpressionCodeGenerator(tree)
95 self.code = gen.getCode()
96
97class Interactive(AbstractCompileMode):
98
99 mode = "single"
100
101 def compile(self):
102 tree = self._get_tree()
103 gen = InteractiveCodeGenerator(tree)
104 self.code = gen.getCode()
105
106class Module(AbstractCompileMode):
107
108 mode = "exec"
109
110 def compile(self, display=0):
111 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000112 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000113 if display:
114 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000115 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000116 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000117
118 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000119 f.write(self.getPycHeader())
120 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000121
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000122 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000123
124 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000125 # compile.c uses marshal to write a long directly, with
126 # calling the interface that would also generate a 1-byte code
127 # to indicate the type of the value. simplest way to get the
128 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000129 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000130 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000131 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000132
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000133class LocalNameFinder:
134 """Find local names in scope"""
135 def __init__(self, names=()):
136 self.names = misc.Set()
137 self.globals = misc.Set()
138 for name in names:
139 self.names.add(name)
140
141 # XXX list comprehensions and for loops
142
143 def getLocals(self):
144 for elt in self.globals.elements():
145 if self.names.has_elt(elt):
146 self.names.remove(elt)
147 return self.names
148
149 def visitDict(self, node):
150 pass
151
152 def visitGlobal(self, node):
153 for name in node.names:
154 self.globals.add(name)
155
156 def visitFunction(self, node):
157 self.names.add(node.name)
158
159 def visitLambda(self, node):
160 pass
161
162 def visitImport(self, node):
163 for name, alias in node.names:
164 self.names.add(alias or name)
165
166 def visitFrom(self, node):
167 for name, alias in node.names:
168 self.names.add(alias or name)
169
170 def visitClass(self, node):
171 self.names.add(node.name)
172
173 def visitAssName(self, node):
174 self.names.add(node.name)
175
Jeremy Hylton2afff322001-08-27 21:51:52 +0000176def is_constant_false(node):
177 if isinstance(node, ast.Const):
178 if not node.value:
179 return 1
180 return 0
181
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000182class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000183 """Defines basic code generator for Python bytecode
184
185 This class is an abstract base class. Concrete subclasses must
186 define an __init__() that defines self.graph and then calls the
187 __init__() defined in this class.
188
189 The concrete class must also define the class attributes
190 NameFinder, FunctionGen, and ClassGen. These attributes can be
191 defined in the initClass() method, which is a hook for
192 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000193 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000194 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000195
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000196 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000197 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000198 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000199
Jeremy Hylton37c93512001-09-17 18:03:55 +0000200 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000201 if self.__initialized is None:
202 self.initClass()
203 self.__class__.__initialized = 1
204 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000205 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000206 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000207 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000208 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000209 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000210
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000211 # XXX set flags based on future features
212 futures = self.get_module().futures
213 for feature in futures:
214 if feature == "division":
215 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000216 self._div_op = "BINARY_TRUE_DIVIDE"
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000217 elif feature == "absolute_import":
218 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
219 elif feature == "with_statement":
220 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Eric Smith5d5c63f2008-03-19 02:11:30 +0000221 elif feature == "print_function":
222 self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000223
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000224 def initClass(self):
225 """This method is called once for each class"""
226
227 def checkClass(self):
228 """Verify that class is constructed correctly"""
229 try:
230 assert hasattr(self, 'graph')
231 assert getattr(self, 'NameFinder')
232 assert getattr(self, 'FunctionGen')
233 assert getattr(self, 'ClassGen')
234 except AssertionError, msg:
235 intro = "Bad class construction for %s" % self.__class__.__name__
236 raise AssertionError, intro
237
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000238 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000239 self.emit = self.graph.emit
240 self.newBlock = self.graph.newBlock
241 self.startBlock = self.graph.startBlock
242 self.nextBlock = self.graph.nextBlock
243 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000244
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000245 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000246 """Return a code object"""
247 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000248
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000249 def mangle(self, name):
250 if self.class_name is not None:
251 return misc.mangle(name, self.class_name)
252 else:
253 return name
254
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000255 def parseSymbols(self, tree):
256 s = symbols.SymbolVisitor()
257 walk(tree, s)
258 return s.scopes
259
260 def get_module(self):
261 raise RuntimeError, "should be implemented by subclasses"
262
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000263 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000264
Jeremy Hylton40245602000-02-08 21:15:48 +0000265 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000266 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000267
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000268 def storeName(self, name):
269 self._nameOp('STORE', name)
270
271 def loadName(self, name):
272 self._nameOp('LOAD', name)
273
274 def delName(self, name):
275 self._nameOp('DELETE', name)
276
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000277 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000278 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000279 scope = self.scope.check_name(name)
280 if scope == SC_LOCAL:
281 if not self.optimized:
282 self.emit(prefix + '_NAME', name)
283 else:
284 self.emit(prefix + '_FAST', name)
285 elif scope == SC_GLOBAL:
286 if not self.optimized:
287 self.emit(prefix + '_NAME', name)
288 else:
289 self.emit(prefix + '_GLOBAL', name)
290 elif scope == SC_FREE or scope == SC_CELL:
291 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000292 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000293 raise RuntimeError, "unsupported scope for var %s: %d" % \
294 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000295
Jeremy Hylton13d70942001-04-12 21:04:43 +0000296 def _implicitNameOp(self, prefix, name):
297 """Emit name ops for names generated implicitly by for loops
298
299 The interpreter generates names that start with a period or
300 dollar sign. The symbol table ignores these names because
301 they aren't present in the program text.
302 """
303 if self.optimized:
304 self.emit(prefix + '_FAST', name)
305 else:
306 self.emit(prefix + '_NAME', name)
307
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000308 # The set_lineno() function and the explicit emit() calls for
309 # SET_LINENO below are only used to generate the line number table.
310 # As of Python 2.3, the interpreter does not have a SET_LINENO
311 # instruction. pyassem treats SET_LINENO opcodes as a special case.
312
313 def set_lineno(self, node, force=False):
314 """Emit SET_LINENO if necessary.
315
316 The instruction is considered necessary if the node has a
317 lineno attribute and it is different than the last lineno
318 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000319
320 Returns true if SET_LINENO was emitted.
321
322 There are no rules for when an AST node should have a lineno
323 attribute. The transformer and AST code need to be reviewed
324 and a consistent policy implemented and documented. Until
325 then, this method works around missing line numbers.
326 """
327 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000328 if lineno is not None and (lineno != self.last_lineno
329 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000330 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000331 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000332 return True
333 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000334
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000335 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000336 # code objects. They use class attributes to determine what
337 # specialized code generators to use.
338
339 NameFinder = LocalNameFinder
340 FunctionGen = None
341 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000342
343 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000344 self.scopes = self.parseSymbols(node)
345 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000346 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000347 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000348 self.emit('LOAD_CONST', node.doc)
349 self.storeName('__doc__')
350 lnf = walk(node.node, self.NameFinder(), verbose=0)
351 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000352 self.visit(node.node)
353 self.emit('LOAD_CONST', None)
354 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000355
Barry Warsaw52acb492001-12-21 20:04:22 +0000356 def visitExpression(self, node):
357 self.set_lineno(node)
358 self.scopes = self.parseSymbols(node)
359 self.scope = self.scopes[node]
360 self.visit(node.node)
361 self.emit('RETURN_VALUE')
362
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000363 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000364 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000365 if node.doc:
366 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000367 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000368
369 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000370 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000371
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000372 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000373 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000374 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000375 self.visit(decorator)
376 ndecorators = len(node.decorators.nodes)
377 else:
378 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000379
Jeremy Hylton37c93512001-09-17 18:03:55 +0000380 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000381 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000382 walk(node.code, gen)
383 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000384 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000385 for default in node.defaults:
386 self.visit(default)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000387 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000388 for i in range(ndecorators):
389 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000390
391 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000392 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000393 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000394 walk(node.code, gen)
395 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000396 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000397 self.emit('LOAD_CONST', node.name)
398 for base in node.bases:
399 self.visit(base)
400 self.emit('BUILD_TUPLE', len(node.bases))
Neil Schemenauer06ded092006-08-04 16:20:30 +0000401 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000402 self.emit('CALL_FUNCTION', 0)
403 self.emit('BUILD_CLASS')
404 self.storeName(node.name)
405
406 # The rest are standard visitor methods
407
408 # The next few implement control-flow statements
409
410 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000411 end = self.newBlock()
412 numtests = len(node.tests)
413 for i in range(numtests):
414 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000415 if is_constant_false(test):
416 # XXX will need to check generator stuff here
417 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000418 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000419 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000420 nextTest = self.newBlock()
421 self.emit('JUMP_IF_FALSE', nextTest)
422 self.nextBlock()
423 self.emit('POP_TOP')
424 self.visit(suite)
425 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000426 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000427 self.emit('POP_TOP')
428 if node.else_:
429 self.visit(node.else_)
430 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000431
432 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000433 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000434
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000435 loop = self.newBlock()
436 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000437
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000438 after = self.newBlock()
439 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000440
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000441 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000442 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000444 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000445 self.visit(node.test)
446 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000447
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000448 self.nextBlock()
449 self.emit('POP_TOP')
450 self.visit(node.body)
451 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000452
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000453 self.startBlock(else_) # or just the POPs if not else clause
454 self.emit('POP_TOP')
455 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000456 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 if node.else_:
458 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000459 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000460
461 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000462 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000463 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000465 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000466
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000467 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000468 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000469 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000470 self.emit('GET_ITER')
471
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000472 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000473 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000474 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475 self.visit(node.assign)
476 self.visit(node.body)
477 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000478 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000479 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000480 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481 if node.else_:
482 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000483 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000484
485 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000486 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000487 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000488 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000489 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000490 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000491
492 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000493 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000494 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000495 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000496 kind, block = self.setups.top()
497 if kind == LOOP:
498 self.set_lineno(node)
499 self.emit('JUMP_ABSOLUTE', block)
500 self.nextBlock()
501 elif kind == EXCEPT or kind == TRY_FINALLY:
502 self.set_lineno(node)
503 # find the block that starts the loop
504 top = len(self.setups)
505 while top > 0:
506 top = top - 1
507 kind, loop_block = self.setups[top]
508 if kind == LOOP:
509 break
510 if kind != LOOP:
511 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000512 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000513 self.emit('CONTINUE_LOOP', loop_block)
514 self.nextBlock()
515 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000516 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000517 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000518
519 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000520 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000521 for child in node.nodes[:-1]:
522 self.visit(child)
523 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000524 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000525 self.emit('POP_TOP')
526 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000527 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000528
529 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000530 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000531
532 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000533 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000534
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000535 def visitIfExp(self, node):
536 endblock = self.newBlock()
537 elseblock = self.newBlock()
538 self.visit(node.test)
539 self.emit('JUMP_IF_FALSE', elseblock)
540 self.emit('POP_TOP')
541 self.visit(node.then)
542 self.emit('JUMP_FORWARD', endblock)
543 self.nextBlock(elseblock)
544 self.emit('POP_TOP')
545 self.visit(node.else_)
546 self.nextBlock(endblock)
547
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000548 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000549 self.visit(node.expr)
550 cleanup = self.newBlock()
551 for op, code in node.ops[:-1]:
552 self.visit(code)
553 self.emit('DUP_TOP')
554 self.emit('ROT_THREE')
555 self.emit('COMPARE_OP', op)
556 self.emit('JUMP_IF_FALSE', cleanup)
557 self.nextBlock()
558 self.emit('POP_TOP')
559 # now do the last comparison
560 if node.ops:
561 op, code = node.ops[-1]
562 self.visit(code)
563 self.emit('COMPARE_OP', op)
564 if len(node.ops) > 1:
565 end = self.newBlock()
566 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000567 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000568 self.emit('ROT_TWO')
569 self.emit('POP_TOP')
570 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000571
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000572 # list comprehensions
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
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000576 self.emit('BUILD_LIST', 0)
Tim Peterse0c446b2001-10-18 21:57:37 +0000577
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000578 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000579 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000580 start, anchor = self.visit(for_)
581 cont = None
582 for if_ in for_.ifs:
583 if cont is None:
584 cont = self.newBlock()
585 self.visit(if_, cont)
586 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000587
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000588 self.visit(node.expr)
Antoine Pitroud0c35152008-12-17 00:38:28 +0000589 self.emit('LIST_APPEND', len(node.quals) + 1)
Tim Peterse0c446b2001-10-18 21:57:37 +0000590
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000591 for start, cont, anchor in stack:
592 if cont:
593 skip_one = self.newBlock()
594 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000595 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000596 self.emit('POP_TOP')
597 self.nextBlock(skip_one)
598 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000599 self.startBlock(anchor)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000600
601 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000602 start = self.newBlock()
603 anchor = self.newBlock()
604
605 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000606 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000607 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000608 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000609 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000610 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000611 self.visit(node.assign)
612 return start, anchor
613
614 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000615 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000616 self.visit(node.test)
617 self.emit('JUMP_IF_FALSE', branch)
618 self.newBlock()
619 self.emit('POP_TOP')
620
Neil Schemenauer06ded092006-08-04 16:20:30 +0000621 def _makeClosure(self, gen, args):
622 frees = gen.scope.get_free_vars()
623 if frees:
624 for name in frees:
625 self.emit('LOAD_CLOSURE', name)
626 self.emit('BUILD_TUPLE', len(frees))
627 self.emit('LOAD_CONST', gen)
628 self.emit('MAKE_CLOSURE', args)
629 else:
630 self.emit('LOAD_CONST', gen)
631 self.emit('MAKE_FUNCTION', args)
632
Raymond Hettinger354433a2004-05-19 08:20:33 +0000633 def visitGenExpr(self, node):
634 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
635 self.get_module())
636 walk(node.code, gen)
637 gen.finish()
638 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000639 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000640 # precomputation of outmost iterable
641 self.visit(node.code.quals[0].iter)
642 self.emit('GET_ITER')
643 self.emit('CALL_FUNCTION', 1)
644
645 def visitGenExprInner(self, node):
646 self.set_lineno(node)
647 # setup list
648
649 stack = []
650 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000651 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000652 cont = None
653 for if_ in for_.ifs:
654 if cont is None:
655 cont = self.newBlock()
656 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000657 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000658
659 self.visit(node.expr)
660 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000661 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000662
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000663 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000664 if cont:
665 skip_one = self.newBlock()
666 self.emit('JUMP_FORWARD', skip_one)
667 self.startBlock(cont)
668 self.emit('POP_TOP')
669 self.nextBlock(skip_one)
670 self.emit('JUMP_ABSOLUTE', start)
671 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000672 self.emit('POP_BLOCK')
673 self.setups.pop()
674 self.startBlock(end)
675
Raymond Hettinger354433a2004-05-19 08:20:33 +0000676 self.emit('LOAD_CONST', None)
677
678 def visitGenExprFor(self, node):
679 start = self.newBlock()
680 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000681 end = self.newBlock()
682
683 self.setups.push((LOOP, start))
684 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000685
Raymond Hettinger354433a2004-05-19 08:20:33 +0000686 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000687 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000688 else:
689 self.visit(node.iter)
690 self.emit('GET_ITER')
691
692 self.nextBlock(start)
693 self.set_lineno(node, force=True)
694 self.emit('FOR_ITER', anchor)
695 self.nextBlock()
696 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000697 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000698
699 def visitGenExprIf(self, node, branch):
700 self.set_lineno(node, force=True)
701 self.visit(node.test)
702 self.emit('JUMP_IF_FALSE', branch)
703 self.newBlock()
704 self.emit('POP_TOP')
705
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000706 # exception related
707
708 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000709 # XXX would be interesting to implement this via a
710 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000711 if __debug__:
712 end = self.newBlock()
713 self.set_lineno(node)
714 # XXX AssertionError appears to be special case -- it is always
715 # loaded as a global even if there is a local name. I guess this
716 # is a sort of renaming op.
717 self.nextBlock()
718 self.visit(node.test)
719 self.emit('JUMP_IF_TRUE', end)
720 self.nextBlock()
721 self.emit('POP_TOP')
722 self.emit('LOAD_GLOBAL', 'AssertionError')
723 if node.fail:
724 self.visit(node.fail)
725 self.emit('RAISE_VARARGS', 2)
726 else:
727 self.emit('RAISE_VARARGS', 1)
728 self.nextBlock(end)
729 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000730
731 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000732 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000733 n = 0
734 if node.expr1:
735 self.visit(node.expr1)
736 n = n + 1
737 if node.expr2:
738 self.visit(node.expr2)
739 n = n + 1
740 if node.expr3:
741 self.visit(node.expr3)
742 n = n + 1
743 self.emit('RAISE_VARARGS', n)
744
745 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000746 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000747 handlers = self.newBlock()
748 end = self.newBlock()
749 if node.else_:
750 lElse = self.newBlock()
751 else:
752 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000753 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000754 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000755 self.nextBlock(body)
756 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000757 self.visit(node.body)
758 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000759 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000760 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000761 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000762
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000763 last = len(node.handlers) - 1
764 for i in range(len(node.handlers)):
765 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000766 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000767 if expr:
768 self.emit('DUP_TOP')
769 self.visit(expr)
770 self.emit('COMPARE_OP', 'exception match')
771 next = self.newBlock()
772 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000773 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000774 self.emit('POP_TOP')
775 self.emit('POP_TOP')
776 if target:
777 self.visit(target)
778 else:
779 self.emit('POP_TOP')
780 self.emit('POP_TOP')
781 self.visit(body)
782 self.emit('JUMP_FORWARD', end)
783 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000784 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000785 else:
786 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000787 if expr: # XXX
788 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000789 self.emit('END_FINALLY')
790 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000791 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000792 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000793 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000794
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000795 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000796 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000797 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000798 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000799 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000800 self.nextBlock(body)
801 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000802 self.visit(node.body)
803 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000804 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000806 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000807 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000808 self.visit(node.final)
809 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000810 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000812 __with_count = 0
813
814 def visitWith(self, node):
815 body = self.newBlock()
816 final = self.newBlock()
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000817 valuevar = "$value%d" % self.__with_count
818 self.__with_count += 1
819 self.set_lineno(node)
820 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000821 self.emit('DUP_TOP')
822 self.emit('LOAD_ATTR', '__exit__')
Nick Coghlan7af53be2008-03-07 14:13:28 +0000823 self.emit('ROT_TWO')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000824 self.emit('LOAD_ATTR', '__enter__')
825 self.emit('CALL_FUNCTION', 0)
826 if node.vars is None:
827 self.emit('POP_TOP')
828 else:
829 self._implicitNameOp('STORE', valuevar)
830 self.emit('SETUP_FINALLY', final)
831 self.nextBlock(body)
832 self.setups.push((TRY_FINALLY, body))
833 if node.vars is not None:
834 self._implicitNameOp('LOAD', valuevar)
835 self._implicitNameOp('DELETE', valuevar)
836 self.visit(node.vars)
837 self.visit(node.body)
838 self.emit('POP_BLOCK')
839 self.setups.pop()
840 self.emit('LOAD_CONST', None)
841 self.nextBlock(final)
842 self.setups.push((END_FINALLY, final))
843 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000844 self.emit('END_FINALLY')
845 self.setups.pop()
846 self.__with_count -= 1
847
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000848 # misc
849
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000850 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000851 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000852 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000853 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000854
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000855 def visitConst(self, node):
856 self.emit('LOAD_CONST', node.value)
857
858 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000859 self.emit('LOAD_CONST', node.name)
860 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000861
862 def visitGlobal(self, node):
863 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000864 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000865
866 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000867 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000868 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000869
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000870 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000871 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000872
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000873 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000874 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000875 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000876 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000877 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000878 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000879 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000880 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000881 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000882 if alias:
883 self._resolveDots(name)
884 self.storeName(alias)
885 else:
886 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000887
888 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000889 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000890 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000891 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000892 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000893 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000894 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000895 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000896 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000897 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000898 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000899 if VERSION > 1:
900 if name == '*':
901 self.namespace = 0
902 self.emit('IMPORT_STAR')
903 # There can only be one name w/ from ... import *
904 assert len(node.names) == 1
905 return
906 else:
907 self.emit('IMPORT_FROM', name)
908 self._resolveDots(name)
909 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000910 else:
911 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000912 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000913
Jeremy Hylton20516082000-09-01 20:33:26 +0000914 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000915 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000916 if len(elts) == 1:
917 return
918 for elt in elts[1:]:
919 self.emit('LOAD_ATTR', elt)
920
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000921 def visitGetattr(self, node):
922 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000923 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000924
925 # next five implement assignments
926
927 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000928 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000929 self.visit(node.expr)
930 dups = len(node.nodes) - 1
931 for i in range(len(node.nodes)):
932 elt = node.nodes[i]
933 if i < dups:
934 self.emit('DUP_TOP')
935 if isinstance(elt, ast.Node):
936 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000937
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000938 def visitAssName(self, node):
939 if node.flags == 'OP_ASSIGN':
940 self.storeName(node.name)
941 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000942 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000943 self.delName(node.name)
944 else:
945 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000946
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000947 def visitAssAttr(self, node):
948 self.visit(node.expr)
949 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000950 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000951 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000952 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953 else:
954 print "warning: unexpected flags:", node.flags
955 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000956
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000957 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000958 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000959 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000960 for child in node.nodes:
961 self.visit(child)
962
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000963 if VERSION > 1:
964 visitAssTuple = _visitAssSequence
965 visitAssList = _visitAssSequence
966 else:
967 def visitAssTuple(self, node):
968 self._visitAssSequence(node, 'UNPACK_TUPLE')
969
970 def visitAssList(self, node):
971 self._visitAssSequence(node, 'UNPACK_LIST')
972
973 # augmented assignment
974
975 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000976 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000977 aug_node = wrap_aug(node.node)
978 self.visit(aug_node, "load")
979 self.visit(node.expr)
980 self.emit(self._augmented_opcode[node.op])
981 self.visit(aug_node, "store")
982
983 _augmented_opcode = {
984 '+=' : 'INPLACE_ADD',
985 '-=' : 'INPLACE_SUBTRACT',
986 '*=' : 'INPLACE_MULTIPLY',
987 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000988 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000989 '%=' : 'INPLACE_MODULO',
990 '**=': 'INPLACE_POWER',
991 '>>=': 'INPLACE_RSHIFT',
992 '<<=': 'INPLACE_LSHIFT',
993 '&=' : 'INPLACE_AND',
994 '^=' : 'INPLACE_XOR',
995 '|=' : 'INPLACE_OR',
996 }
997
998 def visitAugName(self, node, mode):
999 if mode == "load":
1000 self.loadName(node.name)
1001 elif mode == "store":
1002 self.storeName(node.name)
1003
1004 def visitAugGetattr(self, node, mode):
1005 if mode == "load":
1006 self.visit(node.expr)
1007 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001008 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001009 elif mode == "store":
1010 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001011 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001012
1013 def visitAugSlice(self, node, mode):
1014 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001015 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001016 elif mode == "store":
1017 slice = 0
1018 if node.lower:
1019 slice = slice | 1
1020 if node.upper:
1021 slice = slice | 2
1022 if slice == 0:
1023 self.emit('ROT_TWO')
1024 elif slice == 3:
1025 self.emit('ROT_FOUR')
1026 else:
1027 self.emit('ROT_THREE')
1028 self.emit('STORE_SLICE+%d' % slice)
1029
1030 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001031 if mode == "load":
1032 self.visitSubscript(node, 1)
1033 elif mode == "store":
1034 self.emit('ROT_THREE')
1035 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001036
1037 def visitExec(self, node):
1038 self.visit(node.expr)
1039 if node.locals is None:
1040 self.emit('LOAD_CONST', None)
1041 else:
1042 self.visit(node.locals)
1043 if node.globals is None:
1044 self.emit('DUP_TOP')
1045 else:
1046 self.visit(node.globals)
1047 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001048
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001049 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001050 pos = 0
1051 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001052 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001053 self.visit(node.node)
1054 for arg in node.args:
1055 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001056 if isinstance(arg, ast.Keyword):
1057 kw = kw + 1
1058 else:
1059 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001060 if node.star_args is not None:
1061 self.visit(node.star_args)
1062 if node.dstar_args is not None:
1063 self.visit(node.dstar_args)
1064 have_star = node.star_args is not None
1065 have_dstar = node.dstar_args is not None
1066 opcode = callfunc_opcode_info[have_star, have_dstar]
1067 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001068
Jeremy Hylton2afff322001-08-27 21:51:52 +00001069 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001070 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001071 if node.dest:
1072 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001073 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001074 if node.dest:
1075 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001076 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001077 if node.dest:
1078 self.emit('ROT_TWO')
1079 self.emit('PRINT_ITEM_TO')
1080 else:
1081 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001082 if node.dest and not newline:
1083 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001084
1085 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001086 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001087 if node.dest:
1088 self.emit('PRINT_NEWLINE_TO')
1089 else:
1090 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001091
1092 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001093 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001094 self.visit(node.value)
1095 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001096
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001097 def visitYield(self, node):
1098 self.set_lineno(node)
1099 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001100 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001101
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001102 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001103
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001104 def visitSlice(self, node, aug_flag=None):
1105 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001106 self.visit(node.expr)
1107 slice = 0
1108 if node.lower:
1109 self.visit(node.lower)
1110 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001111 if node.upper:
1112 self.visit(node.upper)
1113 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001114 if aug_flag:
1115 if slice == 0:
1116 self.emit('DUP_TOP')
1117 elif slice == 3:
1118 self.emit('DUP_TOPX', 3)
1119 else:
1120 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001121 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001122 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001123 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001124 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001125 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001126 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001127 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001128 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001129 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001130
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001131 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001132 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001133 for sub in node.subs:
1134 self.visit(sub)
1135 if len(node.subs) > 1:
1136 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001137 if aug_flag:
1138 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001139 if node.flags == 'OP_APPLY':
1140 self.emit('BINARY_SUBSCR')
1141 elif node.flags == 'OP_ASSIGN':
1142 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001143 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001144 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001145
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001146 # binary ops
1147
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001148 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001149 self.visit(node.left)
1150 self.visit(node.right)
1151 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001152
1153 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001154 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001155
1156 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001157 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001158
1159 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001160 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001161
1162 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001163 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001164
Jeremy Hylton94afe322001-08-29 18:14:39 +00001165 def visitFloorDiv(self, node):
1166 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1167
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001168 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001169 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001170
Jeremy Hylton126960b2000-02-14 21:33:10 +00001171 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001173
1174 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001175 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001176
1177 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001179
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001180 # unary ops
1181
1182 def unaryOp(self, node, op):
1183 self.visit(node.expr)
1184 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001185
Jeremy Hylton126960b2000-02-14 21:33:10 +00001186 def visitInvert(self, node):
1187 return self.unaryOp(node, 'UNARY_INVERT')
1188
Jeremy Hylton40245602000-02-08 21:15:48 +00001189 def visitUnarySub(self, node):
1190 return self.unaryOp(node, 'UNARY_NEGATIVE')
1191
1192 def visitUnaryAdd(self, node):
1193 return self.unaryOp(node, 'UNARY_POSITIVE')
1194
1195 def visitUnaryInvert(self, node):
1196 return self.unaryOp(node, 'UNARY_INVERT')
1197
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001198 def visitNot(self, node):
1199 return self.unaryOp(node, 'UNARY_NOT')
1200
Jeremy Hylton40245602000-02-08 21:15:48 +00001201 def visitBackquote(self, node):
1202 return self.unaryOp(node, 'UNARY_CONVERT')
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
Jeremy Hyltona5058122000-02-14 14:14:29 +00001223 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001224 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001225
Jeremy Hylton40245602000-02-08 21:15:48 +00001226 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001227 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001228 for elt in node.nodes:
1229 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001230 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001231
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001232 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001233 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001234 for elt in node.nodes:
1235 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001236 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001237
1238 def visitSliceobj(self, node):
1239 for child in node.nodes:
1240 self.visit(child)
1241 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001242
Jeremy Hyltona5058122000-02-14 14:14:29 +00001243 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001244 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001245 self.emit('BUILD_MAP', 0)
1246 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001247 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001248 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001249 self.visit(v)
1250 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001251 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001252
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001253class NestedScopeMixin:
1254 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001255 def initClass(self):
1256 self.__class__.NameFinder = LocalNameFinder
1257 self.__class__.FunctionGen = FunctionCodeGenerator
1258 self.__class__.ClassGen = ClassCodeGenerator
1259
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001260class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001261 __super_init = CodeGenerator.__init__
1262
1263 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001264
Jeremy Hylton37c93512001-09-17 18:03:55 +00001265 def __init__(self, tree):
1266 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001267 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001268 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001269 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001270
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001271 def get_module(self):
1272 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001273
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001274class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1275 __super_init = CodeGenerator.__init__
1276
1277 scopes = None
1278 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001279
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001280 def __init__(self, tree):
1281 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1282 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001283 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001284
1285 def get_module(self):
1286 return self
1287
1288class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1289
1290 __super_init = CodeGenerator.__init__
1291
1292 scopes = None
1293 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001294
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001295 def __init__(self, tree):
1296 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1297 self.__super_init()
1298 self.set_lineno(tree)
1299 walk(tree, self)
1300 self.emit('RETURN_VALUE')
1301
1302 def get_module(self):
1303 return self
Tim Peterse4418602002-02-16 07:34:19 +00001304
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001305 def visitDiscard(self, node):
1306 # XXX Discard means it's an expression. Perhaps this is a bad
1307 # name.
1308 self.visit(node.expr)
1309 self.emit('PRINT_EXPR')
1310
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001311class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001312 optimized = 1
1313 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001314
Jeremy Hylton37c93512001-09-17 18:03:55 +00001315 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001316 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001317 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001318 if isLambda:
1319 klass = FunctionCodeGenerator
1320 name = "<lambda.%d>" % klass.lambdaCount
1321 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001322 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001323 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001324
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001325 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001326 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1327 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001328 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001329 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001330
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001331 if not isLambda and func.doc:
1332 self.setDocstring(func.doc)
1333
Jeremy Hylton2afff322001-08-27 21:51:52 +00001334 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001335 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001336 if func.varargs:
1337 self.graph.setFlag(CO_VARARGS)
1338 if func.kwargs:
1339 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001340 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001341 if hasTupleArg:
1342 self.generateArgUnpack(func.argnames)
1343
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001344 def get_module(self):
1345 return self.module
1346
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001347 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001348 self.graph.startExitBlock()
1349 if not self.isLambda:
1350 self.emit('LOAD_CONST', None)
1351 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001352
1353 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001354 for i in range(len(args)):
1355 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001356 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001357 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001358 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001359
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001360 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001361 if VERSION > 1:
1362 self.emit('UNPACK_SEQUENCE', len(tup))
1363 else:
1364 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001365 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001366 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001367 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001368 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001369 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001370
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001371 unpackTuple = unpackSequence
1372
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001373class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001374 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001375 super_init = CodeGenerator.__init__ # call be other init
1376 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001377
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001378 __super_init = AbstractFunctionCode.__init__
1379
Jeremy Hylton37c93512001-09-17 18:03:55 +00001380 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001381 self.scopes = scopes
1382 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001383 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001384 self.graph.setFreeVars(self.scope.get_free_vars())
1385 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001386 if self.scope.generator is not None:
1387 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001388
Raymond Hettinger354433a2004-05-19 08:20:33 +00001389class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1390 CodeGenerator):
1391 super_init = CodeGenerator.__init__ # call be other init
1392 scopes = None
1393
1394 __super_init = AbstractFunctionCode.__init__
1395
1396 def __init__(self, gexp, scopes, class_name, mod):
1397 self.scopes = scopes
1398 self.scope = scopes[gexp]
1399 self.__super_init(gexp, scopes, 1, class_name, mod)
1400 self.graph.setFreeVars(self.scope.get_free_vars())
1401 self.graph.setCellVars(self.scope.get_cell_vars())
1402 self.graph.setFlag(CO_GENERATOR)
1403
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001404class AbstractClassCode:
1405
Jeremy Hylton37c93512001-09-17 18:03:55 +00001406 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001407 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001408 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001409 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001410 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001411 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001412 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001413 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001414 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001415 if klass.doc:
1416 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001417
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001418 def get_module(self):
1419 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001420
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001421 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001422 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001423 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001424 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001425
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001426class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001427 super_init = CodeGenerator.__init__
1428 scopes = None
1429
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001430 __super_init = AbstractClassCode.__init__
1431
Jeremy Hylton37c93512001-09-17 18:03:55 +00001432 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001433 self.scopes = scopes
1434 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001435 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001436 self.graph.setFreeVars(self.scope.get_free_vars())
1437 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001438 self.set_lineno(klass)
1439 self.emit("LOAD_GLOBAL", "__name__")
1440 self.storeName("__module__")
1441 if klass.doc:
1442 self.emit("LOAD_CONST", klass.doc)
1443 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001444
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001445def generateArgList(arglist):
1446 """Generate an arg list marking TupleArgs"""
1447 args = []
1448 extra = []
1449 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001450 for i in range(len(arglist)):
1451 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001452 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001453 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001454 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001455 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001456 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001457 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001458 else:
1459 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001460 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001461
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001462def findOp(node):
1463 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1464 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001465 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001466 return v.op
1467
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001468class OpFinder:
1469 def __init__(self):
1470 self.op = None
1471 def visitAssName(self, node):
1472 if self.op is None:
1473 self.op = node.flags
1474 elif self.op != node.flags:
1475 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001476 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001477 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001478
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001479class Delegator:
1480 """Base class to support delegation for augmented assignment nodes
1481
1482 To generator code for augmented assignments, we use the following
1483 wrapper classes. In visitAugAssign, the left-hand expression node
1484 is visited twice. The first time the visit uses the normal method
1485 for that node . The second time the visit uses a different method
1486 that generates the appropriate code to perform the assignment.
1487 These delegator classes wrap the original AST nodes in order to
1488 support the variant visit methods.
1489 """
1490 def __init__(self, obj):
1491 self.obj = obj
1492
1493 def __getattr__(self, attr):
1494 return getattr(self.obj, attr)
1495
1496class AugGetattr(Delegator):
1497 pass
1498
1499class AugName(Delegator):
1500 pass
1501
1502class AugSlice(Delegator):
1503 pass
1504
1505class AugSubscript(Delegator):
1506 pass
1507
1508wrapper = {
1509 ast.Getattr: AugGetattr,
1510 ast.Name: AugName,
1511 ast.Slice: AugSlice,
1512 ast.Subscript: AugSubscript,
1513 }
1514
1515def wrap_aug(node):
1516 return wrapper[node.__class__](node)
1517
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001518if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001519 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001520 compileFile(file)