blob: 9959b13411727fcb61d6f36db8cd80d2fbf7aa7f [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,
12 CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION,
13 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"
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000217 elif feature == "generators":
218 self.graph.setFlag(CO_GENERATOR_ALLOWED)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000219 elif feature == "absolute_import":
220 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
221 elif feature == "with_statement":
222 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
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)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000387 frees = gen.scope.get_free_vars()
388 if frees:
389 for name in frees:
390 self.emit('LOAD_CLOSURE', name)
391 self.emit('LOAD_CONST', gen)
392 self.emit('MAKE_CLOSURE', len(node.defaults))
393 else:
394 self.emit('LOAD_CONST', gen)
395 self.emit('MAKE_FUNCTION', len(node.defaults))
Tim Peters6db15d72004-08-04 02:36:18 +0000396
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000397 for i in range(ndecorators):
398 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000399
400 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000401 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000402 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000403 walk(node.code, gen)
404 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000405 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000406 self.emit('LOAD_CONST', node.name)
407 for base in node.bases:
408 self.visit(base)
409 self.emit('BUILD_TUPLE', len(node.bases))
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000410 frees = gen.scope.get_free_vars()
411 for name in frees:
412 self.emit('LOAD_CLOSURE', name)
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000413 self.emit('LOAD_CONST', gen)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000414 if frees:
415 self.emit('MAKE_CLOSURE', 0)
416 else:
417 self.emit('MAKE_FUNCTION', 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000418 self.emit('CALL_FUNCTION', 0)
419 self.emit('BUILD_CLASS')
420 self.storeName(node.name)
421
422 # The rest are standard visitor methods
423
424 # The next few implement control-flow statements
425
426 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000427 end = self.newBlock()
428 numtests = len(node.tests)
429 for i in range(numtests):
430 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000431 if is_constant_false(test):
432 # XXX will need to check generator stuff here
433 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000434 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000435 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000436 nextTest = self.newBlock()
437 self.emit('JUMP_IF_FALSE', nextTest)
438 self.nextBlock()
439 self.emit('POP_TOP')
440 self.visit(suite)
441 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000442 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000443 self.emit('POP_TOP')
444 if node.else_:
445 self.visit(node.else_)
446 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000447
448 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000449 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000450
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000451 loop = self.newBlock()
452 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000453
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000454 after = self.newBlock()
455 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000456
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000458 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000459
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000460 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000461 self.visit(node.test)
462 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000463
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 self.nextBlock()
465 self.emit('POP_TOP')
466 self.visit(node.body)
467 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000468
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000469 self.startBlock(else_) # or just the POPs if not else clause
470 self.emit('POP_TOP')
471 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000472 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000473 if node.else_:
474 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000475 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000476
477 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000478 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000479 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000480 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000481 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000482
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000483 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000484 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000485 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000486 self.emit('GET_ITER')
487
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000488 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000489 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000490 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000491 self.visit(node.assign)
492 self.visit(node.body)
493 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000494 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000495 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000496 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000497 if node.else_:
498 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000499 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000500
501 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000502 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000503 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000504 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000505 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000506 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000507
508 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000509 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000510 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000511 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000512 kind, block = self.setups.top()
513 if kind == LOOP:
514 self.set_lineno(node)
515 self.emit('JUMP_ABSOLUTE', block)
516 self.nextBlock()
517 elif kind == EXCEPT or kind == TRY_FINALLY:
518 self.set_lineno(node)
519 # find the block that starts the loop
520 top = len(self.setups)
521 while top > 0:
522 top = top - 1
523 kind, loop_block = self.setups[top]
524 if kind == LOOP:
525 break
526 if kind != LOOP:
527 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000528 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000529 self.emit('CONTINUE_LOOP', loop_block)
530 self.nextBlock()
531 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000532 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000533 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000534
535 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000536 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000537 for child in node.nodes[:-1]:
538 self.visit(child)
539 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000540 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000541 self.emit('POP_TOP')
542 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000543 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000544
545 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000546 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000547
548 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000549 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000550
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000551 def visitIfExp(self, node):
552 endblock = self.newBlock()
553 elseblock = self.newBlock()
554 self.visit(node.test)
555 self.emit('JUMP_IF_FALSE', elseblock)
556 self.emit('POP_TOP')
557 self.visit(node.then)
558 self.emit('JUMP_FORWARD', endblock)
559 self.nextBlock(elseblock)
560 self.emit('POP_TOP')
561 self.visit(node.else_)
562 self.nextBlock(endblock)
563
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000564 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000565 self.visit(node.expr)
566 cleanup = self.newBlock()
567 for op, code in node.ops[:-1]:
568 self.visit(code)
569 self.emit('DUP_TOP')
570 self.emit('ROT_THREE')
571 self.emit('COMPARE_OP', op)
572 self.emit('JUMP_IF_FALSE', cleanup)
573 self.nextBlock()
574 self.emit('POP_TOP')
575 # now do the last comparison
576 if node.ops:
577 op, code = node.ops[-1]
578 self.visit(code)
579 self.emit('COMPARE_OP', op)
580 if len(node.ops) > 1:
581 end = self.newBlock()
582 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000583 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000584 self.emit('ROT_TWO')
585 self.emit('POP_TOP')
586 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000587
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000588 # list comprehensions
589 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000590
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000591 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000592 self.set_lineno(node)
593 # setup list
594 append = "$append%d" % self.__list_count
595 self.__list_count = self.__list_count + 1
596 self.emit('BUILD_LIST', 0)
597 self.emit('DUP_TOP')
598 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000599 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000600
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000601 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000602 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000603 start, anchor = self.visit(for_)
604 cont = None
605 for if_ in for_.ifs:
606 if cont is None:
607 cont = self.newBlock()
608 self.visit(if_, cont)
609 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000610
Jeremy Hylton13d70942001-04-12 21:04:43 +0000611 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000612 self.visit(node.expr)
613 self.emit('CALL_FUNCTION', 1)
614 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000615
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000616 for start, cont, anchor in stack:
617 if cont:
618 skip_one = self.newBlock()
619 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000620 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000621 self.emit('POP_TOP')
622 self.nextBlock(skip_one)
623 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000624 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000625 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000626
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000627 self.__list_count = self.__list_count - 1
628
629 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000630 start = self.newBlock()
631 anchor = self.newBlock()
632
633 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000634 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000635 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000636 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000637 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000638 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000639 self.visit(node.assign)
640 return start, anchor
641
642 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000643 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000644 self.visit(node.test)
645 self.emit('JUMP_IF_FALSE', branch)
646 self.newBlock()
647 self.emit('POP_TOP')
648
Raymond Hettinger354433a2004-05-19 08:20:33 +0000649 def visitGenExpr(self, node):
650 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
651 self.get_module())
652 walk(node.code, gen)
653 gen.finish()
654 self.set_lineno(node)
655 frees = gen.scope.get_free_vars()
656 if frees:
657 for name in frees:
658 self.emit('LOAD_CLOSURE', name)
659 self.emit('LOAD_CONST', gen)
660 self.emit('MAKE_CLOSURE', 0)
661 else:
662 self.emit('LOAD_CONST', gen)
663 self.emit('MAKE_FUNCTION', 0)
664
665 # precomputation of outmost iterable
666 self.visit(node.code.quals[0].iter)
667 self.emit('GET_ITER')
668 self.emit('CALL_FUNCTION', 1)
669
670 def visitGenExprInner(self, node):
671 self.set_lineno(node)
672 # setup list
673
674 stack = []
675 for i, for_ in zip(range(len(node.quals)), node.quals):
676 start, anchor = self.visit(for_)
677 cont = None
678 for if_ in for_.ifs:
679 if cont is None:
680 cont = self.newBlock()
681 self.visit(if_, cont)
682 stack.insert(0, (start, cont, anchor))
683
684 self.visit(node.expr)
685 self.emit('YIELD_VALUE')
686
687 for start, cont, anchor in stack:
688 if cont:
689 skip_one = self.newBlock()
690 self.emit('JUMP_FORWARD', skip_one)
691 self.startBlock(cont)
692 self.emit('POP_TOP')
693 self.nextBlock(skip_one)
694 self.emit('JUMP_ABSOLUTE', start)
695 self.startBlock(anchor)
696 self.emit('LOAD_CONST', None)
697
698 def visitGenExprFor(self, node):
699 start = self.newBlock()
700 anchor = self.newBlock()
Tim Peters4e0e1b62004-07-07 20:54:48 +0000701
Raymond Hettinger354433a2004-05-19 08:20:33 +0000702 if node.is_outmost:
703 self.loadName('[outmost-iterable]')
704 else:
705 self.visit(node.iter)
706 self.emit('GET_ITER')
707
708 self.nextBlock(start)
709 self.set_lineno(node, force=True)
710 self.emit('FOR_ITER', anchor)
711 self.nextBlock()
712 self.visit(node.assign)
713 return start, anchor
714
715 def visitGenExprIf(self, node, branch):
716 self.set_lineno(node, force=True)
717 self.visit(node.test)
718 self.emit('JUMP_IF_FALSE', branch)
719 self.newBlock()
720 self.emit('POP_TOP')
721
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000722 # exception related
723
724 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000725 # XXX would be interesting to implement this via a
726 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000727 if __debug__:
728 end = self.newBlock()
729 self.set_lineno(node)
730 # XXX AssertionError appears to be special case -- it is always
731 # loaded as a global even if there is a local name. I guess this
732 # is a sort of renaming op.
733 self.nextBlock()
734 self.visit(node.test)
735 self.emit('JUMP_IF_TRUE', end)
736 self.nextBlock()
737 self.emit('POP_TOP')
738 self.emit('LOAD_GLOBAL', 'AssertionError')
739 if node.fail:
740 self.visit(node.fail)
741 self.emit('RAISE_VARARGS', 2)
742 else:
743 self.emit('RAISE_VARARGS', 1)
744 self.nextBlock(end)
745 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000746
747 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000748 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000749 n = 0
750 if node.expr1:
751 self.visit(node.expr1)
752 n = n + 1
753 if node.expr2:
754 self.visit(node.expr2)
755 n = n + 1
756 if node.expr3:
757 self.visit(node.expr3)
758 n = n + 1
759 self.emit('RAISE_VARARGS', n)
760
761 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000762 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000763 handlers = self.newBlock()
764 end = self.newBlock()
765 if node.else_:
766 lElse = self.newBlock()
767 else:
768 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000769 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000770 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000771 self.nextBlock(body)
772 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000773 self.visit(node.body)
774 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000775 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000776 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000777 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000778
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000779 last = len(node.handlers) - 1
780 for i in range(len(node.handlers)):
781 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000782 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000783 if expr:
784 self.emit('DUP_TOP')
785 self.visit(expr)
786 self.emit('COMPARE_OP', 'exception match')
787 next = self.newBlock()
788 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000789 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000790 self.emit('POP_TOP')
791 self.emit('POP_TOP')
792 if target:
793 self.visit(target)
794 else:
795 self.emit('POP_TOP')
796 self.emit('POP_TOP')
797 self.visit(body)
798 self.emit('JUMP_FORWARD', end)
799 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000800 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000801 else:
802 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000803 if expr: # XXX
804 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 self.emit('END_FINALLY')
806 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000807 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000808 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000809 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000810
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000812 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000813 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000814 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000815 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000816 self.nextBlock(body)
817 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000818 self.visit(node.body)
819 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000820 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000821 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000822 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000823 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000824 self.visit(node.final)
825 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000826 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000827
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000828 __with_count = 0
829
830 def visitWith(self, node):
831 body = self.newBlock()
832 final = self.newBlock()
833 exitvar = "$exit%d" % self.__with_count
834 valuevar = "$value%d" % self.__with_count
835 self.__with_count += 1
836 self.set_lineno(node)
837 self.visit(node.expr)
838 self.emit('LOAD_ATTR', '__context__')
839 self.emit('CALL_FUNCTION', 0)
840 self.emit('DUP_TOP')
841 self.emit('LOAD_ATTR', '__exit__')
842 self._implicitNameOp('STORE', exitvar)
843 self.emit('LOAD_ATTR', '__enter__')
844 self.emit('CALL_FUNCTION', 0)
845 if node.vars is None:
846 self.emit('POP_TOP')
847 else:
848 self._implicitNameOp('STORE', valuevar)
849 self.emit('SETUP_FINALLY', final)
850 self.nextBlock(body)
851 self.setups.push((TRY_FINALLY, body))
852 if node.vars is not None:
853 self._implicitNameOp('LOAD', valuevar)
854 self._implicitNameOp('DELETE', valuevar)
855 self.visit(node.vars)
856 self.visit(node.body)
857 self.emit('POP_BLOCK')
858 self.setups.pop()
859 self.emit('LOAD_CONST', None)
860 self.nextBlock(final)
861 self.setups.push((END_FINALLY, final))
862 self.emit('WITH_CLEANUP')
863 self.emit('CALL_FUNCTION', 3)
864 self.emit('POP_TOP')
865 self.emit('END_FINALLY')
866 self.setups.pop()
867 self.__with_count -= 1
868
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000869 # misc
870
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000871 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000872 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000873 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000874 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000875
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000876 def visitConst(self, node):
877 self.emit('LOAD_CONST', node.value)
878
879 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000880 self.emit('LOAD_CONST', node.name)
881 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000882
883 def visitGlobal(self, node):
884 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000885 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000886
887 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000888 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000889 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000890
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000891 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000892 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000893
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000894 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000895 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000896 level = 0 if "absolute_import" in self.futures else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000897 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000898 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000899 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000900 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000901 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000902 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000903 if alias:
904 self._resolveDots(name)
905 self.storeName(alias)
906 else:
907 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000908
909 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000910 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000911 level = node.level
912 if level == 0 and "absolute_import" not in self.futures:
913 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000914 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000915 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000916 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000917 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000918 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000919 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000920 if VERSION > 1:
921 if name == '*':
922 self.namespace = 0
923 self.emit('IMPORT_STAR')
924 # There can only be one name w/ from ... import *
925 assert len(node.names) == 1
926 return
927 else:
928 self.emit('IMPORT_FROM', name)
929 self._resolveDots(name)
930 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000931 else:
932 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000933 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000934
Jeremy Hylton20516082000-09-01 20:33:26 +0000935 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000936 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000937 if len(elts) == 1:
938 return
939 for elt in elts[1:]:
940 self.emit('LOAD_ATTR', elt)
941
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000942 def visitGetattr(self, node):
943 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000944 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000945
946 # next five implement assignments
947
948 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000949 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000950 self.visit(node.expr)
951 dups = len(node.nodes) - 1
952 for i in range(len(node.nodes)):
953 elt = node.nodes[i]
954 if i < dups:
955 self.emit('DUP_TOP')
956 if isinstance(elt, ast.Node):
957 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000958
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000959 def visitAssName(self, node):
960 if node.flags == 'OP_ASSIGN':
961 self.storeName(node.name)
962 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000963 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000964 self.delName(node.name)
965 else:
966 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000967
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000968 def visitAssAttr(self, node):
969 self.visit(node.expr)
970 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000971 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000972 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000973 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000974 else:
975 print "warning: unexpected flags:", node.flags
976 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000977
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000978 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000979 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000980 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000981 for child in node.nodes:
982 self.visit(child)
983
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000984 if VERSION > 1:
985 visitAssTuple = _visitAssSequence
986 visitAssList = _visitAssSequence
987 else:
988 def visitAssTuple(self, node):
989 self._visitAssSequence(node, 'UNPACK_TUPLE')
990
991 def visitAssList(self, node):
992 self._visitAssSequence(node, 'UNPACK_LIST')
993
994 # augmented assignment
995
996 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000997 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000998 aug_node = wrap_aug(node.node)
999 self.visit(aug_node, "load")
1000 self.visit(node.expr)
1001 self.emit(self._augmented_opcode[node.op])
1002 self.visit(aug_node, "store")
1003
1004 _augmented_opcode = {
1005 '+=' : 'INPLACE_ADD',
1006 '-=' : 'INPLACE_SUBTRACT',
1007 '*=' : 'INPLACE_MULTIPLY',
1008 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001009 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001010 '%=' : 'INPLACE_MODULO',
1011 '**=': 'INPLACE_POWER',
1012 '>>=': 'INPLACE_RSHIFT',
1013 '<<=': 'INPLACE_LSHIFT',
1014 '&=' : 'INPLACE_AND',
1015 '^=' : 'INPLACE_XOR',
1016 '|=' : 'INPLACE_OR',
1017 }
1018
1019 def visitAugName(self, node, mode):
1020 if mode == "load":
1021 self.loadName(node.name)
1022 elif mode == "store":
1023 self.storeName(node.name)
1024
1025 def visitAugGetattr(self, node, mode):
1026 if mode == "load":
1027 self.visit(node.expr)
1028 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001029 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001030 elif mode == "store":
1031 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001032 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001033
1034 def visitAugSlice(self, node, mode):
1035 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001036 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001037 elif mode == "store":
1038 slice = 0
1039 if node.lower:
1040 slice = slice | 1
1041 if node.upper:
1042 slice = slice | 2
1043 if slice == 0:
1044 self.emit('ROT_TWO')
1045 elif slice == 3:
1046 self.emit('ROT_FOUR')
1047 else:
1048 self.emit('ROT_THREE')
1049 self.emit('STORE_SLICE+%d' % slice)
1050
1051 def visitAugSubscript(self, node, mode):
1052 if len(node.subs) > 1:
1053 raise SyntaxError, "augmented assignment to tuple is not possible"
1054 if mode == "load":
1055 self.visitSubscript(node, 1)
1056 elif mode == "store":
1057 self.emit('ROT_THREE')
1058 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001059
1060 def visitExec(self, node):
1061 self.visit(node.expr)
1062 if node.locals is None:
1063 self.emit('LOAD_CONST', None)
1064 else:
1065 self.visit(node.locals)
1066 if node.globals is None:
1067 self.emit('DUP_TOP')
1068 else:
1069 self.visit(node.globals)
1070 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001071
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001072 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001073 pos = 0
1074 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001075 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001076 self.visit(node.node)
1077 for arg in node.args:
1078 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001079 if isinstance(arg, ast.Keyword):
1080 kw = kw + 1
1081 else:
1082 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001083 if node.star_args is not None:
1084 self.visit(node.star_args)
1085 if node.dstar_args is not None:
1086 self.visit(node.dstar_args)
1087 have_star = node.star_args is not None
1088 have_dstar = node.dstar_args is not None
1089 opcode = callfunc_opcode_info[have_star, have_dstar]
1090 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001091
Jeremy Hylton2afff322001-08-27 21:51:52 +00001092 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001093 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001094 if node.dest:
1095 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001096 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001097 if node.dest:
1098 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001099 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001100 if node.dest:
1101 self.emit('ROT_TWO')
1102 self.emit('PRINT_ITEM_TO')
1103 else:
1104 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001105 if node.dest and not newline:
1106 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001107
1108 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001109 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001110 if node.dest:
1111 self.emit('PRINT_NEWLINE_TO')
1112 else:
1113 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001114
1115 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001116 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001117 self.visit(node.value)
1118 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001119
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001120 def visitYield(self, node):
1121 self.set_lineno(node)
1122 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001123 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001124
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001125 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001126
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001127 def visitSlice(self, node, aug_flag=None):
1128 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001129 self.visit(node.expr)
1130 slice = 0
1131 if node.lower:
1132 self.visit(node.lower)
1133 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001134 if node.upper:
1135 self.visit(node.upper)
1136 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001137 if aug_flag:
1138 if slice == 0:
1139 self.emit('DUP_TOP')
1140 elif slice == 3:
1141 self.emit('DUP_TOPX', 3)
1142 else:
1143 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001144 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001145 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001146 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001147 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001148 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001149 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001150 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001151 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001152 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001153
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001154 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001155 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001156 for sub in node.subs:
1157 self.visit(sub)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001158 if aug_flag:
1159 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001160 if len(node.subs) > 1:
1161 self.emit('BUILD_TUPLE', len(node.subs))
1162 if node.flags == 'OP_APPLY':
1163 self.emit('BINARY_SUBSCR')
1164 elif node.flags == 'OP_ASSIGN':
1165 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001166 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001167 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001168
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001169 # binary ops
1170
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001171 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 self.visit(node.left)
1173 self.visit(node.right)
1174 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001175
1176 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001177 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001178
1179 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001180 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001181
1182 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001183 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001184
1185 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001186 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001187
Jeremy Hylton94afe322001-08-29 18:14:39 +00001188 def visitFloorDiv(self, node):
1189 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1190
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001191 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001192 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001193
Jeremy Hylton126960b2000-02-14 21:33:10 +00001194 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001195 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001196
1197 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001198 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001199
1200 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001201 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001202
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001203 # unary ops
1204
1205 def unaryOp(self, node, op):
1206 self.visit(node.expr)
1207 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001208
Jeremy Hylton126960b2000-02-14 21:33:10 +00001209 def visitInvert(self, node):
1210 return self.unaryOp(node, 'UNARY_INVERT')
1211
Jeremy Hylton40245602000-02-08 21:15:48 +00001212 def visitUnarySub(self, node):
1213 return self.unaryOp(node, 'UNARY_NEGATIVE')
1214
1215 def visitUnaryAdd(self, node):
1216 return self.unaryOp(node, 'UNARY_POSITIVE')
1217
1218 def visitUnaryInvert(self, node):
1219 return self.unaryOp(node, 'UNARY_INVERT')
1220
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001221 def visitNot(self, node):
1222 return self.unaryOp(node, 'UNARY_NOT')
1223
Jeremy Hylton40245602000-02-08 21:15:48 +00001224 def visitBackquote(self, node):
1225 return self.unaryOp(node, 'UNARY_CONVERT')
1226
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001227 # bit ops
1228
Jeremy Hyltona5058122000-02-14 14:14:29 +00001229 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001230 self.visit(nodes[0])
1231 for node in nodes[1:]:
1232 self.visit(node)
1233 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001234
1235 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001236 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001237
1238 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001239 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001240
1241 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001242 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001243
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001244 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001245
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001247 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001248
Jeremy Hylton40245602000-02-08 21:15:48 +00001249 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001250 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001251 for elt in node.nodes:
1252 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001253 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001254
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001255 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001256 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001257 for elt in node.nodes:
1258 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001259 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001260
1261 def visitSliceobj(self, node):
1262 for child in node.nodes:
1263 self.visit(child)
1264 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001265
Jeremy Hyltona5058122000-02-14 14:14:29 +00001266 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001267 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001268 self.emit('BUILD_MAP', 0)
1269 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001270 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001271 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001272 self.visit(v)
1273 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001274 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001275
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001276class NestedScopeMixin:
1277 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001278 def initClass(self):
1279 self.__class__.NameFinder = LocalNameFinder
1280 self.__class__.FunctionGen = FunctionCodeGenerator
1281 self.__class__.ClassGen = ClassCodeGenerator
1282
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001283class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001284 __super_init = CodeGenerator.__init__
1285
1286 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001287
Jeremy Hylton37c93512001-09-17 18:03:55 +00001288 def __init__(self, tree):
1289 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001290 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001291 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001292 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001293
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001294 def get_module(self):
1295 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001296
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001297class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1298 __super_init = CodeGenerator.__init__
1299
1300 scopes = None
1301 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001302
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001303 def __init__(self, tree):
1304 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1305 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001306 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001307
1308 def get_module(self):
1309 return self
1310
1311class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1312
1313 __super_init = CodeGenerator.__init__
1314
1315 scopes = None
1316 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001317
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001318 def __init__(self, tree):
1319 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1320 self.__super_init()
1321 self.set_lineno(tree)
1322 walk(tree, self)
1323 self.emit('RETURN_VALUE')
1324
1325 def get_module(self):
1326 return self
Tim Peterse4418602002-02-16 07:34:19 +00001327
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001328 def visitDiscard(self, node):
1329 # XXX Discard means it's an expression. Perhaps this is a bad
1330 # name.
1331 self.visit(node.expr)
1332 self.emit('PRINT_EXPR')
1333
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001334class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001335 optimized = 1
1336 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001337
Jeremy Hylton37c93512001-09-17 18:03:55 +00001338 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001339 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001340 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001341 if isLambda:
1342 klass = FunctionCodeGenerator
1343 name = "<lambda.%d>" % klass.lambdaCount
1344 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001345 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001346 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001347
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001348 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001349 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1350 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001351 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001352 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001353
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001354 if not isLambda and func.doc:
1355 self.setDocstring(func.doc)
1356
Jeremy Hylton2afff322001-08-27 21:51:52 +00001357 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001358 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001359 if func.varargs:
1360 self.graph.setFlag(CO_VARARGS)
1361 if func.kwargs:
1362 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001363 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001364 if hasTupleArg:
1365 self.generateArgUnpack(func.argnames)
1366
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001367 def get_module(self):
1368 return self.module
1369
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001370 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001371 self.graph.startExitBlock()
1372 if not self.isLambda:
1373 self.emit('LOAD_CONST', None)
1374 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001375
1376 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001377 for i in range(len(args)):
1378 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001379 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001380 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001381 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001382
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001383 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001384 if VERSION > 1:
1385 self.emit('UNPACK_SEQUENCE', len(tup))
1386 else:
1387 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001388 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001389 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001390 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001391 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001392 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001393
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001394 unpackTuple = unpackSequence
1395
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001396class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001397 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001398 super_init = CodeGenerator.__init__ # call be other init
1399 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001400
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001401 __super_init = AbstractFunctionCode.__init__
1402
Jeremy Hylton37c93512001-09-17 18:03:55 +00001403 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001404 self.scopes = scopes
1405 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001406 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001407 self.graph.setFreeVars(self.scope.get_free_vars())
1408 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001409 if self.scope.generator is not None:
1410 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001411
Raymond Hettinger354433a2004-05-19 08:20:33 +00001412class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1413 CodeGenerator):
1414 super_init = CodeGenerator.__init__ # call be other init
1415 scopes = None
1416
1417 __super_init = AbstractFunctionCode.__init__
1418
1419 def __init__(self, gexp, scopes, class_name, mod):
1420 self.scopes = scopes
1421 self.scope = scopes[gexp]
1422 self.__super_init(gexp, scopes, 1, class_name, mod)
1423 self.graph.setFreeVars(self.scope.get_free_vars())
1424 self.graph.setCellVars(self.scope.get_cell_vars())
1425 self.graph.setFlag(CO_GENERATOR)
1426
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001427class AbstractClassCode:
1428
Jeremy Hylton37c93512001-09-17 18:03:55 +00001429 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001430 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001431 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001432 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001433 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001434 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001435 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001436 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001437 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001438 if klass.doc:
1439 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001440
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001441 def get_module(self):
1442 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001443
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001444 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001445 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001446 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001447 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001448
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001449class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001450 super_init = CodeGenerator.__init__
1451 scopes = None
1452
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001453 __super_init = AbstractClassCode.__init__
1454
Jeremy Hylton37c93512001-09-17 18:03:55 +00001455 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001456 self.scopes = scopes
1457 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001458 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001459 self.graph.setFreeVars(self.scope.get_free_vars())
1460 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001461 self.set_lineno(klass)
1462 self.emit("LOAD_GLOBAL", "__name__")
1463 self.storeName("__module__")
1464 if klass.doc:
1465 self.emit("LOAD_CONST", klass.doc)
1466 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001467
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001468def generateArgList(arglist):
1469 """Generate an arg list marking TupleArgs"""
1470 args = []
1471 extra = []
1472 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001473 for i in range(len(arglist)):
1474 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001475 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001476 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001477 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001478 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001479 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001480 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001481 else:
1482 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001483 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001484
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001485def findOp(node):
1486 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1487 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001488 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001489 return v.op
1490
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001491class OpFinder:
1492 def __init__(self):
1493 self.op = None
1494 def visitAssName(self, node):
1495 if self.op is None:
1496 self.op = node.flags
1497 elif self.op != node.flags:
1498 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001499 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001500 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001501
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001502class Delegator:
1503 """Base class to support delegation for augmented assignment nodes
1504
1505 To generator code for augmented assignments, we use the following
1506 wrapper classes. In visitAugAssign, the left-hand expression node
1507 is visited twice. The first time the visit uses the normal method
1508 for that node . The second time the visit uses a different method
1509 that generates the appropriate code to perform the assignment.
1510 These delegator classes wrap the original AST nodes in order to
1511 support the variant visit methods.
1512 """
1513 def __init__(self, obj):
1514 self.obj = obj
1515
1516 def __getattr__(self, attr):
1517 return getattr(self.obj, attr)
1518
1519class AugGetattr(Delegator):
1520 pass
1521
1522class AugName(Delegator):
1523 pass
1524
1525class AugSlice(Delegator):
1526 pass
1527
1528class AugSubscript(Delegator):
1529 pass
1530
1531wrapper = {
1532 ast.Getattr: AugGetattr,
1533 ast.Name: AugName,
1534 ast.Slice: AugSlice,
1535 ast.Subscript: AugSubscript,
1536 }
1537
1538def wrap_aug(node):
1539 return wrapper[node.__class__](node)
1540
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001541if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001542 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001543 compileFile(file)