blob: 0e497817a3137ac88f75651d8119197172ca6ae9 [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
Guido van Rossumbe19ed72007-02-09 05:37:30 +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')
Guido van Rossumb940e112007-01-10 16:19:56 +0000230 except AssertionError as msg:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000231 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)
Neal Norwitzc1505362006-12-28 06:47:50 +0000381 num_kwargs = 0
Guido van Rossum4f72a782006-10-27 23:31:49 +0000382 for keyword in node.kwonlyargs:
383 default = keyword.expr
384 if isinstance(default, ast.EmptyNode):
385 continue
Neal Norwitzc1505362006-12-28 06:47:50 +0000386 self.emit('LOAD_CONST', keyword.arg.name)
Guido van Rossum4f72a782006-10-27 23:31:49 +0000387 self.visit(default)
Neal Norwitzc1505362006-12-28 06:47:50 +0000388 num_kwargs += 1
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000389 for default in node.defaults:
390 self.visit(default)
Neal Norwitzc1505362006-12-28 06:47:50 +0000391
392 num_annotations = self._visit_annotations(node)
393
394 oparg = len(node.defaults)
395 oparg |= num_kwargs << 8
396 oparg |= num_annotations << 16
397
398 self._makeClosure(gen, oparg)
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000399 for i in range(ndecorators):
400 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000401
Neal Norwitzc1505362006-12-28 06:47:50 +0000402 def _visit_annotations(self, node):
403 # emit code, return num_annotations
404 annotations = []
405 annotations.extend(self._visit_argument_annotations(node.arguments))
406 annotations.extend(self._visit_kwarg_annotations(node.kwonlyargs))
407 if node.returns:
408 self.visit(node.returns)
409 annotations.append('return')
410 if not annotations:
411 return 0
412 self.emit('LOAD_CONST', tuple(annotations))
413 return len(annotations) + 1
414
415 def _visit_argument_annotations(self, arguments):
416 for arg in arguments:
417 if isinstance(arg, ast.SimpleArg):
418 if arg.annotation:
419 self.visit(arg.annotation)
420 yield arg.name
421 else:
422 for name in self._visit_argument_annotations(arg.args):
423 yield name
424
425 def _visit_kwarg_annotations(self, kwargs):
426 for kwarg in kwargs:
427 arg = kwarg.arg
428 if arg.annotation:
429 self.visit(arg.annotation)
430 yield arg.name
431
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000432 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000433 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000434 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000435 walk(node.code, gen)
436 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000437 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000438 self.emit('LOAD_CONST', node.name)
439 for base in node.bases:
440 self.visit(base)
441 self.emit('BUILD_TUPLE', len(node.bases))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000442 self._makeClosure(gen, 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443 self.emit('CALL_FUNCTION', 0)
444 self.emit('BUILD_CLASS')
445 self.storeName(node.name)
446
447 # The rest are standard visitor methods
448
449 # The next few implement control-flow statements
450
451 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000452 end = self.newBlock()
453 numtests = len(node.tests)
454 for i in range(numtests):
455 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000456 if is_constant_false(test):
457 # XXX will need to check generator stuff here
458 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000459 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000461 nextTest = self.newBlock()
462 self.emit('JUMP_IF_FALSE', nextTest)
463 self.nextBlock()
464 self.emit('POP_TOP')
465 self.visit(suite)
466 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000467 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000468 self.emit('POP_TOP')
469 if node.else_:
470 self.visit(node.else_)
471 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000472
473 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000474 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000476 loop = self.newBlock()
477 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000479 after = self.newBlock()
480 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000482 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000483 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000484
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000485 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000486 self.visit(node.test)
487 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000488
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000489 self.nextBlock()
490 self.emit('POP_TOP')
491 self.visit(node.body)
492 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000493
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000494 self.startBlock(else_) # or just the POPs if not else clause
495 self.emit('POP_TOP')
496 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000497 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000498 if node.else_:
499 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000500 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000501
502 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000503 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000504 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000505 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000506 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000507
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000508 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000509 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000510 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000511 self.emit('GET_ITER')
512
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000513 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000514 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000515 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000516 self.visit(node.assign)
517 self.visit(node.body)
518 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000519 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000520 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000521 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000522 if node.else_:
523 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000524 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000525
526 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000527 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000528 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000529 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000530 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000531 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532
533 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000534 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000535 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000536 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000537 kind, block = self.setups.top()
538 if kind == LOOP:
539 self.set_lineno(node)
540 self.emit('JUMP_ABSOLUTE', block)
541 self.nextBlock()
542 elif kind == EXCEPT or kind == TRY_FINALLY:
543 self.set_lineno(node)
544 # find the block that starts the loop
545 top = len(self.setups)
546 while top > 0:
547 top = top - 1
548 kind, loop_block = self.setups[top]
549 if kind == LOOP:
550 break
551 if kind != LOOP:
552 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000553 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000554 self.emit('CONTINUE_LOOP', loop_block)
555 self.nextBlock()
556 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000557 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000558 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000559
560 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000561 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000562 for child in node.nodes[:-1]:
563 self.visit(child)
564 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000565 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000566 self.emit('POP_TOP')
567 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000568 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000569
570 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000571 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000572
573 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000574 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000575
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000576 def visitIfExp(self, node):
577 endblock = self.newBlock()
578 elseblock = self.newBlock()
579 self.visit(node.test)
580 self.emit('JUMP_IF_FALSE', elseblock)
581 self.emit('POP_TOP')
582 self.visit(node.then)
583 self.emit('JUMP_FORWARD', endblock)
584 self.nextBlock(elseblock)
585 self.emit('POP_TOP')
586 self.visit(node.else_)
587 self.nextBlock(endblock)
588
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000589 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000590 self.visit(node.expr)
591 cleanup = self.newBlock()
592 for op, code in node.ops[:-1]:
593 self.visit(code)
594 self.emit('DUP_TOP')
595 self.emit('ROT_THREE')
596 self.emit('COMPARE_OP', op)
597 self.emit('JUMP_IF_FALSE', cleanup)
598 self.nextBlock()
599 self.emit('POP_TOP')
600 # now do the last comparison
601 if node.ops:
602 op, code = node.ops[-1]
603 self.visit(code)
604 self.emit('COMPARE_OP', op)
605 if len(node.ops) > 1:
606 end = self.newBlock()
607 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000608 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000609 self.emit('ROT_TWO')
610 self.emit('POP_TOP')
611 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000612
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000613 # list comprehensions
614 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000615
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000616 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.set_lineno(node)
618 # setup list
Thomas Wouters89f507f2006-12-13 04:49:30 +0000619 tmpname = "$list%d" % self.__list_count
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000620 self.__list_count = self.__list_count + 1
621 self.emit('BUILD_LIST', 0)
622 self.emit('DUP_TOP')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000623 self._implicitNameOp('STORE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000624
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000625 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000626 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000627 start, anchor = self.visit(for_)
628 cont = None
629 for if_ in for_.ifs:
630 if cont is None:
631 cont = self.newBlock()
632 self.visit(if_, cont)
633 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000634
Thomas Wouters89f507f2006-12-13 04:49:30 +0000635 self._implicitNameOp('LOAD', tmpname)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000636 self.visit(node.expr)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000637 self.emit('LIST_APPEND')
Tim Peterse0c446b2001-10-18 21:57:37 +0000638
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000639 for start, cont, anchor in stack:
640 if cont:
641 skip_one = self.newBlock()
642 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000643 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000644 self.emit('POP_TOP')
645 self.nextBlock(skip_one)
646 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000647 self.startBlock(anchor)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000648 self._implicitNameOp('DELETE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000649
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000650 self.__list_count = self.__list_count - 1
651
652 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000653 start = self.newBlock()
654 anchor = self.newBlock()
655
656 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000657 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000658 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000659 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000660 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000661 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000662 self.visit(node.assign)
663 return start, anchor
664
665 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000666 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000667 self.visit(node.test)
668 self.emit('JUMP_IF_FALSE', branch)
669 self.newBlock()
670 self.emit('POP_TOP')
671
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000672 def _makeClosure(self, gen, args):
673 frees = gen.scope.get_free_vars()
674 if frees:
675 for name in frees:
676 self.emit('LOAD_CLOSURE', name)
677 self.emit('BUILD_TUPLE', len(frees))
678 self.emit('LOAD_CONST', gen)
679 self.emit('MAKE_CLOSURE', args)
680 else:
681 self.emit('LOAD_CONST', gen)
682 self.emit('MAKE_FUNCTION', args)
683
Raymond Hettinger354433a2004-05-19 08:20:33 +0000684 def visitGenExpr(self, node):
685 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
686 self.get_module())
687 walk(node.code, gen)
688 gen.finish()
689 self.set_lineno(node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000690 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000691 # precomputation of outmost iterable
692 self.visit(node.code.quals[0].iter)
693 self.emit('GET_ITER')
694 self.emit('CALL_FUNCTION', 1)
695
696 def visitGenExprInner(self, node):
697 self.set_lineno(node)
698 # setup list
699
700 stack = []
701 for i, for_ in zip(range(len(node.quals)), node.quals):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000702 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000703 cont = None
704 for if_ in for_.ifs:
705 if cont is None:
706 cont = self.newBlock()
707 self.visit(if_, cont)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000708 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000709
710 self.visit(node.expr)
711 self.emit('YIELD_VALUE')
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000712 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000713
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000714 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000715 if cont:
716 skip_one = self.newBlock()
717 self.emit('JUMP_FORWARD', skip_one)
718 self.startBlock(cont)
719 self.emit('POP_TOP')
720 self.nextBlock(skip_one)
721 self.emit('JUMP_ABSOLUTE', start)
722 self.startBlock(anchor)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000723 self.emit('POP_BLOCK')
724 self.setups.pop()
725 self.startBlock(end)
726
Raymond Hettinger354433a2004-05-19 08:20:33 +0000727 self.emit('LOAD_CONST', None)
728
729 def visitGenExprFor(self, node):
730 start = self.newBlock()
731 anchor = self.newBlock()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000732 end = self.newBlock()
733
734 self.setups.push((LOOP, start))
735 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000736
Raymond Hettinger354433a2004-05-19 08:20:33 +0000737 if node.is_outmost:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000738 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000739 else:
740 self.visit(node.iter)
741 self.emit('GET_ITER')
742
743 self.nextBlock(start)
744 self.set_lineno(node, force=True)
745 self.emit('FOR_ITER', anchor)
746 self.nextBlock()
747 self.visit(node.assign)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000748 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000749
750 def visitGenExprIf(self, node, branch):
751 self.set_lineno(node, force=True)
752 self.visit(node.test)
753 self.emit('JUMP_IF_FALSE', branch)
754 self.newBlock()
755 self.emit('POP_TOP')
756
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000757 # exception related
758
759 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000760 # XXX would be interesting to implement this via a
761 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000762 if __debug__:
763 end = self.newBlock()
764 self.set_lineno(node)
765 # XXX AssertionError appears to be special case -- it is always
766 # loaded as a global even if there is a local name. I guess this
767 # is a sort of renaming op.
768 self.nextBlock()
769 self.visit(node.test)
770 self.emit('JUMP_IF_TRUE', end)
771 self.nextBlock()
772 self.emit('POP_TOP')
773 self.emit('LOAD_GLOBAL', 'AssertionError')
774 if node.fail:
775 self.visit(node.fail)
776 self.emit('RAISE_VARARGS', 2)
777 else:
778 self.emit('RAISE_VARARGS', 1)
779 self.nextBlock(end)
780 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000781
782 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000783 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000784 n = 0
785 if node.expr1:
786 self.visit(node.expr1)
787 n = n + 1
788 if node.expr2:
789 self.visit(node.expr2)
790 n = n + 1
791 if node.expr3:
792 self.visit(node.expr3)
793 n = n + 1
794 self.emit('RAISE_VARARGS', n)
795
796 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000797 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000798 handlers = self.newBlock()
799 end = self.newBlock()
800 if node.else_:
801 lElse = self.newBlock()
802 else:
803 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000804 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000806 self.nextBlock(body)
807 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000808 self.visit(node.body)
809 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000810 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000812 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000813
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000814 last = len(node.handlers) - 1
815 for i in range(len(node.handlers)):
816 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000817 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000818 if expr:
819 self.emit('DUP_TOP')
820 self.visit(expr)
821 self.emit('COMPARE_OP', 'exception match')
822 next = self.newBlock()
823 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000824 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000825 self.emit('POP_TOP')
826 self.emit('POP_TOP')
827 if target:
Guido van Rossum16be03e2007-01-10 18:51:35 +0000828 cleanup_body = self.newBlock()
829 cleanup_final = self.newBlock()
830 target_name = target[1]
831
832 self.storeName(target_name)
833 self.emit('POP_TOP')
834 self.emit('SETUP_FINALLY', cleanup_final)
835 self.nextBlock(cleanup_body)
836 self.setups.push((TRY_FINALLY, cleanup_body))
837 self.visit(body)
838 self.emit('POP_BLOCK')
839 self.setups.pop()
840 self.emit('LOAD_CONST', None)
841 self.nextBlock(cleanup_final)
842 self.setups.push((END_FINALLY, cleanup_final))
843
844
845 self.emit('LOAD_CONST', None)
846 self.storeName(target_name)
847 self._implicitNameOp('DELETE', target_name)
848
849 self.emit('END_FINALLY')
850 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000851 else:
852 self.emit('POP_TOP')
Guido van Rossum16be03e2007-01-10 18:51:35 +0000853 self.emit('POP_TOP')
854 self.visit(body)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000855 self.emit('JUMP_FORWARD', end)
856 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000857 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000858 else:
859 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000860 if expr: # XXX
861 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000862 self.emit('END_FINALLY')
863 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000864 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000865 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000866 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000867
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000868 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000869 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000870 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000871 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000872 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000873 self.nextBlock(body)
874 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000875 self.visit(node.body)
876 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000877 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000878 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000879 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000880 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000881 self.visit(node.final)
882 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000883 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000884
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000885 __with_count = 0
886
887 def visitWith(self, node):
888 body = self.newBlock()
889 final = self.newBlock()
890 exitvar = "$exit%d" % self.__with_count
891 valuevar = "$value%d" % self.__with_count
892 self.__with_count += 1
893 self.set_lineno(node)
894 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000895 self.emit('DUP_TOP')
896 self.emit('LOAD_ATTR', '__exit__')
897 self._implicitNameOp('STORE', exitvar)
898 self.emit('LOAD_ATTR', '__enter__')
899 self.emit('CALL_FUNCTION', 0)
900 if node.vars is None:
901 self.emit('POP_TOP')
902 else:
903 self._implicitNameOp('STORE', valuevar)
904 self.emit('SETUP_FINALLY', final)
905 self.nextBlock(body)
906 self.setups.push((TRY_FINALLY, body))
907 if node.vars is not None:
908 self._implicitNameOp('LOAD', valuevar)
909 self._implicitNameOp('DELETE', valuevar)
910 self.visit(node.vars)
911 self.visit(node.body)
912 self.emit('POP_BLOCK')
913 self.setups.pop()
914 self.emit('LOAD_CONST', None)
915 self.nextBlock(final)
916 self.setups.push((END_FINALLY, final))
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000917 self._implicitNameOp('LOAD', exitvar)
918 self._implicitNameOp('DELETE', exitvar)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000919 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000920 self.emit('END_FINALLY')
921 self.setups.pop()
922 self.__with_count -= 1
923
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000924 # misc
925
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000926 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000927 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000928 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000929 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000930
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000931 def visitConst(self, node):
932 self.emit('LOAD_CONST', node.value)
933
934 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000935 self.emit('LOAD_CONST', node.name)
936 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000937
938 def visitGlobal(self, node):
939 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000940 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000941
942 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000943 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000944 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000945
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000946 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000947 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000948
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000949 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000950 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000951 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000952 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000953 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000954 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000955 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000956 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000957 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000958 if alias:
959 self._resolveDots(name)
960 self.storeName(alias)
961 else:
962 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000963
964 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000965 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000966 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000967 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000968 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000969 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000970 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000971 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000972 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000973 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000974 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000975 if VERSION > 1:
976 if name == '*':
977 self.namespace = 0
978 self.emit('IMPORT_STAR')
979 # There can only be one name w/ from ... import *
980 assert len(node.names) == 1
981 return
982 else:
983 self.emit('IMPORT_FROM', name)
984 self._resolveDots(name)
985 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000986 else:
987 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000988 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000989
Jeremy Hylton20516082000-09-01 20:33:26 +0000990 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000991 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000992 if len(elts) == 1:
993 return
994 for elt in elts[1:]:
995 self.emit('LOAD_ATTR', elt)
996
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000997 def visitGetattr(self, node):
998 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000999 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001000
1001 # next five implement assignments
1002
1003 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001004 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001005 self.visit(node.expr)
1006 dups = len(node.nodes) - 1
1007 for i in range(len(node.nodes)):
1008 elt = node.nodes[i]
1009 if i < dups:
1010 self.emit('DUP_TOP')
1011 if isinstance(elt, ast.Node):
1012 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001013
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001014 def visitAssName(self, node):
1015 if node.flags == 'OP_ASSIGN':
1016 self.storeName(node.name)
1017 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +00001018 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001019 self.delName(node.name)
1020 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001021 print("oops", node.flags)
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001022
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001023 def visitAssAttr(self, node):
1024 self.visit(node.expr)
1025 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001026 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001027 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001028 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001029 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001030 print("warning: unexpected flags:", node.flags)
1031 print(node)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001032
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001033 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001034 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001035 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001036 for child in node.nodes:
1037 self.visit(child)
1038
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001039 if VERSION > 1:
1040 visitAssTuple = _visitAssSequence
1041 visitAssList = _visitAssSequence
1042 else:
1043 def visitAssTuple(self, node):
1044 self._visitAssSequence(node, 'UNPACK_TUPLE')
1045
1046 def visitAssList(self, node):
1047 self._visitAssSequence(node, 'UNPACK_LIST')
1048
1049 # augmented assignment
1050
1051 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +00001052 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001053 aug_node = wrap_aug(node.node)
1054 self.visit(aug_node, "load")
1055 self.visit(node.expr)
1056 self.emit(self._augmented_opcode[node.op])
1057 self.visit(aug_node, "store")
1058
1059 _augmented_opcode = {
1060 '+=' : 'INPLACE_ADD',
1061 '-=' : 'INPLACE_SUBTRACT',
1062 '*=' : 'INPLACE_MULTIPLY',
Neal Norwitze7086d42006-03-17 08:59:09 +00001063 '/=' : 'INPLACE_TRUE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001064 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001065 '%=' : 'INPLACE_MODULO',
1066 '**=': 'INPLACE_POWER',
1067 '>>=': 'INPLACE_RSHIFT',
1068 '<<=': 'INPLACE_LSHIFT',
1069 '&=' : 'INPLACE_AND',
1070 '^=' : 'INPLACE_XOR',
1071 '|=' : 'INPLACE_OR',
1072 }
1073
1074 def visitAugName(self, node, mode):
1075 if mode == "load":
1076 self.loadName(node.name)
1077 elif mode == "store":
1078 self.storeName(node.name)
1079
1080 def visitAugGetattr(self, node, mode):
1081 if mode == "load":
1082 self.visit(node.expr)
1083 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001084 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001085 elif mode == "store":
1086 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001087 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001088
1089 def visitAugSlice(self, node, mode):
1090 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001091 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001092 elif mode == "store":
1093 slice = 0
1094 if node.lower:
1095 slice = slice | 1
1096 if node.upper:
1097 slice = slice | 2
1098 if slice == 0:
1099 self.emit('ROT_TWO')
1100 elif slice == 3:
1101 self.emit('ROT_FOUR')
1102 else:
1103 self.emit('ROT_THREE')
1104 self.emit('STORE_SLICE+%d' % slice)
1105
1106 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001107 if mode == "load":
1108 self.visitSubscript(node, 1)
1109 elif mode == "store":
1110 self.emit('ROT_THREE')
1111 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001112
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001113 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001114 pos = 0
1115 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001116 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001117 self.visit(node.node)
1118 for arg in node.args:
1119 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001120 if isinstance(arg, ast.Keyword):
1121 kw = kw + 1
1122 else:
1123 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001124 if node.star_args is not None:
1125 self.visit(node.star_args)
1126 if node.dstar_args is not None:
1127 self.visit(node.dstar_args)
1128 have_star = node.star_args is not None
1129 have_dstar = node.dstar_args is not None
1130 opcode = callfunc_opcode_info[have_star, have_dstar]
1131 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001132
Jeremy Hylton2afff322001-08-27 21:51:52 +00001133 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001134 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001135 if node.dest:
1136 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001137 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001138 if node.dest:
1139 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001140 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001141 if node.dest:
1142 self.emit('ROT_TWO')
1143 self.emit('PRINT_ITEM_TO')
1144 else:
1145 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001146 if node.dest and not newline:
1147 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001148
1149 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001150 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001151 if node.dest:
1152 self.emit('PRINT_NEWLINE_TO')
1153 else:
1154 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001155
1156 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001157 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001158 self.visit(node.value)
1159 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001160
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001161 def visitYield(self, node):
1162 self.set_lineno(node)
1163 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001164 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001165
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001166 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001167
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001168 def visitSlice(self, node, aug_flag=None):
1169 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001170 self.visit(node.expr)
1171 slice = 0
1172 if node.lower:
1173 self.visit(node.lower)
1174 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001175 if node.upper:
1176 self.visit(node.upper)
1177 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001178 if aug_flag:
1179 if slice == 0:
1180 self.emit('DUP_TOP')
1181 elif slice == 3:
1182 self.emit('DUP_TOPX', 3)
1183 else:
1184 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001185 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001186 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001187 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001188 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001189 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001190 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001191 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001192 print("weird slice", node.flags)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001193 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001194
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001195 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001196 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001197 for sub in node.subs:
1198 self.visit(sub)
1199 if len(node.subs) > 1:
1200 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001201 if aug_flag:
1202 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001203 if node.flags == 'OP_APPLY':
1204 self.emit('BINARY_SUBSCR')
1205 elif node.flags == 'OP_ASSIGN':
1206 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001207 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001208 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001209
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001210 # binary ops
1211
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001212 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001213 self.visit(node.left)
1214 self.visit(node.right)
1215 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001216
1217 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001218 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001219
1220 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001221 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001222
1223 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001224 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001225
1226 def visitDiv(self, node):
Neal Norwitzc6d210c2006-03-16 06:02:10 +00001227 return self.binaryOp(node, 'BINARY_TRUE_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001228
Jeremy Hylton94afe322001-08-29 18:14:39 +00001229 def visitFloorDiv(self, node):
1230 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1231
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001232 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001233 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001234
Jeremy Hylton126960b2000-02-14 21:33:10 +00001235 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001236 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001237
1238 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001239 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001240
1241 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001242 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001243
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001244 # unary ops
1245
1246 def unaryOp(self, node, op):
1247 self.visit(node.expr)
1248 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001249
Jeremy Hylton126960b2000-02-14 21:33:10 +00001250 def visitInvert(self, node):
1251 return self.unaryOp(node, 'UNARY_INVERT')
1252
Jeremy Hylton40245602000-02-08 21:15:48 +00001253 def visitUnarySub(self, node):
1254 return self.unaryOp(node, 'UNARY_NEGATIVE')
1255
1256 def visitUnaryAdd(self, node):
1257 return self.unaryOp(node, 'UNARY_POSITIVE')
1258
1259 def visitUnaryInvert(self, node):
1260 return self.unaryOp(node, 'UNARY_INVERT')
1261
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001262 def visitNot(self, node):
1263 return self.unaryOp(node, 'UNARY_NOT')
1264
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001265 # bit ops
1266
Jeremy Hyltona5058122000-02-14 14:14:29 +00001267 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001268 self.visit(nodes[0])
1269 for node in nodes[1:]:
1270 self.visit(node)
1271 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001272
1273 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001274 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001275
1276 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001277 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001278
1279 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001280 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001281
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001282 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001283
1284 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001285 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001286 for elt in node.nodes:
1287 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001288 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001289
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001290 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001291 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001292 for elt in node.nodes:
1293 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001294 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001295
Guido van Rossum86e58e22006-08-28 15:27:34 +00001296 def visitSet(self, node):
1297 self.set_lineno(node)
1298 for elt in node.items:
1299 self.visit(elt)
1300 self.emit('BUILD_SET', len(node.items))
1301
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001302 def visitSliceobj(self, node):
1303 for child in node.nodes:
1304 self.visit(child)
1305 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001306
Jeremy Hyltona5058122000-02-14 14:14:29 +00001307 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001308 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001309 self.emit('BUILD_MAP', 0)
1310 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001311 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001312 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001313 self.visit(v)
1314 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001315 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001316
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001317class NestedScopeMixin:
1318 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001319 def initClass(self):
1320 self.__class__.NameFinder = LocalNameFinder
1321 self.__class__.FunctionGen = FunctionCodeGenerator
1322 self.__class__.ClassGen = ClassCodeGenerator
1323
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001324class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001325 __super_init = CodeGenerator.__init__
1326
1327 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001328
Jeremy Hylton37c93512001-09-17 18:03:55 +00001329 def __init__(self, tree):
1330 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001331 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001332 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001333 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001334
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001335 def get_module(self):
1336 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001337
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001338class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1339 __super_init = CodeGenerator.__init__
1340
1341 scopes = None
1342 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001343
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001344 def __init__(self, tree):
1345 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1346 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001347 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001348
1349 def get_module(self):
1350 return self
1351
1352class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1353
1354 __super_init = CodeGenerator.__init__
1355
1356 scopes = None
1357 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001358
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001359 def __init__(self, tree):
1360 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1361 self.__super_init()
1362 self.set_lineno(tree)
1363 walk(tree, self)
1364 self.emit('RETURN_VALUE')
1365
1366 def get_module(self):
1367 return self
Tim Peterse4418602002-02-16 07:34:19 +00001368
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001369 def visitDiscard(self, node):
1370 # XXX Discard means it's an expression. Perhaps this is a bad
1371 # name.
1372 self.visit(node.expr)
1373 self.emit('PRINT_EXPR')
1374
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001375class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001376 optimized = 1
1377 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001378
Jeremy Hylton37c93512001-09-17 18:03:55 +00001379 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001380 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001381 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001382 if isLambda:
1383 klass = FunctionCodeGenerator
1384 name = "<lambda.%d>" % klass.lambdaCount
1385 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001386 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001387 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001388
Neal Norwitzc1505362006-12-28 06:47:50 +00001389 args, hasTupleArg = generateArgList(func.arguments)
Guido van Rossum4f72a782006-10-27 23:31:49 +00001390 kwonlyargs = generateKwonlyArgList(func.kwonlyargs)
Tim Peterse0c446b2001-10-18 21:57:37 +00001391 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
Guido van Rossum4f72a782006-10-27 23:31:49 +00001392 kwonlyargs=kwonlyargs,
Tim Peterse0c446b2001-10-18 21:57:37 +00001393 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001394 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001395 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001396
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001397 if not isLambda and func.doc:
1398 self.setDocstring(func.doc)
1399
Neal Norwitzc1505362006-12-28 06:47:50 +00001400 lnf = walk(func.code, self.NameFinder(args+kwonlyargs), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001401 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001402 if func.varargs:
1403 self.graph.setFlag(CO_VARARGS)
1404 if func.kwargs:
1405 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001406 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001407 if hasTupleArg:
Neal Norwitzc1505362006-12-28 06:47:50 +00001408 self.generateArgUnpack(func.arguments)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001409
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001410 def get_module(self):
1411 return self.module
1412
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001413 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001414 self.graph.startExitBlock()
1415 if not self.isLambda:
1416 self.emit('LOAD_CONST', None)
1417 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001418
1419 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001420 for i in range(len(args)):
1421 arg = args[i]
Neal Norwitzc1505362006-12-28 06:47:50 +00001422 if isinstance(arg, ast.NestedArgs):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001423 self.emit('LOAD_FAST', '.%d' % (i * 2))
Neal Norwitzc1505362006-12-28 06:47:50 +00001424 self.unpackSequence(tuple(_nested_names(arg)))
Tim Peterse0c446b2001-10-18 21:57:37 +00001425
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001426 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001427 if VERSION > 1:
1428 self.emit('UNPACK_SEQUENCE', len(tup))
1429 else:
1430 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001431 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001432 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001433 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001434 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001435 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001436
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001437 unpackTuple = unpackSequence
1438
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001439class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001440 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001441 super_init = CodeGenerator.__init__ # call be other init
1442 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001443
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001444 __super_init = AbstractFunctionCode.__init__
1445
Jeremy Hylton37c93512001-09-17 18:03:55 +00001446 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001447 self.scopes = scopes
1448 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001449 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001450 self.graph.setFreeVars(self.scope.get_free_vars())
1451 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001452 if self.scope.generator is not None:
1453 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001454
Raymond Hettinger354433a2004-05-19 08:20:33 +00001455class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1456 CodeGenerator):
1457 super_init = CodeGenerator.__init__ # call be other init
1458 scopes = None
1459
1460 __super_init = AbstractFunctionCode.__init__
1461
1462 def __init__(self, gexp, scopes, class_name, mod):
1463 self.scopes = scopes
1464 self.scope = scopes[gexp]
1465 self.__super_init(gexp, scopes, 1, class_name, mod)
1466 self.graph.setFreeVars(self.scope.get_free_vars())
1467 self.graph.setCellVars(self.scope.get_cell_vars())
1468 self.graph.setFlag(CO_GENERATOR)
1469
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001470class AbstractClassCode:
1471
Jeremy Hylton37c93512001-09-17 18:03:55 +00001472 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001473 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001474 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001475 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001476 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001477 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001478 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001479 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001480 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001481 if klass.doc:
1482 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001483
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001484 def get_module(self):
1485 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001486
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001487 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001488 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001489 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001490 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001491
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001492class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001493 super_init = CodeGenerator.__init__
1494 scopes = None
1495
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001496 __super_init = AbstractClassCode.__init__
1497
Jeremy Hylton37c93512001-09-17 18:03:55 +00001498 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001499 self.scopes = scopes
1500 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001501 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001502 self.graph.setFreeVars(self.scope.get_free_vars())
1503 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001504 self.set_lineno(klass)
1505 self.emit("LOAD_GLOBAL", "__name__")
1506 self.storeName("__module__")
1507 if klass.doc:
1508 self.emit("LOAD_CONST", klass.doc)
1509 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001510
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001511def generateArgList(arglist):
1512 """Generate an arg list marking TupleArgs"""
1513 args = []
1514 extra = []
1515 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001516 for i in range(len(arglist)):
1517 elt = arglist[i]
Neal Norwitzc1505362006-12-28 06:47:50 +00001518 if isinstance(elt, ast.SimpleArg):
1519 args.append(elt.name)
1520 elif isinstance(elt, ast.NestedArgs):
1521 t = tuple(_nested_names(elt))
1522 args.append(TupleArg(i * 2, t))
1523 extra.extend(misc.flatten(t))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001524 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001525 else:
1526 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001527 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001528
Neal Norwitzc1505362006-12-28 06:47:50 +00001529def _nested_names(elt):
1530 for arg in elt.args:
1531 if isinstance(arg, ast.SimpleArg):
1532 yield arg.name
1533 elif isinstance(arg, ast.NestedArgs):
1534 yield tuple(_nested_names(arg))
1535
Guido van Rossum4f72a782006-10-27 23:31:49 +00001536def generateKwonlyArgList(keywordOnlyArgs):
Neal Norwitzc1505362006-12-28 06:47:50 +00001537 kwonlyargs = []
Guido van Rossum4f72a782006-10-27 23:31:49 +00001538 for elt in keywordOnlyArgs:
Neal Norwitzc1505362006-12-28 06:47:50 +00001539 assert isinstance(elt, ast.Kwarg)
1540 kwonlyargs.append(elt.arg.name)
Guido van Rossum4f72a782006-10-27 23:31:49 +00001541 return kwonlyargs
1542
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001543def findOp(node):
1544 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1545 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001546 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001547 return v.op
1548
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001549class OpFinder:
1550 def __init__(self):
1551 self.op = None
1552 def visitAssName(self, node):
1553 if self.op is None:
1554 self.op = node.flags
1555 elif self.op != node.flags:
1556 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001557 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001558 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001559
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001560class Delegator:
1561 """Base class to support delegation for augmented assignment nodes
1562
1563 To generator code for augmented assignments, we use the following
1564 wrapper classes. In visitAugAssign, the left-hand expression node
1565 is visited twice. The first time the visit uses the normal method
1566 for that node . The second time the visit uses a different method
1567 that generates the appropriate code to perform the assignment.
1568 These delegator classes wrap the original AST nodes in order to
1569 support the variant visit methods.
1570 """
1571 def __init__(self, obj):
1572 self.obj = obj
1573
1574 def __getattr__(self, attr):
1575 return getattr(self.obj, attr)
1576
1577class AugGetattr(Delegator):
1578 pass
1579
1580class AugName(Delegator):
1581 pass
1582
1583class AugSlice(Delegator):
1584 pass
1585
1586class AugSubscript(Delegator):
1587 pass
1588
1589wrapper = {
1590 ast.Getattr: AugGetattr,
1591 ast.Name: AugName,
1592 ast.Slice: AugSlice,
1593 ast.Subscript: AugSubscript,
1594 }
1595
1596def wrap_aug(node):
1597 return wrapper[node.__class__](node)
1598
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001599if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001600 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001601 compileFile(file)