blob: aac2dda7e2244f8571130de9573ba1bf2b168dff [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)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000383 frees = gen.scope.get_free_vars()
384 if frees:
385 for name in frees:
386 self.emit('LOAD_CLOSURE', name)
387 self.emit('LOAD_CONST', gen)
388 self.emit('MAKE_CLOSURE', len(node.defaults))
389 else:
390 self.emit('LOAD_CONST', gen)
391 self.emit('MAKE_FUNCTION', len(node.defaults))
Tim Peters6db15d72004-08-04 02:36:18 +0000392
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000393 for i in range(ndecorators):
394 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000395
396 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000397 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000398 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000399 walk(node.code, gen)
400 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000401 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000402 self.emit('LOAD_CONST', node.name)
403 for base in node.bases:
404 self.visit(base)
405 self.emit('BUILD_TUPLE', len(node.bases))
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000406 frees = gen.scope.get_free_vars()
407 for name in frees:
408 self.emit('LOAD_CLOSURE', name)
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000409 self.emit('LOAD_CONST', gen)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000410 if frees:
411 self.emit('MAKE_CLOSURE', 0)
412 else:
413 self.emit('MAKE_FUNCTION', 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000414 self.emit('CALL_FUNCTION', 0)
415 self.emit('BUILD_CLASS')
416 self.storeName(node.name)
417
418 # The rest are standard visitor methods
419
420 # The next few implement control-flow statements
421
422 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000423 end = self.newBlock()
424 numtests = len(node.tests)
425 for i in range(numtests):
426 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000427 if is_constant_false(test):
428 # XXX will need to check generator stuff here
429 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000430 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000431 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000432 nextTest = self.newBlock()
433 self.emit('JUMP_IF_FALSE', nextTest)
434 self.nextBlock()
435 self.emit('POP_TOP')
436 self.visit(suite)
437 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000438 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000439 self.emit('POP_TOP')
440 if node.else_:
441 self.visit(node.else_)
442 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
444 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000445 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000446
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000447 loop = self.newBlock()
448 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000449
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000450 after = self.newBlock()
451 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000452
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000453 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000454 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000455
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000456 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.visit(node.test)
458 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000459
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 self.nextBlock()
461 self.emit('POP_TOP')
462 self.visit(node.body)
463 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000464
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000465 self.startBlock(else_) # or just the POPs if not else clause
466 self.emit('POP_TOP')
467 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000468 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000469 if node.else_:
470 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000471 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000472
473 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000474 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000476 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000477 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000479 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000480 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000482 self.emit('GET_ITER')
483
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000484 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000485 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000486 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000487 self.visit(node.assign)
488 self.visit(node.body)
489 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000490 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000491 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000492 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000493 if node.else_:
494 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000495 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000496
497 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000498 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000499 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000500 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000501 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000502 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000503
504 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000505 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000506 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000507 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000508 kind, block = self.setups.top()
509 if kind == LOOP:
510 self.set_lineno(node)
511 self.emit('JUMP_ABSOLUTE', block)
512 self.nextBlock()
513 elif kind == EXCEPT or kind == TRY_FINALLY:
514 self.set_lineno(node)
515 # find the block that starts the loop
516 top = len(self.setups)
517 while top > 0:
518 top = top - 1
519 kind, loop_block = self.setups[top]
520 if kind == LOOP:
521 break
522 if kind != LOOP:
523 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000524 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000525 self.emit('CONTINUE_LOOP', loop_block)
526 self.nextBlock()
527 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000528 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000529 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000530
531 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000532 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000533 for child in node.nodes[:-1]:
534 self.visit(child)
535 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000536 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000537 self.emit('POP_TOP')
538 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000539 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000540
541 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000542 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000543
544 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000545 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000546
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000547 def visitIfExp(self, node):
548 endblock = self.newBlock()
549 elseblock = self.newBlock()
550 self.visit(node.test)
551 self.emit('JUMP_IF_FALSE', elseblock)
552 self.emit('POP_TOP')
553 self.visit(node.then)
554 self.emit('JUMP_FORWARD', endblock)
555 self.nextBlock(elseblock)
556 self.emit('POP_TOP')
557 self.visit(node.else_)
558 self.nextBlock(endblock)
559
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000560 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000561 self.visit(node.expr)
562 cleanup = self.newBlock()
563 for op, code in node.ops[:-1]:
564 self.visit(code)
565 self.emit('DUP_TOP')
566 self.emit('ROT_THREE')
567 self.emit('COMPARE_OP', op)
568 self.emit('JUMP_IF_FALSE', cleanup)
569 self.nextBlock()
570 self.emit('POP_TOP')
571 # now do the last comparison
572 if node.ops:
573 op, code = node.ops[-1]
574 self.visit(code)
575 self.emit('COMPARE_OP', op)
576 if len(node.ops) > 1:
577 end = self.newBlock()
578 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000579 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000580 self.emit('ROT_TWO')
581 self.emit('POP_TOP')
582 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000583
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000584 # list comprehensions
585 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000586
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000587 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000588 self.set_lineno(node)
589 # setup list
590 append = "$append%d" % self.__list_count
591 self.__list_count = self.__list_count + 1
592 self.emit('BUILD_LIST', 0)
593 self.emit('DUP_TOP')
594 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000595 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000596
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000597 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000598 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000599 start, anchor = self.visit(for_)
600 cont = None
601 for if_ in for_.ifs:
602 if cont is None:
603 cont = self.newBlock()
604 self.visit(if_, cont)
605 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000606
Jeremy Hylton13d70942001-04-12 21:04:43 +0000607 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000608 self.visit(node.expr)
609 self.emit('CALL_FUNCTION', 1)
610 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000611
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000612 for start, cont, anchor in stack:
613 if cont:
614 skip_one = self.newBlock()
615 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000616 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.emit('POP_TOP')
618 self.nextBlock(skip_one)
619 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000620 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000621 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000622
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000623 self.__list_count = self.__list_count - 1
624
625 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000626 start = self.newBlock()
627 anchor = self.newBlock()
628
629 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000630 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000631 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000632 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000633 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000634 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000635 self.visit(node.assign)
636 return start, anchor
637
638 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000639 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000640 self.visit(node.test)
641 self.emit('JUMP_IF_FALSE', branch)
642 self.newBlock()
643 self.emit('POP_TOP')
644
Raymond Hettinger354433a2004-05-19 08:20:33 +0000645 def visitGenExpr(self, node):
646 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
647 self.get_module())
648 walk(node.code, gen)
649 gen.finish()
650 self.set_lineno(node)
651 frees = gen.scope.get_free_vars()
652 if frees:
653 for name in frees:
654 self.emit('LOAD_CLOSURE', name)
655 self.emit('LOAD_CONST', gen)
656 self.emit('MAKE_CLOSURE', 0)
657 else:
658 self.emit('LOAD_CONST', gen)
659 self.emit('MAKE_FUNCTION', 0)
660
661 # precomputation of outmost iterable
662 self.visit(node.code.quals[0].iter)
663 self.emit('GET_ITER')
664 self.emit('CALL_FUNCTION', 1)
665
666 def visitGenExprInner(self, node):
667 self.set_lineno(node)
668 # setup list
669
670 stack = []
671 for i, for_ in zip(range(len(node.quals)), node.quals):
672 start, anchor = self.visit(for_)
673 cont = None
674 for if_ in for_.ifs:
675 if cont is None:
676 cont = self.newBlock()
677 self.visit(if_, cont)
678 stack.insert(0, (start, cont, anchor))
679
680 self.visit(node.expr)
681 self.emit('YIELD_VALUE')
682
683 for start, cont, anchor in stack:
684 if cont:
685 skip_one = self.newBlock()
686 self.emit('JUMP_FORWARD', skip_one)
687 self.startBlock(cont)
688 self.emit('POP_TOP')
689 self.nextBlock(skip_one)
690 self.emit('JUMP_ABSOLUTE', start)
691 self.startBlock(anchor)
692 self.emit('LOAD_CONST', None)
693
694 def visitGenExprFor(self, node):
695 start = self.newBlock()
696 anchor = self.newBlock()
Tim Peters4e0e1b62004-07-07 20:54:48 +0000697
Raymond Hettinger354433a2004-05-19 08:20:33 +0000698 if node.is_outmost:
699 self.loadName('[outmost-iterable]')
700 else:
701 self.visit(node.iter)
702 self.emit('GET_ITER')
703
704 self.nextBlock(start)
705 self.set_lineno(node, force=True)
706 self.emit('FOR_ITER', anchor)
707 self.nextBlock()
708 self.visit(node.assign)
709 return start, anchor
710
711 def visitGenExprIf(self, node, branch):
712 self.set_lineno(node, force=True)
713 self.visit(node.test)
714 self.emit('JUMP_IF_FALSE', branch)
715 self.newBlock()
716 self.emit('POP_TOP')
717
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000718 # exception related
719
720 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000721 # XXX would be interesting to implement this via a
722 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000723 if __debug__:
724 end = self.newBlock()
725 self.set_lineno(node)
726 # XXX AssertionError appears to be special case -- it is always
727 # loaded as a global even if there is a local name. I guess this
728 # is a sort of renaming op.
729 self.nextBlock()
730 self.visit(node.test)
731 self.emit('JUMP_IF_TRUE', end)
732 self.nextBlock()
733 self.emit('POP_TOP')
734 self.emit('LOAD_GLOBAL', 'AssertionError')
735 if node.fail:
736 self.visit(node.fail)
737 self.emit('RAISE_VARARGS', 2)
738 else:
739 self.emit('RAISE_VARARGS', 1)
740 self.nextBlock(end)
741 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000742
743 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000744 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000745 n = 0
746 if node.expr1:
747 self.visit(node.expr1)
748 n = n + 1
749 if node.expr2:
750 self.visit(node.expr2)
751 n = n + 1
752 if node.expr3:
753 self.visit(node.expr3)
754 n = n + 1
755 self.emit('RAISE_VARARGS', n)
756
757 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000758 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000759 handlers = self.newBlock()
760 end = self.newBlock()
761 if node.else_:
762 lElse = self.newBlock()
763 else:
764 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000765 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000766 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000767 self.nextBlock(body)
768 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000769 self.visit(node.body)
770 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000771 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000772 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000773 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000774
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 last = len(node.handlers) - 1
776 for i in range(len(node.handlers)):
777 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000778 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000779 if expr:
780 self.emit('DUP_TOP')
781 self.visit(expr)
782 self.emit('COMPARE_OP', 'exception match')
783 next = self.newBlock()
784 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000785 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000786 self.emit('POP_TOP')
787 self.emit('POP_TOP')
788 if target:
789 self.visit(target)
790 else:
791 self.emit('POP_TOP')
792 self.emit('POP_TOP')
793 self.visit(body)
794 self.emit('JUMP_FORWARD', end)
795 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000796 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000797 else:
798 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000799 if expr: # XXX
800 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000801 self.emit('END_FINALLY')
802 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000803 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000804 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000805 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000806
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000807 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000810 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000812 self.nextBlock(body)
813 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000814 self.visit(node.body)
815 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000816 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000817 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000818 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000819 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000820 self.visit(node.final)
821 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000822 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000823
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000824 __with_count = 0
825
826 def visitWith(self, node):
827 body = self.newBlock()
828 final = self.newBlock()
829 exitvar = "$exit%d" % self.__with_count
830 valuevar = "$value%d" % self.__with_count
831 self.__with_count += 1
832 self.set_lineno(node)
833 self.visit(node.expr)
834 self.emit('LOAD_ATTR', '__context__')
835 self.emit('CALL_FUNCTION', 0)
836 self.emit('DUP_TOP')
837 self.emit('LOAD_ATTR', '__exit__')
838 self._implicitNameOp('STORE', exitvar)
839 self.emit('LOAD_ATTR', '__enter__')
840 self.emit('CALL_FUNCTION', 0)
841 if node.vars is None:
842 self.emit('POP_TOP')
843 else:
844 self._implicitNameOp('STORE', valuevar)
845 self.emit('SETUP_FINALLY', final)
846 self.nextBlock(body)
847 self.setups.push((TRY_FINALLY, body))
848 if node.vars is not None:
849 self._implicitNameOp('LOAD', valuevar)
850 self._implicitNameOp('DELETE', valuevar)
851 self.visit(node.vars)
852 self.visit(node.body)
853 self.emit('POP_BLOCK')
854 self.setups.pop()
855 self.emit('LOAD_CONST', None)
856 self.nextBlock(final)
857 self.setups.push((END_FINALLY, final))
858 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000859 self.emit('END_FINALLY')
860 self.setups.pop()
861 self.__with_count -= 1
862
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000863 # misc
864
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000865 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000866 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000867 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000868 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000869
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000870 def visitConst(self, node):
871 self.emit('LOAD_CONST', node.value)
872
873 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000874 self.emit('LOAD_CONST', node.name)
875 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000876
877 def visitGlobal(self, node):
878 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000879 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000880
881 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000882 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000883 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000884
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000885 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000886 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000887
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000888 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000889 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000890 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000891 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000892 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000893 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000894 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000895 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000896 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000897 if alias:
898 self._resolveDots(name)
899 self.storeName(alias)
900 else:
901 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000902
903 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000904 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000905 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000906 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000907 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000908 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000909 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000910 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000911 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000912 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000913 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000914 if VERSION > 1:
915 if name == '*':
916 self.namespace = 0
917 self.emit('IMPORT_STAR')
918 # There can only be one name w/ from ... import *
919 assert len(node.names) == 1
920 return
921 else:
922 self.emit('IMPORT_FROM', name)
923 self._resolveDots(name)
924 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000925 else:
926 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000927 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000928
Jeremy Hylton20516082000-09-01 20:33:26 +0000929 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000930 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000931 if len(elts) == 1:
932 return
933 for elt in elts[1:]:
934 self.emit('LOAD_ATTR', elt)
935
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000936 def visitGetattr(self, node):
937 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000938 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000939
940 # next five implement assignments
941
942 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000943 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000944 self.visit(node.expr)
945 dups = len(node.nodes) - 1
946 for i in range(len(node.nodes)):
947 elt = node.nodes[i]
948 if i < dups:
949 self.emit('DUP_TOP')
950 if isinstance(elt, ast.Node):
951 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000952
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000953 def visitAssName(self, node):
954 if node.flags == 'OP_ASSIGN':
955 self.storeName(node.name)
956 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000957 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000958 self.delName(node.name)
959 else:
960 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000961
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000962 def visitAssAttr(self, node):
963 self.visit(node.expr)
964 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000965 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000966 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000967 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000968 else:
969 print "warning: unexpected flags:", node.flags
970 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000971
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000972 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000973 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000974 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000975 for child in node.nodes:
976 self.visit(child)
977
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000978 if VERSION > 1:
979 visitAssTuple = _visitAssSequence
980 visitAssList = _visitAssSequence
981 else:
982 def visitAssTuple(self, node):
983 self._visitAssSequence(node, 'UNPACK_TUPLE')
984
985 def visitAssList(self, node):
986 self._visitAssSequence(node, 'UNPACK_LIST')
987
988 # augmented assignment
989
990 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000991 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000992 aug_node = wrap_aug(node.node)
993 self.visit(aug_node, "load")
994 self.visit(node.expr)
995 self.emit(self._augmented_opcode[node.op])
996 self.visit(aug_node, "store")
997
998 _augmented_opcode = {
999 '+=' : 'INPLACE_ADD',
1000 '-=' : 'INPLACE_SUBTRACT',
1001 '*=' : 'INPLACE_MULTIPLY',
Neal Norwitze7086d42006-03-17 08:59:09 +00001002 '/=' : 'INPLACE_TRUE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001003 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001004 '%=' : 'INPLACE_MODULO',
1005 '**=': 'INPLACE_POWER',
1006 '>>=': 'INPLACE_RSHIFT',
1007 '<<=': 'INPLACE_LSHIFT',
1008 '&=' : 'INPLACE_AND',
1009 '^=' : 'INPLACE_XOR',
1010 '|=' : 'INPLACE_OR',
1011 }
1012
1013 def visitAugName(self, node, mode):
1014 if mode == "load":
1015 self.loadName(node.name)
1016 elif mode == "store":
1017 self.storeName(node.name)
1018
1019 def visitAugGetattr(self, node, mode):
1020 if mode == "load":
1021 self.visit(node.expr)
1022 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001023 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001024 elif mode == "store":
1025 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001026 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001027
1028 def visitAugSlice(self, node, mode):
1029 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001030 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001031 elif mode == "store":
1032 slice = 0
1033 if node.lower:
1034 slice = slice | 1
1035 if node.upper:
1036 slice = slice | 2
1037 if slice == 0:
1038 self.emit('ROT_TWO')
1039 elif slice == 3:
1040 self.emit('ROT_FOUR')
1041 else:
1042 self.emit('ROT_THREE')
1043 self.emit('STORE_SLICE+%d' % slice)
1044
1045 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001046 if mode == "load":
1047 self.visitSubscript(node, 1)
1048 elif mode == "store":
1049 self.emit('ROT_THREE')
1050 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001051
1052 def visitExec(self, node):
1053 self.visit(node.expr)
1054 if node.locals is None:
1055 self.emit('LOAD_CONST', None)
1056 else:
1057 self.visit(node.locals)
1058 if node.globals is None:
1059 self.emit('DUP_TOP')
1060 else:
1061 self.visit(node.globals)
1062 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001063
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001064 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001065 pos = 0
1066 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001067 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001068 self.visit(node.node)
1069 for arg in node.args:
1070 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001071 if isinstance(arg, ast.Keyword):
1072 kw = kw + 1
1073 else:
1074 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001075 if node.star_args is not None:
1076 self.visit(node.star_args)
1077 if node.dstar_args is not None:
1078 self.visit(node.dstar_args)
1079 have_star = node.star_args is not None
1080 have_dstar = node.dstar_args is not None
1081 opcode = callfunc_opcode_info[have_star, have_dstar]
1082 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001083
Jeremy Hylton2afff322001-08-27 21:51:52 +00001084 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001085 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001086 if node.dest:
1087 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001088 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001089 if node.dest:
1090 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001091 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001092 if node.dest:
1093 self.emit('ROT_TWO')
1094 self.emit('PRINT_ITEM_TO')
1095 else:
1096 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001097 if node.dest and not newline:
1098 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001099
1100 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001101 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001102 if node.dest:
1103 self.emit('PRINT_NEWLINE_TO')
1104 else:
1105 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001106
1107 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001108 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001109 self.visit(node.value)
1110 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001111
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001112 def visitYield(self, node):
1113 self.set_lineno(node)
1114 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001115 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001116
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001117 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001118
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001119 def visitSlice(self, node, aug_flag=None):
1120 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001121 self.visit(node.expr)
1122 slice = 0
1123 if node.lower:
1124 self.visit(node.lower)
1125 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001126 if node.upper:
1127 self.visit(node.upper)
1128 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001129 if aug_flag:
1130 if slice == 0:
1131 self.emit('DUP_TOP')
1132 elif slice == 3:
1133 self.emit('DUP_TOPX', 3)
1134 else:
1135 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001136 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001137 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001138 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001139 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001140 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001141 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001142 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001143 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001144 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001145
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001146 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001147 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001148 for sub in node.subs:
1149 self.visit(sub)
1150 if len(node.subs) > 1:
1151 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001152 if aug_flag:
1153 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001154 if node.flags == 'OP_APPLY':
1155 self.emit('BINARY_SUBSCR')
1156 elif node.flags == 'OP_ASSIGN':
1157 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001158 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001159 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001160
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001161 # binary ops
1162
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001163 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001164 self.visit(node.left)
1165 self.visit(node.right)
1166 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001167
1168 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001169 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001170
1171 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001173
1174 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001175 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001176
1177 def visitDiv(self, node):
Neal Norwitzc6d210c2006-03-16 06:02:10 +00001178 return self.binaryOp(node, 'BINARY_TRUE_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001179
Jeremy Hylton94afe322001-08-29 18:14:39 +00001180 def visitFloorDiv(self, node):
1181 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1182
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001183 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001184 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001185
Jeremy Hylton126960b2000-02-14 21:33:10 +00001186 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001187 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001188
1189 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001190 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001191
1192 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001193 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001194
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001195 # unary ops
1196
1197 def unaryOp(self, node, op):
1198 self.visit(node.expr)
1199 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001200
Jeremy Hylton126960b2000-02-14 21:33:10 +00001201 def visitInvert(self, node):
1202 return self.unaryOp(node, 'UNARY_INVERT')
1203
Jeremy Hylton40245602000-02-08 21:15:48 +00001204 def visitUnarySub(self, node):
1205 return self.unaryOp(node, 'UNARY_NEGATIVE')
1206
1207 def visitUnaryAdd(self, node):
1208 return self.unaryOp(node, 'UNARY_POSITIVE')
1209
1210 def visitUnaryInvert(self, node):
1211 return self.unaryOp(node, 'UNARY_INVERT')
1212
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001213 def visitNot(self, node):
1214 return self.unaryOp(node, 'UNARY_NOT')
1215
Jeremy Hylton40245602000-02-08 21:15:48 +00001216 def visitBackquote(self, node):
1217 return self.unaryOp(node, 'UNARY_CONVERT')
1218
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001219 # bit ops
1220
Jeremy Hyltona5058122000-02-14 14:14:29 +00001221 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001222 self.visit(nodes[0])
1223 for node in nodes[1:]:
1224 self.visit(node)
1225 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001226
1227 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001228 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001229
1230 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001231 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001232
1233 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001234 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001235
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001236 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001237
Jeremy Hyltona5058122000-02-14 14:14:29 +00001238 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001239 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001240
Jeremy Hylton40245602000-02-08 21:15:48 +00001241 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001242 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001243 for elt in node.nodes:
1244 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001245 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001246
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001247 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001248 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001249 for elt in node.nodes:
1250 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001251 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001252
1253 def visitSliceobj(self, node):
1254 for child in node.nodes:
1255 self.visit(child)
1256 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001257
Jeremy Hyltona5058122000-02-14 14:14:29 +00001258 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001259 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001260 self.emit('BUILD_MAP', 0)
1261 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001262 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001263 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001264 self.visit(v)
1265 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001266 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001267
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001268class NestedScopeMixin:
1269 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001270 def initClass(self):
1271 self.__class__.NameFinder = LocalNameFinder
1272 self.__class__.FunctionGen = FunctionCodeGenerator
1273 self.__class__.ClassGen = ClassCodeGenerator
1274
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001275class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001276 __super_init = CodeGenerator.__init__
1277
1278 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001279
Jeremy Hylton37c93512001-09-17 18:03:55 +00001280 def __init__(self, tree):
1281 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001282 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001283 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001284 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001285
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001286 def get_module(self):
1287 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001288
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001289class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
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("<expression>", tree.filename)
1297 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001298 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001299
1300 def get_module(self):
1301 return self
1302
1303class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1304
1305 __super_init = CodeGenerator.__init__
1306
1307 scopes = None
1308 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001309
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001310 def __init__(self, tree):
1311 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1312 self.__super_init()
1313 self.set_lineno(tree)
1314 walk(tree, self)
1315 self.emit('RETURN_VALUE')
1316
1317 def get_module(self):
1318 return self
Tim Peterse4418602002-02-16 07:34:19 +00001319
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001320 def visitDiscard(self, node):
1321 # XXX Discard means it's an expression. Perhaps this is a bad
1322 # name.
1323 self.visit(node.expr)
1324 self.emit('PRINT_EXPR')
1325
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001326class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001327 optimized = 1
1328 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001329
Jeremy Hylton37c93512001-09-17 18:03:55 +00001330 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001331 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001332 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001333 if isLambda:
1334 klass = FunctionCodeGenerator
1335 name = "<lambda.%d>" % klass.lambdaCount
1336 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001337 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001338 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001339
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001340 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001341 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1342 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001343 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001344 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001345
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001346 if not isLambda and func.doc:
1347 self.setDocstring(func.doc)
1348
Jeremy Hylton2afff322001-08-27 21:51:52 +00001349 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001350 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001351 if func.varargs:
1352 self.graph.setFlag(CO_VARARGS)
1353 if func.kwargs:
1354 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001355 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001356 if hasTupleArg:
1357 self.generateArgUnpack(func.argnames)
1358
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001359 def get_module(self):
1360 return self.module
1361
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001362 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001363 self.graph.startExitBlock()
1364 if not self.isLambda:
1365 self.emit('LOAD_CONST', None)
1366 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001367
1368 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001369 for i in range(len(args)):
1370 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001371 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001372 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001373 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001374
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001375 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001376 if VERSION > 1:
1377 self.emit('UNPACK_SEQUENCE', len(tup))
1378 else:
1379 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001380 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001381 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001382 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001383 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001384 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001385
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001386 unpackTuple = unpackSequence
1387
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001388class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001389 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001390 super_init = CodeGenerator.__init__ # call be other init
1391 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001392
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001393 __super_init = AbstractFunctionCode.__init__
1394
Jeremy Hylton37c93512001-09-17 18:03:55 +00001395 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001396 self.scopes = scopes
1397 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001398 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001399 self.graph.setFreeVars(self.scope.get_free_vars())
1400 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001401 if self.scope.generator is not None:
1402 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001403
Raymond Hettinger354433a2004-05-19 08:20:33 +00001404class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1405 CodeGenerator):
1406 super_init = CodeGenerator.__init__ # call be other init
1407 scopes = None
1408
1409 __super_init = AbstractFunctionCode.__init__
1410
1411 def __init__(self, gexp, scopes, class_name, mod):
1412 self.scopes = scopes
1413 self.scope = scopes[gexp]
1414 self.__super_init(gexp, scopes, 1, class_name, mod)
1415 self.graph.setFreeVars(self.scope.get_free_vars())
1416 self.graph.setCellVars(self.scope.get_cell_vars())
1417 self.graph.setFlag(CO_GENERATOR)
1418
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001419class AbstractClassCode:
1420
Jeremy Hylton37c93512001-09-17 18:03:55 +00001421 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001422 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001423 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001424 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001425 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001426 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001427 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001428 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001429 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001430 if klass.doc:
1431 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001432
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001433 def get_module(self):
1434 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001435
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001436 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001437 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001438 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001439 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001440
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001441class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001442 super_init = CodeGenerator.__init__
1443 scopes = None
1444
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001445 __super_init = AbstractClassCode.__init__
1446
Jeremy Hylton37c93512001-09-17 18:03:55 +00001447 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001448 self.scopes = scopes
1449 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001450 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001451 self.graph.setFreeVars(self.scope.get_free_vars())
1452 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001453 self.set_lineno(klass)
1454 self.emit("LOAD_GLOBAL", "__name__")
1455 self.storeName("__module__")
1456 if klass.doc:
1457 self.emit("LOAD_CONST", klass.doc)
1458 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001459
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001460def generateArgList(arglist):
1461 """Generate an arg list marking TupleArgs"""
1462 args = []
1463 extra = []
1464 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001465 for i in range(len(arglist)):
1466 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001467 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001468 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001469 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001470 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001471 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001472 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001473 else:
1474 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001475 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001476
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001477def findOp(node):
1478 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1479 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001480 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001481 return v.op
1482
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001483class OpFinder:
1484 def __init__(self):
1485 self.op = None
1486 def visitAssName(self, node):
1487 if self.op is None:
1488 self.op = node.flags
1489 elif self.op != node.flags:
1490 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001491 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001492 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001493
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001494class Delegator:
1495 """Base class to support delegation for augmented assignment nodes
1496
1497 To generator code for augmented assignments, we use the following
1498 wrapper classes. In visitAugAssign, the left-hand expression node
1499 is visited twice. The first time the visit uses the normal method
1500 for that node . The second time the visit uses a different method
1501 that generates the appropriate code to perform the assignment.
1502 These delegator classes wrap the original AST nodes in order to
1503 support the variant visit methods.
1504 """
1505 def __init__(self, obj):
1506 self.obj = obj
1507
1508 def __getattr__(self, attr):
1509 return getattr(self.obj, attr)
1510
1511class AugGetattr(Delegator):
1512 pass
1513
1514class AugName(Delegator):
1515 pass
1516
1517class AugSlice(Delegator):
1518 pass
1519
1520class AugSubscript(Delegator):
1521 pass
1522
1523wrapper = {
1524 ast.Getattr: AugGetattr,
1525 ast.Name: AugName,
1526 ast.Slice: AugSlice,
1527 ast.Subscript: AugSubscript,
1528 }
1529
1530def wrap_aug(node):
1531 return wrapper[node.__class__](node)
1532
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001533if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001534 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001535 compileFile(file)