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