blob: b46b1c1489e25e8a5519db07fb3c49f84d238a05 [file] [log] [blame]
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001import imp
Jeremy Hylton53187f32000-02-08 19:01:29 +00002import os
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00003import marshal
Jeremy Hylton53187f32000-02-08 19:01:29 +00004import struct
Jeremy Hylton9c048f92000-10-13 21:58:13 +00005import sys
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00006from cStringIO import StringIO
7
Jeremy Hylton37c93512001-09-17 18:03:55 +00008from compiler import ast, parse, walk, syntax
Jeremy Hylton364f9b92001-04-12 06:40:42 +00009from compiler import pyassem, misc, future, symbols
10from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000011from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
Neal Norwitzeaed39f2006-03-03 19:12:58 +000012 CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +000013 CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT)
Jeremy Hylton71ebc332001-08-30 20:25:55 +000014from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000015
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000016# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000017# Do we have Python 1.x or Python 2.x?
18try:
19 VERSION = sys.version_info[0]
20except AttributeError:
21 VERSION = 1
22
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000023callfunc_opcode_info = {
24 # (Have *args, Have **args) : opcode
25 (0,0) : "CALL_FUNCTION",
26 (1,0) : "CALL_FUNCTION_VAR",
27 (0,1) : "CALL_FUNCTION_KW",
28 (1,1) : "CALL_FUNCTION_VAR_KW",
29}
30
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000031LOOP = 1
32EXCEPT = 2
33TRY_FINALLY = 3
34END_FINALLY = 4
35
Jeremy Hylton9dca3642001-09-17 21:02:51 +000036def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000037 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000038 buf = f.read()
39 f.close()
40 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000041 try:
42 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000043 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000044 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000045 else:
46 f = open(filename + "c", "wb")
47 mod.dump(f)
48 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000049
Jeremy Hylton9dca3642001-09-17 21:02:51 +000050def compile(source, filename, mode, flags=None, dont_inherit=None):
51 """Replacement for builtin compile() function"""
52 if flags is not None or dont_inherit is not None:
53 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000054
Jeremy Hylton9dca3642001-09-17 21:02:51 +000055 if mode == "single":
56 gen = Interactive(source, filename)
57 elif mode == "exec":
58 gen = Module(source, filename)
59 elif mode == "eval":
60 gen = Expression(source, filename)
61 else:
62 raise ValueError("compile() 3rd arg must be 'exec' or "
63 "'eval' or 'single'")
64 gen.compile()
65 return gen.code
66
67class AbstractCompileMode:
68
69 mode = None # defined by subclass
70
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000071 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000072 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000073 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000074 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000075
Jeremy Hylton9dca3642001-09-17 21:02:51 +000076 def _get_tree(self):
77 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000078 misc.set_filename(self.filename, tree)
79 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000080 return tree
81
82 def compile(self):
83 pass # implemented by subclass
84
85 def getCode(self):
86 return self.code
87
88class Expression(AbstractCompileMode):
89
90 mode = "eval"
91
92 def compile(self):
93 tree = self._get_tree()
94 gen = ExpressionCodeGenerator(tree)
95 self.code = gen.getCode()
96
97class Interactive(AbstractCompileMode):
98
99 mode = "single"
100
101 def compile(self):
102 tree = self._get_tree()
103 gen = InteractiveCodeGenerator(tree)
104 self.code = gen.getCode()
105
106class Module(AbstractCompileMode):
107
108 mode = "exec"
109
110 def compile(self, display=0):
111 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000112 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000113 if display:
114 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000115 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000116 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000117
118 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000119 f.write(self.getPycHeader())
120 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000121
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000122 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000123
124 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000125 # compile.c uses marshal to write a long directly, with
126 # calling the interface that would also generate a 1-byte code
127 # to indicate the type of the value. simplest way to get the
128 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000129 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000130 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000131 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000132
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000133class LocalNameFinder:
134 """Find local names in scope"""
135 def __init__(self, names=()):
136 self.names = misc.Set()
137 self.globals = misc.Set()
138 for name in names:
139 self.names.add(name)
140
141 # XXX list comprehensions and for loops
142
143 def getLocals(self):
144 for elt in self.globals.elements():
145 if self.names.has_elt(elt):
146 self.names.remove(elt)
147 return self.names
148
149 def visitDict(self, node):
150 pass
151
152 def visitGlobal(self, node):
153 for name in node.names:
154 self.globals.add(name)
155
156 def visitFunction(self, node):
157 self.names.add(node.name)
158
159 def visitLambda(self, node):
160 pass
161
162 def visitImport(self, node):
163 for name, alias in node.names:
164 self.names.add(alias or name)
165
166 def visitFrom(self, node):
167 for name, alias in node.names:
168 self.names.add(alias or name)
169
170 def visitClass(self, node):
171 self.names.add(node.name)
172
173 def visitAssName(self, node):
174 self.names.add(node.name)
175
Jeremy Hylton2afff322001-08-27 21:51:52 +0000176def is_constant_false(node):
177 if isinstance(node, ast.Const):
178 if not node.value:
179 return 1
180 return 0
181
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000182class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000183 """Defines basic code generator for Python bytecode
184
185 This class is an abstract base class. Concrete subclasses must
186 define an __init__() that defines self.graph and then calls the
187 __init__() defined in this class.
188
189 The concrete class must also define the class attributes
190 NameFinder, FunctionGen, and ClassGen. These attributes can be
191 defined in the initClass() method, which is a hook for
192 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000193 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000194 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000195
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000196 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000197 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000198 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000199
Jeremy Hylton37c93512001-09-17 18:03:55 +0000200 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000201 if self.__initialized is None:
202 self.initClass()
203 self.__class__.__initialized = 1
204 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000205 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000206 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000207 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000208 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000209 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000210
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000211 # XXX set flags based on future features
212 futures = self.get_module().futures
213 for feature in futures:
214 if feature == "division":
215 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000216 self._div_op = "BINARY_TRUE_DIVIDE"
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000217 elif feature == "absolute_import":
218 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
219 elif feature == "with_statement":
220 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000221
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000222 def initClass(self):
223 """This method is called once for each class"""
224
225 def checkClass(self):
226 """Verify that class is constructed correctly"""
227 try:
228 assert hasattr(self, 'graph')
229 assert getattr(self, 'NameFinder')
230 assert getattr(self, 'FunctionGen')
231 assert getattr(self, 'ClassGen')
232 except AssertionError, msg:
233 intro = "Bad class construction for %s" % self.__class__.__name__
234 raise AssertionError, intro
235
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000236 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000237 self.emit = self.graph.emit
238 self.newBlock = self.graph.newBlock
239 self.startBlock = self.graph.startBlock
240 self.nextBlock = self.graph.nextBlock
241 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000242
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000243 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000244 """Return a code object"""
245 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000246
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000247 def mangle(self, name):
248 if self.class_name is not None:
249 return misc.mangle(name, self.class_name)
250 else:
251 return name
252
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000253 def parseSymbols(self, tree):
254 s = symbols.SymbolVisitor()
255 walk(tree, s)
256 return s.scopes
257
258 def get_module(self):
259 raise RuntimeError, "should be implemented by subclasses"
260
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000261 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000262
Jeremy Hylton40245602000-02-08 21:15:48 +0000263 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000264 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000265
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000266 def storeName(self, name):
267 self._nameOp('STORE', name)
268
269 def loadName(self, name):
270 self._nameOp('LOAD', name)
271
272 def delName(self, name):
273 self._nameOp('DELETE', name)
274
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000275 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000276 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000277 scope = self.scope.check_name(name)
278 if scope == SC_LOCAL:
279 if not self.optimized:
280 self.emit(prefix + '_NAME', name)
281 else:
282 self.emit(prefix + '_FAST', name)
283 elif scope == SC_GLOBAL:
284 if not self.optimized:
285 self.emit(prefix + '_NAME', name)
286 else:
287 self.emit(prefix + '_GLOBAL', name)
288 elif scope == SC_FREE or scope == SC_CELL:
289 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000290 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000291 raise RuntimeError, "unsupported scope for var %s: %d" % \
292 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000293
Jeremy Hylton13d70942001-04-12 21:04:43 +0000294 def _implicitNameOp(self, prefix, name):
295 """Emit name ops for names generated implicitly by for loops
296
297 The interpreter generates names that start with a period or
298 dollar sign. The symbol table ignores these names because
299 they aren't present in the program text.
300 """
301 if self.optimized:
302 self.emit(prefix + '_FAST', name)
303 else:
304 self.emit(prefix + '_NAME', name)
305
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000306 # The set_lineno() function and the explicit emit() calls for
307 # SET_LINENO below are only used to generate the line number table.
308 # As of Python 2.3, the interpreter does not have a SET_LINENO
309 # instruction. pyassem treats SET_LINENO opcodes as a special case.
310
311 def set_lineno(self, node, force=False):
312 """Emit SET_LINENO if necessary.
313
314 The instruction is considered necessary if the node has a
315 lineno attribute and it is different than the last lineno
316 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000317
318 Returns true if SET_LINENO was emitted.
319
320 There are no rules for when an AST node should have a lineno
321 attribute. The transformer and AST code need to be reviewed
322 and a consistent policy implemented and documented. Until
323 then, this method works around missing line numbers.
324 """
325 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000326 if lineno is not None and (lineno != self.last_lineno
327 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000328 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000329 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000330 return True
331 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000332
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000333 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000334 # code objects. They use class attributes to determine what
335 # specialized code generators to use.
336
337 NameFinder = LocalNameFinder
338 FunctionGen = None
339 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000340
341 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000342 self.scopes = self.parseSymbols(node)
343 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000344 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000345 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000346 self.emit('LOAD_CONST', node.doc)
347 self.storeName('__doc__')
348 lnf = walk(node.node, self.NameFinder(), verbose=0)
349 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000350 self.visit(node.node)
351 self.emit('LOAD_CONST', None)
352 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000353
Barry Warsaw52acb492001-12-21 20:04:22 +0000354 def visitExpression(self, node):
355 self.set_lineno(node)
356 self.scopes = self.parseSymbols(node)
357 self.scope = self.scopes[node]
358 self.visit(node.node)
359 self.emit('RETURN_VALUE')
360
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000361 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000362 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000363 if node.doc:
364 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000365 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000366
367 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000368 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000369
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000370 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000371 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000372 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000373 self.visit(decorator)
374 ndecorators = len(node.decorators.nodes)
375 else:
376 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000377
Jeremy Hylton37c93512001-09-17 18:03:55 +0000378 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000379 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000380 walk(node.code, gen)
381 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000382 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000383 for default in node.defaults:
384 self.visit(default)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000385 self._makeClosure(gen, len(node.defaults))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000386 for i in range(ndecorators):
387 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000388
389 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000390 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000391 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000392 walk(node.code, gen)
393 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000394 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000395 self.emit('LOAD_CONST', node.name)
396 for base in node.bases:
397 self.visit(base)
398 self.emit('BUILD_TUPLE', len(node.bases))
Neil Schemenauer06ded092006-08-04 16:20:30 +0000399 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000400 self.emit('CALL_FUNCTION', 0)
401 self.emit('BUILD_CLASS')
402 self.storeName(node.name)
403
404 # The rest are standard visitor methods
405
406 # The next few implement control-flow statements
407
408 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000409 end = self.newBlock()
410 numtests = len(node.tests)
411 for i in range(numtests):
412 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000413 if is_constant_false(test):
414 # XXX will need to check generator stuff here
415 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000416 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000417 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000418 nextTest = self.newBlock()
419 self.emit('JUMP_IF_FALSE', nextTest)
420 self.nextBlock()
421 self.emit('POP_TOP')
422 self.visit(suite)
423 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000424 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000425 self.emit('POP_TOP')
426 if node.else_:
427 self.visit(node.else_)
428 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000429
430 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000431 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000432
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000433 loop = self.newBlock()
434 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000435
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000436 after = self.newBlock()
437 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000438
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000439 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000440 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000441
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000442 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000443 self.visit(node.test)
444 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000445
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000446 self.nextBlock()
447 self.emit('POP_TOP')
448 self.visit(node.body)
449 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000450
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000451 self.startBlock(else_) # or just the POPs if not else clause
452 self.emit('POP_TOP')
453 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000454 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000455 if node.else_:
456 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000458
459 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000461 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000462 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000463 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000464
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000465 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000466 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000467 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000468 self.emit('GET_ITER')
469
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000470 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000471 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000472 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000473 self.visit(node.assign)
474 self.visit(node.body)
475 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000476 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000477 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000478 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000479 if node.else_:
480 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000481 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000482
483 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000484 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000485 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000486 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000487 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000488 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000489
490 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000491 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000492 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000493 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000494 kind, block = self.setups.top()
495 if kind == LOOP:
496 self.set_lineno(node)
497 self.emit('JUMP_ABSOLUTE', block)
498 self.nextBlock()
499 elif kind == EXCEPT or kind == TRY_FINALLY:
500 self.set_lineno(node)
501 # find the block that starts the loop
502 top = len(self.setups)
503 while top > 0:
504 top = top - 1
505 kind, loop_block = self.setups[top]
506 if kind == LOOP:
507 break
508 if kind != LOOP:
509 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000510 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000511 self.emit('CONTINUE_LOOP', loop_block)
512 self.nextBlock()
513 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000514 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000515 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000516
517 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000518 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000519 for child in node.nodes[:-1]:
520 self.visit(child)
521 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000522 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000523 self.emit('POP_TOP')
524 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000525 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000526
527 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000528 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000529
530 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000531 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000533 def visitIfExp(self, node):
534 endblock = self.newBlock()
535 elseblock = self.newBlock()
536 self.visit(node.test)
537 self.emit('JUMP_IF_FALSE', elseblock)
538 self.emit('POP_TOP')
539 self.visit(node.then)
540 self.emit('JUMP_FORWARD', endblock)
541 self.nextBlock(elseblock)
542 self.emit('POP_TOP')
543 self.visit(node.else_)
544 self.nextBlock(endblock)
545
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000546 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000547 self.visit(node.expr)
548 cleanup = self.newBlock()
549 for op, code in node.ops[:-1]:
550 self.visit(code)
551 self.emit('DUP_TOP')
552 self.emit('ROT_THREE')
553 self.emit('COMPARE_OP', op)
554 self.emit('JUMP_IF_FALSE', cleanup)
555 self.nextBlock()
556 self.emit('POP_TOP')
557 # now do the last comparison
558 if node.ops:
559 op, code = node.ops[-1]
560 self.visit(code)
561 self.emit('COMPARE_OP', op)
562 if len(node.ops) > 1:
563 end = self.newBlock()
564 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000565 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000566 self.emit('ROT_TWO')
567 self.emit('POP_TOP')
568 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000569
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000570 # list comprehensions
571 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000572
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000573 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000574 self.set_lineno(node)
575 # setup list
Georg Brandl5addf702006-10-29 08:53:06 +0000576 tmpname = "$list%d" % self.__list_count
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000577 self.__list_count = self.__list_count + 1
578 self.emit('BUILD_LIST', 0)
579 self.emit('DUP_TOP')
Georg Brandl5addf702006-10-29 08:53:06 +0000580 self._implicitNameOp('STORE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000581
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000582 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000583 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000584 start, anchor = self.visit(for_)
585 cont = None
586 for if_ in for_.ifs:
587 if cont is None:
588 cont = self.newBlock()
589 self.visit(if_, cont)
590 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000591
Georg Brandl5addf702006-10-29 08:53:06 +0000592 self._implicitNameOp('LOAD', tmpname)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000593 self.visit(node.expr)
Georg Brandlfe9c71b2006-10-29 09:01:01 +0000594 self.emit('LIST_APPEND')
Tim Peterse0c446b2001-10-18 21:57:37 +0000595
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000596 for start, cont, anchor in stack:
597 if cont:
598 skip_one = self.newBlock()
599 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000600 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000601 self.emit('POP_TOP')
602 self.nextBlock(skip_one)
603 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000604 self.startBlock(anchor)
Georg Brandl5addf702006-10-29 08:53:06 +0000605 self._implicitNameOp('DELETE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000606
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000607 self.__list_count = self.__list_count - 1
608
609 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610 start = self.newBlock()
611 anchor = self.newBlock()
612
613 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000614 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000615 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000616 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000617 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000618 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000619 self.visit(node.assign)
620 return start, anchor
621
622 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000623 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000624 self.visit(node.test)
625 self.emit('JUMP_IF_FALSE', branch)
626 self.newBlock()
627 self.emit('POP_TOP')
628
Neil Schemenauer06ded092006-08-04 16:20:30 +0000629 def _makeClosure(self, gen, args):
630 frees = gen.scope.get_free_vars()
631 if frees:
632 for name in frees:
633 self.emit('LOAD_CLOSURE', name)
634 self.emit('BUILD_TUPLE', len(frees))
635 self.emit('LOAD_CONST', gen)
636 self.emit('MAKE_CLOSURE', args)
637 else:
638 self.emit('LOAD_CONST', gen)
639 self.emit('MAKE_FUNCTION', args)
640
Raymond Hettinger354433a2004-05-19 08:20:33 +0000641 def visitGenExpr(self, node):
642 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
643 self.get_module())
644 walk(node.code, gen)
645 gen.finish()
646 self.set_lineno(node)
Neil Schemenauer06ded092006-08-04 16:20:30 +0000647 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000648 # precomputation of outmost iterable
649 self.visit(node.code.quals[0].iter)
650 self.emit('GET_ITER')
651 self.emit('CALL_FUNCTION', 1)
652
653 def visitGenExprInner(self, node):
654 self.set_lineno(node)
655 # setup list
656
657 stack = []
658 for i, for_ in zip(range(len(node.quals)), node.quals):
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000659 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000660 cont = None
661 for if_ in for_.ifs:
662 if cont is None:
663 cont = self.newBlock()
664 self.visit(if_, cont)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000665 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000666
667 self.visit(node.expr)
668 self.emit('YIELD_VALUE')
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000669 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000670
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000671 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000672 if cont:
673 skip_one = self.newBlock()
674 self.emit('JUMP_FORWARD', skip_one)
675 self.startBlock(cont)
676 self.emit('POP_TOP')
677 self.nextBlock(skip_one)
678 self.emit('JUMP_ABSOLUTE', start)
679 self.startBlock(anchor)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000680 self.emit('POP_BLOCK')
681 self.setups.pop()
682 self.startBlock(end)
683
Raymond Hettinger354433a2004-05-19 08:20:33 +0000684 self.emit('LOAD_CONST', None)
685
686 def visitGenExprFor(self, node):
687 start = self.newBlock()
688 anchor = self.newBlock()
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000689 end = self.newBlock()
690
691 self.setups.push((LOOP, start))
692 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000693
Raymond Hettinger354433a2004-05-19 08:20:33 +0000694 if node.is_outmost:
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000695 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000696 else:
697 self.visit(node.iter)
698 self.emit('GET_ITER')
699
700 self.nextBlock(start)
701 self.set_lineno(node, force=True)
702 self.emit('FOR_ITER', anchor)
703 self.nextBlock()
704 self.visit(node.assign)
Neil Schemenauer4c6b0d52006-08-16 23:38:05 +0000705 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000706
707 def visitGenExprIf(self, node, branch):
708 self.set_lineno(node, force=True)
709 self.visit(node.test)
710 self.emit('JUMP_IF_FALSE', branch)
711 self.newBlock()
712 self.emit('POP_TOP')
713
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000714 # exception related
715
716 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000717 # XXX would be interesting to implement this via a
718 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000719 if __debug__:
720 end = self.newBlock()
721 self.set_lineno(node)
722 # XXX AssertionError appears to be special case -- it is always
723 # loaded as a global even if there is a local name. I guess this
724 # is a sort of renaming op.
725 self.nextBlock()
726 self.visit(node.test)
727 self.emit('JUMP_IF_TRUE', end)
728 self.nextBlock()
729 self.emit('POP_TOP')
730 self.emit('LOAD_GLOBAL', 'AssertionError')
731 if node.fail:
732 self.visit(node.fail)
733 self.emit('RAISE_VARARGS', 2)
734 else:
735 self.emit('RAISE_VARARGS', 1)
736 self.nextBlock(end)
737 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000738
739 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000740 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000741 n = 0
742 if node.expr1:
743 self.visit(node.expr1)
744 n = n + 1
745 if node.expr2:
746 self.visit(node.expr2)
747 n = n + 1
748 if node.expr3:
749 self.visit(node.expr3)
750 n = n + 1
751 self.emit('RAISE_VARARGS', n)
752
753 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000754 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000755 handlers = self.newBlock()
756 end = self.newBlock()
757 if node.else_:
758 lElse = self.newBlock()
759 else:
760 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000761 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000762 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000763 self.nextBlock(body)
764 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000765 self.visit(node.body)
766 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000767 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000768 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000769 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000770
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000771 last = len(node.handlers) - 1
772 for i in range(len(node.handlers)):
773 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000774 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 if expr:
776 self.emit('DUP_TOP')
777 self.visit(expr)
778 self.emit('COMPARE_OP', 'exception match')
779 next = self.newBlock()
780 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000781 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000782 self.emit('POP_TOP')
783 self.emit('POP_TOP')
784 if target:
785 self.visit(target)
786 else:
787 self.emit('POP_TOP')
788 self.emit('POP_TOP')
789 self.visit(body)
790 self.emit('JUMP_FORWARD', end)
791 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000792 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000793 else:
794 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000795 if expr: # XXX
796 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000797 self.emit('END_FINALLY')
798 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000799 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000801 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000802
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000804 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000806 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000807 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 self.nextBlock(body)
809 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000810 self.visit(node.body)
811 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000812 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000813 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000814 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000815 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000816 self.visit(node.final)
817 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000818 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000819
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000820 __with_count = 0
821
822 def visitWith(self, node):
823 body = self.newBlock()
824 final = self.newBlock()
825 exitvar = "$exit%d" % self.__with_count
826 valuevar = "$value%d" % self.__with_count
827 self.__with_count += 1
828 self.set_lineno(node)
829 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000830 self.emit('DUP_TOP')
831 self.emit('LOAD_ATTR', '__exit__')
832 self._implicitNameOp('STORE', exitvar)
833 self.emit('LOAD_ATTR', '__enter__')
834 self.emit('CALL_FUNCTION', 0)
835 if node.vars is None:
836 self.emit('POP_TOP')
837 else:
838 self._implicitNameOp('STORE', valuevar)
839 self.emit('SETUP_FINALLY', final)
840 self.nextBlock(body)
841 self.setups.push((TRY_FINALLY, body))
842 if node.vars is not None:
843 self._implicitNameOp('LOAD', valuevar)
844 self._implicitNameOp('DELETE', valuevar)
845 self.visit(node.vars)
846 self.visit(node.body)
847 self.emit('POP_BLOCK')
848 self.setups.pop()
849 self.emit('LOAD_CONST', None)
850 self.nextBlock(final)
851 self.setups.push((END_FINALLY, final))
Georg Brandlab496842007-01-27 17:43:02 +0000852 self._implicitNameOp('LOAD', exitvar)
853 self._implicitNameOp('DELETE', exitvar)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000854 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000855 self.emit('END_FINALLY')
856 self.setups.pop()
857 self.__with_count -= 1
858
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000859 # misc
860
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000861 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000862 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000863 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000864 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000865
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000866 def visitConst(self, node):
867 self.emit('LOAD_CONST', node.value)
868
869 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000870 self.emit('LOAD_CONST', node.name)
871 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000872
873 def visitGlobal(self, node):
874 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000875 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000876
877 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000878 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000879 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000880
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000881 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000882 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000883
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000884 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000885 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000886 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000887 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000888 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000889 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000890 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000891 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000892 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000893 if alias:
894 self._resolveDots(name)
895 self.storeName(alias)
896 else:
897 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000898
899 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000900 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000901 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000902 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000903 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000904 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000905 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000906 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000907 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000908 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000909 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000910 if VERSION > 1:
911 if name == '*':
912 self.namespace = 0
913 self.emit('IMPORT_STAR')
914 # There can only be one name w/ from ... import *
915 assert len(node.names) == 1
916 return
917 else:
918 self.emit('IMPORT_FROM', name)
919 self._resolveDots(name)
920 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000921 else:
922 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000923 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000924
Jeremy Hylton20516082000-09-01 20:33:26 +0000925 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000926 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000927 if len(elts) == 1:
928 return
929 for elt in elts[1:]:
930 self.emit('LOAD_ATTR', elt)
931
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000932 def visitGetattr(self, node):
933 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000934 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000935
936 # next five implement assignments
937
938 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000939 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000940 self.visit(node.expr)
941 dups = len(node.nodes) - 1
942 for i in range(len(node.nodes)):
943 elt = node.nodes[i]
944 if i < dups:
945 self.emit('DUP_TOP')
946 if isinstance(elt, ast.Node):
947 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000948
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000949 def visitAssName(self, node):
950 if node.flags == 'OP_ASSIGN':
951 self.storeName(node.name)
952 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000953 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000954 self.delName(node.name)
955 else:
956 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000957
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000958 def visitAssAttr(self, node):
959 self.visit(node.expr)
960 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000961 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000962 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000963 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000964 else:
965 print "warning: unexpected flags:", node.flags
966 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000967
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000968 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000969 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000970 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000971 for child in node.nodes:
972 self.visit(child)
973
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000974 if VERSION > 1:
975 visitAssTuple = _visitAssSequence
976 visitAssList = _visitAssSequence
977 else:
978 def visitAssTuple(self, node):
979 self._visitAssSequence(node, 'UNPACK_TUPLE')
980
981 def visitAssList(self, node):
982 self._visitAssSequence(node, 'UNPACK_LIST')
983
984 # augmented assignment
985
986 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000987 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000988 aug_node = wrap_aug(node.node)
989 self.visit(aug_node, "load")
990 self.visit(node.expr)
991 self.emit(self._augmented_opcode[node.op])
992 self.visit(aug_node, "store")
993
994 _augmented_opcode = {
995 '+=' : 'INPLACE_ADD',
996 '-=' : 'INPLACE_SUBTRACT',
997 '*=' : 'INPLACE_MULTIPLY',
998 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000999 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001000 '%=' : 'INPLACE_MODULO',
1001 '**=': 'INPLACE_POWER',
1002 '>>=': 'INPLACE_RSHIFT',
1003 '<<=': 'INPLACE_LSHIFT',
1004 '&=' : 'INPLACE_AND',
1005 '^=' : 'INPLACE_XOR',
1006 '|=' : 'INPLACE_OR',
1007 }
1008
1009 def visitAugName(self, node, mode):
1010 if mode == "load":
1011 self.loadName(node.name)
1012 elif mode == "store":
1013 self.storeName(node.name)
1014
1015 def visitAugGetattr(self, node, mode):
1016 if mode == "load":
1017 self.visit(node.expr)
1018 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001019 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001020 elif mode == "store":
1021 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001022 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001023
1024 def visitAugSlice(self, node, mode):
1025 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001026 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001027 elif mode == "store":
1028 slice = 0
1029 if node.lower:
1030 slice = slice | 1
1031 if node.upper:
1032 slice = slice | 2
1033 if slice == 0:
1034 self.emit('ROT_TWO')
1035 elif slice == 3:
1036 self.emit('ROT_FOUR')
1037 else:
1038 self.emit('ROT_THREE')
1039 self.emit('STORE_SLICE+%d' % slice)
1040
1041 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001042 if mode == "load":
1043 self.visitSubscript(node, 1)
1044 elif mode == "store":
1045 self.emit('ROT_THREE')
1046 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001047
1048 def visitExec(self, node):
1049 self.visit(node.expr)
1050 if node.locals is None:
1051 self.emit('LOAD_CONST', None)
1052 else:
1053 self.visit(node.locals)
1054 if node.globals is None:
1055 self.emit('DUP_TOP')
1056 else:
1057 self.visit(node.globals)
1058 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001059
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001060 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001061 pos = 0
1062 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001063 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001064 self.visit(node.node)
1065 for arg in node.args:
1066 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001067 if isinstance(arg, ast.Keyword):
1068 kw = kw + 1
1069 else:
1070 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001071 if node.star_args is not None:
1072 self.visit(node.star_args)
1073 if node.dstar_args is not None:
1074 self.visit(node.dstar_args)
1075 have_star = node.star_args is not None
1076 have_dstar = node.dstar_args is not None
1077 opcode = callfunc_opcode_info[have_star, have_dstar]
1078 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001079
Jeremy Hylton2afff322001-08-27 21:51:52 +00001080 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001081 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001082 if node.dest:
1083 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001084 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001085 if node.dest:
1086 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001087 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001088 if node.dest:
1089 self.emit('ROT_TWO')
1090 self.emit('PRINT_ITEM_TO')
1091 else:
1092 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001093 if node.dest and not newline:
1094 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001095
1096 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001097 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001098 if node.dest:
1099 self.emit('PRINT_NEWLINE_TO')
1100 else:
1101 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001102
1103 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001104 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001105 self.visit(node.value)
1106 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001107
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001108 def visitYield(self, node):
1109 self.set_lineno(node)
1110 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001111 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001112
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001113 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001114
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001115 def visitSlice(self, node, aug_flag=None):
1116 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001117 self.visit(node.expr)
1118 slice = 0
1119 if node.lower:
1120 self.visit(node.lower)
1121 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001122 if node.upper:
1123 self.visit(node.upper)
1124 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001125 if aug_flag:
1126 if slice == 0:
1127 self.emit('DUP_TOP')
1128 elif slice == 3:
1129 self.emit('DUP_TOPX', 3)
1130 else:
1131 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001132 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001133 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001134 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001135 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001136 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001137 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001138 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001139 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001140 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001141
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001142 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001143 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001144 for sub in node.subs:
1145 self.visit(sub)
1146 if len(node.subs) > 1:
1147 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001148 if aug_flag:
1149 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001150 if node.flags == 'OP_APPLY':
1151 self.emit('BINARY_SUBSCR')
1152 elif node.flags == 'OP_ASSIGN':
1153 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001154 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001155 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001156
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001157 # binary ops
1158
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001159 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001160 self.visit(node.left)
1161 self.visit(node.right)
1162 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001163
1164 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001165 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001166
1167 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001168 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001169
1170 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001171 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001172
1173 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001174 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001175
Jeremy Hylton94afe322001-08-29 18:14:39 +00001176 def visitFloorDiv(self, node):
1177 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1178
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001179 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001180 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001181
Jeremy Hylton126960b2000-02-14 21:33:10 +00001182 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001183 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001184
1185 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001186 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001187
1188 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001189 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001190
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001191 # unary ops
1192
1193 def unaryOp(self, node, op):
1194 self.visit(node.expr)
1195 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001196
Jeremy Hylton126960b2000-02-14 21:33:10 +00001197 def visitInvert(self, node):
1198 return self.unaryOp(node, 'UNARY_INVERT')
1199
Jeremy Hylton40245602000-02-08 21:15:48 +00001200 def visitUnarySub(self, node):
1201 return self.unaryOp(node, 'UNARY_NEGATIVE')
1202
1203 def visitUnaryAdd(self, node):
1204 return self.unaryOp(node, 'UNARY_POSITIVE')
1205
1206 def visitUnaryInvert(self, node):
1207 return self.unaryOp(node, 'UNARY_INVERT')
1208
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001209 def visitNot(self, node):
1210 return self.unaryOp(node, 'UNARY_NOT')
1211
Jeremy Hylton40245602000-02-08 21:15:48 +00001212 def visitBackquote(self, node):
1213 return self.unaryOp(node, 'UNARY_CONVERT')
1214
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001215 # bit ops
1216
Jeremy Hyltona5058122000-02-14 14:14:29 +00001217 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001218 self.visit(nodes[0])
1219 for node in nodes[1:]:
1220 self.visit(node)
1221 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001222
1223 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001224 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001225
1226 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001227 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001228
1229 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001230 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001231
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001232 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001233
Jeremy Hyltona5058122000-02-14 14:14:29 +00001234 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001235 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001236
Jeremy Hylton40245602000-02-08 21:15:48 +00001237 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001238 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001239 for elt in node.nodes:
1240 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001241 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001242
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001243 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001244 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001245 for elt in node.nodes:
1246 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001247 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001248
1249 def visitSliceobj(self, node):
1250 for child in node.nodes:
1251 self.visit(child)
1252 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001253
Jeremy Hyltona5058122000-02-14 14:14:29 +00001254 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001255 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001256 self.emit('BUILD_MAP', 0)
1257 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001258 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001259 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001260 self.visit(v)
1261 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001262 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001263
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001264class NestedScopeMixin:
1265 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001266 def initClass(self):
1267 self.__class__.NameFinder = LocalNameFinder
1268 self.__class__.FunctionGen = FunctionCodeGenerator
1269 self.__class__.ClassGen = ClassCodeGenerator
1270
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001271class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001272 __super_init = CodeGenerator.__init__
1273
1274 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001275
Jeremy Hylton37c93512001-09-17 18:03:55 +00001276 def __init__(self, tree):
1277 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001278 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001279 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001280 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001281
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001282 def get_module(self):
1283 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001284
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001285class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1286 __super_init = CodeGenerator.__init__
1287
1288 scopes = None
1289 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001290
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001291 def __init__(self, tree):
1292 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1293 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001294 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001295
1296 def get_module(self):
1297 return self
1298
1299class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1300
1301 __super_init = CodeGenerator.__init__
1302
1303 scopes = None
1304 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001305
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001306 def __init__(self, tree):
1307 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1308 self.__super_init()
1309 self.set_lineno(tree)
1310 walk(tree, self)
1311 self.emit('RETURN_VALUE')
1312
1313 def get_module(self):
1314 return self
Tim Peterse4418602002-02-16 07:34:19 +00001315
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001316 def visitDiscard(self, node):
1317 # XXX Discard means it's an expression. Perhaps this is a bad
1318 # name.
1319 self.visit(node.expr)
1320 self.emit('PRINT_EXPR')
1321
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001322class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001323 optimized = 1
1324 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001325
Jeremy Hylton37c93512001-09-17 18:03:55 +00001326 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001327 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001328 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001329 if isLambda:
1330 klass = FunctionCodeGenerator
1331 name = "<lambda.%d>" % klass.lambdaCount
1332 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001333 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001334 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001335
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001336 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001337 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1338 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001339 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001340 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001341
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001342 if not isLambda and func.doc:
1343 self.setDocstring(func.doc)
1344
Jeremy Hylton2afff322001-08-27 21:51:52 +00001345 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001346 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001347 if func.varargs:
1348 self.graph.setFlag(CO_VARARGS)
1349 if func.kwargs:
1350 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001351 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001352 if hasTupleArg:
1353 self.generateArgUnpack(func.argnames)
1354
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001355 def get_module(self):
1356 return self.module
1357
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001358 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001359 self.graph.startExitBlock()
1360 if not self.isLambda:
1361 self.emit('LOAD_CONST', None)
1362 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001363
1364 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001365 for i in range(len(args)):
1366 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001367 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001368 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001369 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001370
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001371 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001372 if VERSION > 1:
1373 self.emit('UNPACK_SEQUENCE', len(tup))
1374 else:
1375 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001376 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001377 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001378 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001379 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001380 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001381
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001382 unpackTuple = unpackSequence
1383
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001384class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001385 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001386 super_init = CodeGenerator.__init__ # call be other init
1387 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001388
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001389 __super_init = AbstractFunctionCode.__init__
1390
Jeremy Hylton37c93512001-09-17 18:03:55 +00001391 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001392 self.scopes = scopes
1393 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001394 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001395 self.graph.setFreeVars(self.scope.get_free_vars())
1396 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001397 if self.scope.generator is not None:
1398 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001399
Raymond Hettinger354433a2004-05-19 08:20:33 +00001400class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1401 CodeGenerator):
1402 super_init = CodeGenerator.__init__ # call be other init
1403 scopes = None
1404
1405 __super_init = AbstractFunctionCode.__init__
1406
1407 def __init__(self, gexp, scopes, class_name, mod):
1408 self.scopes = scopes
1409 self.scope = scopes[gexp]
1410 self.__super_init(gexp, scopes, 1, class_name, mod)
1411 self.graph.setFreeVars(self.scope.get_free_vars())
1412 self.graph.setCellVars(self.scope.get_cell_vars())
1413 self.graph.setFlag(CO_GENERATOR)
1414
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001415class AbstractClassCode:
1416
Jeremy Hylton37c93512001-09-17 18:03:55 +00001417 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001418 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001419 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001420 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001421 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001422 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001423 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001424 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001425 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001426 if klass.doc:
1427 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001428
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001429 def get_module(self):
1430 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001431
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001432 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001433 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001434 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001435 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001436
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001437class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001438 super_init = CodeGenerator.__init__
1439 scopes = None
1440
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001441 __super_init = AbstractClassCode.__init__
1442
Jeremy Hylton37c93512001-09-17 18:03:55 +00001443 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001444 self.scopes = scopes
1445 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001446 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001447 self.graph.setFreeVars(self.scope.get_free_vars())
1448 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001449 self.set_lineno(klass)
1450 self.emit("LOAD_GLOBAL", "__name__")
1451 self.storeName("__module__")
1452 if klass.doc:
1453 self.emit("LOAD_CONST", klass.doc)
1454 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001455
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001456def generateArgList(arglist):
1457 """Generate an arg list marking TupleArgs"""
1458 args = []
1459 extra = []
1460 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001461 for i in range(len(arglist)):
1462 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001463 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001464 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001465 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001466 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001467 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001468 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001469 else:
1470 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001471 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001472
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001473def findOp(node):
1474 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1475 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001476 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001477 return v.op
1478
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001479class OpFinder:
1480 def __init__(self):
1481 self.op = None
1482 def visitAssName(self, node):
1483 if self.op is None:
1484 self.op = node.flags
1485 elif self.op != node.flags:
1486 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001487 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001488 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001489
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001490class Delegator:
1491 """Base class to support delegation for augmented assignment nodes
1492
1493 To generator code for augmented assignments, we use the following
1494 wrapper classes. In visitAugAssign, the left-hand expression node
1495 is visited twice. The first time the visit uses the normal method
1496 for that node . The second time the visit uses a different method
1497 that generates the appropriate code to perform the assignment.
1498 These delegator classes wrap the original AST nodes in order to
1499 support the variant visit methods.
1500 """
1501 def __init__(self, obj):
1502 self.obj = obj
1503
1504 def __getattr__(self, attr):
1505 return getattr(self.obj, attr)
1506
1507class AugGetattr(Delegator):
1508 pass
1509
1510class AugName(Delegator):
1511 pass
1512
1513class AugSlice(Delegator):
1514 pass
1515
1516class AugSubscript(Delegator):
1517 pass
1518
1519wrapper = {
1520 ast.Getattr: AugGetattr,
1521 ast.Name: AugName,
1522 ast.Slice: AugSlice,
1523 ast.Subscript: AugSubscript,
1524 }
1525
1526def wrap_aug(node):
1527 return wrapper[node.__class__](node)
1528
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001529if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001530 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001531 compileFile(file)