blob: cc24650cfd2bfbf2d16f6684271c4ec7c3aa3c0f [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)
Guido van Rossumd16e81a2007-03-19 17:56:01 +0000438 self.emit('LOAD_BUILD_CLASS')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000439 self._makeClosure(gen, 0)
Guido van Rossumd16e81a2007-03-19 17:56:01 +0000440 self.emit('LOAD_CONST', node.name)
441 self.finish_visit_call(node, 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000442 self.storeName(node.name)
443
444 # The rest are standard visitor methods
445
446 # The next few implement control-flow statements
447
448 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000449 end = self.newBlock()
450 numtests = len(node.tests)
451 for i in range(numtests):
452 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000453 if is_constant_false(test):
454 # XXX will need to check generator stuff here
455 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000456 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000458 nextTest = self.newBlock()
459 self.emit('JUMP_IF_FALSE', nextTest)
460 self.nextBlock()
461 self.emit('POP_TOP')
462 self.visit(suite)
463 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000464 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000465 self.emit('POP_TOP')
466 if node.else_:
467 self.visit(node.else_)
468 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000469
470 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000471 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000472
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000473 loop = self.newBlock()
474 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000476 after = self.newBlock()
477 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000479 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000480 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000482 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000483 self.visit(node.test)
484 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000485
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000486 self.nextBlock()
487 self.emit('POP_TOP')
488 self.visit(node.body)
489 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000490
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000491 self.startBlock(else_) # or just the POPs if not else clause
492 self.emit('POP_TOP')
493 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000494 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000495 if node.else_:
496 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000497 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000498
499 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000500 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000501 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000502 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000503 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000504
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000505 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000506 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000507 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000508 self.emit('GET_ITER')
509
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000510 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000511 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000512 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000513 self.visit(node.assign)
514 self.visit(node.body)
515 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000516 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000517 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000518 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000519 if node.else_:
520 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000521 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000522
523 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000524 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000525 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000526 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000527 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000528 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000529
530 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000531 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000533 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000534 kind, block = self.setups.top()
535 if kind == LOOP:
536 self.set_lineno(node)
537 self.emit('JUMP_ABSOLUTE', block)
538 self.nextBlock()
539 elif kind == EXCEPT or kind == TRY_FINALLY:
540 self.set_lineno(node)
541 # find the block that starts the loop
542 top = len(self.setups)
543 while top > 0:
544 top = top - 1
545 kind, loop_block = self.setups[top]
546 if kind == LOOP:
547 break
548 if kind != LOOP:
549 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000550 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000551 self.emit('CONTINUE_LOOP', loop_block)
552 self.nextBlock()
553 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000554 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000555 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000556
557 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000558 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000559 for child in node.nodes[:-1]:
560 self.visit(child)
561 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000562 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000563 self.emit('POP_TOP')
564 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000565 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000566
567 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000568 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000569
570 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000571 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000572
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000573 def visitIfExp(self, node):
574 endblock = self.newBlock()
575 elseblock = self.newBlock()
576 self.visit(node.test)
577 self.emit('JUMP_IF_FALSE', elseblock)
578 self.emit('POP_TOP')
579 self.visit(node.then)
580 self.emit('JUMP_FORWARD', endblock)
581 self.nextBlock(elseblock)
582 self.emit('POP_TOP')
583 self.visit(node.else_)
584 self.nextBlock(endblock)
585
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000586 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000587 self.visit(node.expr)
588 cleanup = self.newBlock()
589 for op, code in node.ops[:-1]:
590 self.visit(code)
591 self.emit('DUP_TOP')
592 self.emit('ROT_THREE')
593 self.emit('COMPARE_OP', op)
594 self.emit('JUMP_IF_FALSE', cleanup)
595 self.nextBlock()
596 self.emit('POP_TOP')
597 # now do the last comparison
598 if node.ops:
599 op, code = node.ops[-1]
600 self.visit(code)
601 self.emit('COMPARE_OP', op)
602 if len(node.ops) > 1:
603 end = self.newBlock()
604 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000605 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000606 self.emit('ROT_TWO')
607 self.emit('POP_TOP')
608 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000609
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610 # list comprehensions
611 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000612
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000613 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000614 self.set_lineno(node)
615 # setup list
Thomas Wouters89f507f2006-12-13 04:49:30 +0000616 tmpname = "$list%d" % self.__list_count
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.__list_count = self.__list_count + 1
618 self.emit('BUILD_LIST', 0)
619 self.emit('DUP_TOP')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000620 self._implicitNameOp('STORE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000621
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000622 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000623 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000624 start, anchor = self.visit(for_)
625 cont = None
626 for if_ in for_.ifs:
627 if cont is None:
628 cont = self.newBlock()
629 self.visit(if_, cont)
630 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000631
Thomas Wouters89f507f2006-12-13 04:49:30 +0000632 self._implicitNameOp('LOAD', tmpname)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000633 self.visit(node.expr)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000634 self.emit('LIST_APPEND')
Tim Peterse0c446b2001-10-18 21:57:37 +0000635
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000636 for start, cont, anchor in stack:
637 if cont:
638 skip_one = self.newBlock()
639 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000640 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000641 self.emit('POP_TOP')
642 self.nextBlock(skip_one)
643 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000644 self.startBlock(anchor)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000645 self._implicitNameOp('DELETE', tmpname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000646
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000647 self.__list_count = self.__list_count - 1
648
649 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000650 start = self.newBlock()
651 anchor = self.newBlock()
652
653 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000654 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000655 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000656 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000657 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000658 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000659 self.visit(node.assign)
660 return start, anchor
661
662 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000663 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000664 self.visit(node.test)
665 self.emit('JUMP_IF_FALSE', branch)
666 self.newBlock()
667 self.emit('POP_TOP')
668
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000669 def _makeClosure(self, gen, args):
670 frees = gen.scope.get_free_vars()
671 if frees:
672 for name in frees:
673 self.emit('LOAD_CLOSURE', name)
674 self.emit('BUILD_TUPLE', len(frees))
675 self.emit('LOAD_CONST', gen)
676 self.emit('MAKE_CLOSURE', args)
677 else:
678 self.emit('LOAD_CONST', gen)
679 self.emit('MAKE_FUNCTION', args)
680
Raymond Hettinger354433a2004-05-19 08:20:33 +0000681 def visitGenExpr(self, node):
682 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
683 self.get_module())
684 walk(node.code, gen)
685 gen.finish()
686 self.set_lineno(node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000687 self._makeClosure(gen, 0)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000688 # precomputation of outmost iterable
689 self.visit(node.code.quals[0].iter)
690 self.emit('GET_ITER')
691 self.emit('CALL_FUNCTION', 1)
692
693 def visitGenExprInner(self, node):
694 self.set_lineno(node)
695 # setup list
696
697 stack = []
698 for i, for_ in zip(range(len(node.quals)), node.quals):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000699 start, anchor, end = self.visit(for_)
Raymond Hettinger354433a2004-05-19 08:20:33 +0000700 cont = None
701 for if_ in for_.ifs:
702 if cont is None:
703 cont = self.newBlock()
704 self.visit(if_, cont)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000705 stack.insert(0, (start, cont, anchor, end))
Raymond Hettinger354433a2004-05-19 08:20:33 +0000706
707 self.visit(node.expr)
708 self.emit('YIELD_VALUE')
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000709 self.emit('POP_TOP')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000710
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000711 for start, cont, anchor, end in stack:
Raymond Hettinger354433a2004-05-19 08:20:33 +0000712 if cont:
713 skip_one = self.newBlock()
714 self.emit('JUMP_FORWARD', skip_one)
715 self.startBlock(cont)
716 self.emit('POP_TOP')
717 self.nextBlock(skip_one)
718 self.emit('JUMP_ABSOLUTE', start)
719 self.startBlock(anchor)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000720 self.emit('POP_BLOCK')
721 self.setups.pop()
722 self.startBlock(end)
723
Raymond Hettinger354433a2004-05-19 08:20:33 +0000724 self.emit('LOAD_CONST', None)
725
726 def visitGenExprFor(self, node):
727 start = self.newBlock()
728 anchor = self.newBlock()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000729 end = self.newBlock()
730
731 self.setups.push((LOOP, start))
732 self.emit('SETUP_LOOP', end)
Tim Peters4e0e1b62004-07-07 20:54:48 +0000733
Raymond Hettinger354433a2004-05-19 08:20:33 +0000734 if node.is_outmost:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000735 self.loadName('.0')
Raymond Hettinger354433a2004-05-19 08:20:33 +0000736 else:
737 self.visit(node.iter)
738 self.emit('GET_ITER')
739
740 self.nextBlock(start)
741 self.set_lineno(node, force=True)
742 self.emit('FOR_ITER', anchor)
743 self.nextBlock()
744 self.visit(node.assign)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000745 return start, anchor, end
Raymond Hettinger354433a2004-05-19 08:20:33 +0000746
747 def visitGenExprIf(self, node, branch):
748 self.set_lineno(node, force=True)
749 self.visit(node.test)
750 self.emit('JUMP_IF_FALSE', branch)
751 self.newBlock()
752 self.emit('POP_TOP')
753
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000754 # exception related
755
756 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000757 # XXX would be interesting to implement this via a
758 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000759 if __debug__:
760 end = self.newBlock()
761 self.set_lineno(node)
762 # XXX AssertionError appears to be special case -- it is always
763 # loaded as a global even if there is a local name. I guess this
764 # is a sort of renaming op.
765 self.nextBlock()
766 self.visit(node.test)
767 self.emit('JUMP_IF_TRUE', end)
768 self.nextBlock()
769 self.emit('POP_TOP')
770 self.emit('LOAD_GLOBAL', 'AssertionError')
771 if node.fail:
772 self.visit(node.fail)
773 self.emit('RAISE_VARARGS', 2)
774 else:
775 self.emit('RAISE_VARARGS', 1)
776 self.nextBlock(end)
777 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000778
779 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000780 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000781 n = 0
782 if node.expr1:
783 self.visit(node.expr1)
784 n = n + 1
785 if node.expr2:
786 self.visit(node.expr2)
787 n = n + 1
788 if node.expr3:
789 self.visit(node.expr3)
790 n = n + 1
791 self.emit('RAISE_VARARGS', n)
792
793 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000794 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000795 handlers = self.newBlock()
796 end = self.newBlock()
797 if node.else_:
798 lElse = self.newBlock()
799 else:
800 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000801 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000802 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000803 self.nextBlock(body)
804 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000805 self.visit(node.body)
806 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000807 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000808 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000809 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000810
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000811 last = len(node.handlers) - 1
812 for i in range(len(node.handlers)):
813 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000814 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000815 if expr:
816 self.emit('DUP_TOP')
817 self.visit(expr)
818 self.emit('COMPARE_OP', 'exception match')
819 next = self.newBlock()
820 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000821 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000822 self.emit('POP_TOP')
823 self.emit('POP_TOP')
824 if target:
Guido van Rossum16be03e2007-01-10 18:51:35 +0000825 cleanup_body = self.newBlock()
826 cleanup_final = self.newBlock()
827 target_name = target[1]
828
829 self.storeName(target_name)
830 self.emit('POP_TOP')
831 self.emit('SETUP_FINALLY', cleanup_final)
832 self.nextBlock(cleanup_body)
833 self.setups.push((TRY_FINALLY, cleanup_body))
834 self.visit(body)
835 self.emit('POP_BLOCK')
836 self.setups.pop()
837 self.emit('LOAD_CONST', None)
838 self.nextBlock(cleanup_final)
839 self.setups.push((END_FINALLY, cleanup_final))
840
841
842 self.emit('LOAD_CONST', None)
843 self.storeName(target_name)
844 self._implicitNameOp('DELETE', target_name)
845
846 self.emit('END_FINALLY')
847 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000848 else:
849 self.emit('POP_TOP')
Guido van Rossum16be03e2007-01-10 18:51:35 +0000850 self.emit('POP_TOP')
851 self.visit(body)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000852 self.emit('JUMP_FORWARD', end)
853 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000854 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000855 else:
856 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000857 if expr: # XXX
858 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000859 self.emit('END_FINALLY')
860 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000861 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000862 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000863 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000864
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000865 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000866 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000867 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000868 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000869 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000870 self.nextBlock(body)
871 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000872 self.visit(node.body)
873 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000874 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000875 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000876 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000877 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000878 self.visit(node.final)
879 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000880 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000881
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000882 __with_count = 0
883
884 def visitWith(self, node):
885 body = self.newBlock()
886 final = self.newBlock()
887 exitvar = "$exit%d" % self.__with_count
888 valuevar = "$value%d" % self.__with_count
889 self.__with_count += 1
890 self.set_lineno(node)
891 self.visit(node.expr)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000892 self.emit('DUP_TOP')
893 self.emit('LOAD_ATTR', '__exit__')
894 self._implicitNameOp('STORE', exitvar)
895 self.emit('LOAD_ATTR', '__enter__')
896 self.emit('CALL_FUNCTION', 0)
897 if node.vars is None:
898 self.emit('POP_TOP')
899 else:
900 self._implicitNameOp('STORE', valuevar)
901 self.emit('SETUP_FINALLY', final)
902 self.nextBlock(body)
903 self.setups.push((TRY_FINALLY, body))
904 if node.vars is not None:
905 self._implicitNameOp('LOAD', valuevar)
906 self._implicitNameOp('DELETE', valuevar)
907 self.visit(node.vars)
908 self.visit(node.body)
909 self.emit('POP_BLOCK')
910 self.setups.pop()
911 self.emit('LOAD_CONST', None)
912 self.nextBlock(final)
913 self.setups.push((END_FINALLY, final))
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000914 self._implicitNameOp('LOAD', exitvar)
915 self._implicitNameOp('DELETE', exitvar)
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000916 self.emit('WITH_CLEANUP')
Guido van Rossum7ad94f02006-02-28 00:32:16 +0000917 self.emit('END_FINALLY')
918 self.setups.pop()
919 self.__with_count -= 1
920
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000921 # misc
922
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000923 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000924 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000925 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000926 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000927
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000928 def visitConst(self, node):
929 self.emit('LOAD_CONST', node.value)
Thomas Wouters00e41de2007-02-23 19:56:57 +0000930
931 def visitBytes(self, node):
932 self.emit('LOAD_CONST', node.value)
933 self.emit('MAKE_BYTES')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000934
935 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000936 self.emit('LOAD_CONST', node.name)
937 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000938
939 def visitGlobal(self, node):
940 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000941 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000942
943 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000944 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000945 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000946
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000947 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000948 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000949
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000950 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000951 self.set_lineno(node)
Neal Norwitzd4e30352006-03-03 20:21:48 +0000952 level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000953 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000954 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000955 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000956 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000957 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000958 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000959 if alias:
960 self._resolveDots(name)
961 self.storeName(alias)
962 else:
963 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000964
965 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000966 self.set_lineno(node)
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000967 level = node.level
Neal Norwitzd4e30352006-03-03 20:21:48 +0000968 if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000969 level = -1
Jeremy Hylton20516082000-09-01 20:33:26 +0000970 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000971 if VERSION > 1:
Thomas Woutersfa0cf4f2006-03-03 18:16:20 +0000972 self.emit('LOAD_CONST', level)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000973 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000974 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000975 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000976 if VERSION > 1:
977 if name == '*':
978 self.namespace = 0
979 self.emit('IMPORT_STAR')
980 # There can only be one name w/ from ... import *
981 assert len(node.names) == 1
982 return
983 else:
984 self.emit('IMPORT_FROM', name)
985 self._resolveDots(name)
986 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000987 else:
988 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000989 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000990
Jeremy Hylton20516082000-09-01 20:33:26 +0000991 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000992 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000993 if len(elts) == 1:
994 return
995 for elt in elts[1:]:
996 self.emit('LOAD_ATTR', elt)
997
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000998 def visitGetattr(self, node):
999 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001000 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001001
1002 # next five implement assignments
1003
1004 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001005 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001006 self.visit(node.expr)
1007 dups = len(node.nodes) - 1
1008 for i in range(len(node.nodes)):
1009 elt = node.nodes[i]
1010 if i < dups:
1011 self.emit('DUP_TOP')
1012 if isinstance(elt, ast.Node):
1013 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001014
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001015 def visitAssName(self, node):
1016 if node.flags == 'OP_ASSIGN':
1017 self.storeName(node.name)
1018 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +00001019 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001020 self.delName(node.name)
1021 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001022 print("oops", node.flags)
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001023
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001024 def visitAssAttr(self, node):
1025 self.visit(node.expr)
1026 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001027 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001028 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001029 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001030 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001031 print("warning: unexpected flags:", node.flags)
1032 print(node)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001033
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001034 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001035 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001036 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001037 for child in node.nodes:
1038 self.visit(child)
1039
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001040 if VERSION > 1:
1041 visitAssTuple = _visitAssSequence
1042 visitAssList = _visitAssSequence
1043 else:
1044 def visitAssTuple(self, node):
1045 self._visitAssSequence(node, 'UNPACK_TUPLE')
1046
1047 def visitAssList(self, node):
1048 self._visitAssSequence(node, 'UNPACK_LIST')
1049
1050 # augmented assignment
1051
1052 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +00001053 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001054 aug_node = wrap_aug(node.node)
1055 self.visit(aug_node, "load")
1056 self.visit(node.expr)
1057 self.emit(self._augmented_opcode[node.op])
1058 self.visit(aug_node, "store")
1059
1060 _augmented_opcode = {
1061 '+=' : 'INPLACE_ADD',
1062 '-=' : 'INPLACE_SUBTRACT',
1063 '*=' : 'INPLACE_MULTIPLY',
Neal Norwitze7086d42006-03-17 08:59:09 +00001064 '/=' : 'INPLACE_TRUE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +00001065 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001066 '%=' : 'INPLACE_MODULO',
1067 '**=': 'INPLACE_POWER',
1068 '>>=': 'INPLACE_RSHIFT',
1069 '<<=': 'INPLACE_LSHIFT',
1070 '&=' : 'INPLACE_AND',
1071 '^=' : 'INPLACE_XOR',
1072 '|=' : 'INPLACE_OR',
1073 }
1074
1075 def visitAugName(self, node, mode):
1076 if mode == "load":
1077 self.loadName(node.name)
1078 elif mode == "store":
1079 self.storeName(node.name)
1080
1081 def visitAugGetattr(self, node, mode):
1082 if mode == "load":
1083 self.visit(node.expr)
1084 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001085 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001086 elif mode == "store":
1087 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001088 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001089
1090 def visitAugSlice(self, node, mode):
1091 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001092 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001093 elif mode == "store":
1094 slice = 0
1095 if node.lower:
1096 slice = slice | 1
1097 if node.upper:
1098 slice = slice | 2
1099 if slice == 0:
1100 self.emit('ROT_TWO')
1101 elif slice == 3:
1102 self.emit('ROT_FOUR')
1103 else:
1104 self.emit('ROT_THREE')
1105 self.emit('STORE_SLICE+%d' % slice)
1106
1107 def visitAugSubscript(self, node, mode):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001108 if mode == "load":
1109 self.visitSubscript(node, 1)
1110 elif mode == "store":
1111 self.emit('ROT_THREE')
1112 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001113
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001114 def visitCallFunc(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001115 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001116 self.visit(node.node)
Guido van Rossumd16e81a2007-03-19 17:56:01 +00001117 self.finish_visit_call(node)
1118
1119 def finish_visit_call(self, node, pos=0, kw=0):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001120 for arg in node.args:
1121 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001122 if isinstance(arg, ast.Keyword):
1123 kw = kw + 1
1124 else:
1125 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001126 if node.star_args is not None:
1127 self.visit(node.star_args)
1128 if node.dstar_args is not None:
1129 self.visit(node.dstar_args)
1130 have_star = node.star_args is not None
1131 have_dstar = node.dstar_args is not None
1132 opcode = callfunc_opcode_info[have_star, have_dstar]
1133 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001134
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001135 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001136 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001137 self.visit(node.value)
1138 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001139
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001140 def visitYield(self, node):
1141 self.set_lineno(node)
1142 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001143 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001144
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001145 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001146
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001147 def visitSlice(self, node, aug_flag=None):
1148 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001149 self.visit(node.expr)
1150 slice = 0
1151 if node.lower:
1152 self.visit(node.lower)
1153 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001154 if node.upper:
1155 self.visit(node.upper)
1156 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001157 if aug_flag:
1158 if slice == 0:
1159 self.emit('DUP_TOP')
1160 elif slice == 3:
1161 self.emit('DUP_TOPX', 3)
1162 else:
1163 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001164 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001165 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001166 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001167 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001168 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001169 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001170 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001171 print("weird slice", node.flags)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001172 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001173
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001174 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001175 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001176 for sub in node.subs:
1177 self.visit(sub)
1178 if len(node.subs) > 1:
1179 self.emit('BUILD_TUPLE', len(node.subs))
Nick Coghlancb35b952006-03-14 13:21:14 +00001180 if aug_flag:
1181 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001182 if node.flags == 'OP_APPLY':
1183 self.emit('BINARY_SUBSCR')
1184 elif node.flags == 'OP_ASSIGN':
1185 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001186 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001187 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001188
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001189 # binary ops
1190
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001191 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001192 self.visit(node.left)
1193 self.visit(node.right)
1194 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001195
1196 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001197 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001198
1199 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001200 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001201
1202 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001203 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001204
1205 def visitDiv(self, node):
Neal Norwitzc6d210c2006-03-16 06:02:10 +00001206 return self.binaryOp(node, 'BINARY_TRUE_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001207
Jeremy Hylton94afe322001-08-29 18:14:39 +00001208 def visitFloorDiv(self, node):
1209 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1210
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001211 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001212 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001213
Jeremy Hylton126960b2000-02-14 21:33:10 +00001214 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001215 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001216
1217 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001218 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001219
1220 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001221 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001222
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001223 # unary ops
1224
1225 def unaryOp(self, node, op):
1226 self.visit(node.expr)
1227 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001228
Jeremy Hylton126960b2000-02-14 21:33:10 +00001229 def visitInvert(self, node):
1230 return self.unaryOp(node, 'UNARY_INVERT')
1231
Jeremy Hylton40245602000-02-08 21:15:48 +00001232 def visitUnarySub(self, node):
1233 return self.unaryOp(node, 'UNARY_NEGATIVE')
1234
1235 def visitUnaryAdd(self, node):
1236 return self.unaryOp(node, 'UNARY_POSITIVE')
1237
1238 def visitUnaryInvert(self, node):
1239 return self.unaryOp(node, 'UNARY_INVERT')
1240
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001241 def visitNot(self, node):
1242 return self.unaryOp(node, 'UNARY_NOT')
1243
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001244 # bit ops
1245
Jeremy Hyltona5058122000-02-14 14:14:29 +00001246 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001247 self.visit(nodes[0])
1248 for node in nodes[1:]:
1249 self.visit(node)
1250 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001251
1252 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001253 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001254
1255 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001256 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001257
1258 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001259 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001260
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001261 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001262
1263 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001264 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001265 for elt in node.nodes:
1266 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001267 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001268
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001269 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001270 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001271 for elt in node.nodes:
1272 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001273 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001274
Guido van Rossum86e58e22006-08-28 15:27:34 +00001275 def visitSet(self, node):
1276 self.set_lineno(node)
1277 for elt in node.items:
1278 self.visit(elt)
1279 self.emit('BUILD_SET', len(node.items))
1280
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001281 def visitSliceobj(self, node):
1282 for child in node.nodes:
1283 self.visit(child)
1284 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001285
Jeremy Hyltona5058122000-02-14 14:14:29 +00001286 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001287 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001288 self.emit('BUILD_MAP', 0)
1289 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001290 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001291 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001292 self.visit(v)
1293 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001294 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001295
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001296class NestedScopeMixin:
1297 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001298 def initClass(self):
1299 self.__class__.NameFinder = LocalNameFinder
1300 self.__class__.FunctionGen = FunctionCodeGenerator
1301 self.__class__.ClassGen = ClassCodeGenerator
1302
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001303class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001304 __super_init = CodeGenerator.__init__
1305
1306 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001307
Jeremy Hylton37c93512001-09-17 18:03:55 +00001308 def __init__(self, tree):
1309 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001310 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001311 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001312 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001313
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001314 def get_module(self):
1315 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001316
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001317class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1318 __super_init = CodeGenerator.__init__
1319
1320 scopes = None
1321 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001322
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001323 def __init__(self, tree):
1324 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1325 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001326 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001327
1328 def get_module(self):
1329 return self
1330
1331class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1332
1333 __super_init = CodeGenerator.__init__
1334
1335 scopes = None
1336 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001337
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001338 def __init__(self, tree):
1339 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1340 self.__super_init()
1341 self.set_lineno(tree)
1342 walk(tree, self)
1343 self.emit('RETURN_VALUE')
1344
1345 def get_module(self):
1346 return self
Tim Peterse4418602002-02-16 07:34:19 +00001347
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001348 def visitDiscard(self, node):
1349 # XXX Discard means it's an expression. Perhaps this is a bad
1350 # name.
1351 self.visit(node.expr)
1352 self.emit('PRINT_EXPR')
1353
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001354class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001355 optimized = 1
1356 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001357
Jeremy Hylton37c93512001-09-17 18:03:55 +00001358 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001359 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001360 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001361 if isLambda:
1362 klass = FunctionCodeGenerator
1363 name = "<lambda.%d>" % klass.lambdaCount
1364 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001365 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001366 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001367
Neal Norwitzc1505362006-12-28 06:47:50 +00001368 args, hasTupleArg = generateArgList(func.arguments)
Guido van Rossum4f72a782006-10-27 23:31:49 +00001369 kwonlyargs = generateKwonlyArgList(func.kwonlyargs)
Tim Peterse0c446b2001-10-18 21:57:37 +00001370 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
Guido van Rossum4f72a782006-10-27 23:31:49 +00001371 kwonlyargs=kwonlyargs,
Tim Peterse0c446b2001-10-18 21:57:37 +00001372 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001373 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001374 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001375
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001376 if not isLambda and func.doc:
1377 self.setDocstring(func.doc)
1378
Neal Norwitzc1505362006-12-28 06:47:50 +00001379 lnf = walk(func.code, self.NameFinder(args+kwonlyargs), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001380 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001381 if func.varargs:
1382 self.graph.setFlag(CO_VARARGS)
1383 if func.kwargs:
1384 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001385 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001386 if hasTupleArg:
Neal Norwitzc1505362006-12-28 06:47:50 +00001387 self.generateArgUnpack(func.arguments)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001388
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001389 def get_module(self):
1390 return self.module
1391
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001392 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001393 self.graph.startExitBlock()
1394 if not self.isLambda:
1395 self.emit('LOAD_CONST', None)
1396 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001397
1398 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001399 for i in range(len(args)):
1400 arg = args[i]
Neal Norwitzc1505362006-12-28 06:47:50 +00001401 if isinstance(arg, ast.NestedArgs):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001402 self.emit('LOAD_FAST', '.%d' % (i * 2))
Neal Norwitzc1505362006-12-28 06:47:50 +00001403 self.unpackSequence(tuple(_nested_names(arg)))
Tim Peterse0c446b2001-10-18 21:57:37 +00001404
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001405 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001406 if VERSION > 1:
1407 self.emit('UNPACK_SEQUENCE', len(tup))
1408 else:
1409 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001410 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001411 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001412 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001413 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001414 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001415
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001416 unpackTuple = unpackSequence
1417
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001418class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001419 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001420 super_init = CodeGenerator.__init__ # call be other init
1421 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001422
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001423 __super_init = AbstractFunctionCode.__init__
1424
Jeremy Hylton37c93512001-09-17 18:03:55 +00001425 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001426 self.scopes = scopes
1427 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001428 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001429 self.graph.setFreeVars(self.scope.get_free_vars())
1430 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001431 if self.scope.generator is not None:
1432 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001433
Raymond Hettinger354433a2004-05-19 08:20:33 +00001434class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1435 CodeGenerator):
1436 super_init = CodeGenerator.__init__ # call be other init
1437 scopes = None
1438
1439 __super_init = AbstractFunctionCode.__init__
1440
1441 def __init__(self, gexp, scopes, class_name, mod):
1442 self.scopes = scopes
1443 self.scope = scopes[gexp]
1444 self.__super_init(gexp, scopes, 1, class_name, mod)
1445 self.graph.setFreeVars(self.scope.get_free_vars())
1446 self.graph.setCellVars(self.scope.get_cell_vars())
1447 self.graph.setFlag(CO_GENERATOR)
1448
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001449class AbstractClassCode:
1450
Jeremy Hylton37c93512001-09-17 18:03:55 +00001451 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001452 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001453 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001454 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001455 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001456 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001457 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001458 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001459 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001460 if klass.doc:
1461 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001462
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001463 def get_module(self):
1464 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001465
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001466 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001467 self.graph.startExitBlock()
Guido van Rossumd16e81a2007-03-19 17:56:01 +00001468 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001469 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001470
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001471class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001472 super_init = CodeGenerator.__init__
1473 scopes = None
1474
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001475 __super_init = AbstractClassCode.__init__
1476
Jeremy Hylton37c93512001-09-17 18:03:55 +00001477 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001478 self.scopes = scopes
1479 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001480 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001481 self.graph.setFreeVars(self.scope.get_free_vars())
1482 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001483 self.set_lineno(klass)
1484 self.emit("LOAD_GLOBAL", "__name__")
1485 self.storeName("__module__")
1486 if klass.doc:
1487 self.emit("LOAD_CONST", klass.doc)
1488 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001489
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001490def generateArgList(arglist):
1491 """Generate an arg list marking TupleArgs"""
1492 args = []
1493 extra = []
1494 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001495 for i in range(len(arglist)):
1496 elt = arglist[i]
Neal Norwitzc1505362006-12-28 06:47:50 +00001497 if isinstance(elt, ast.SimpleArg):
1498 args.append(elt.name)
1499 elif isinstance(elt, ast.NestedArgs):
1500 t = tuple(_nested_names(elt))
1501 args.append(TupleArg(i * 2, t))
1502 extra.extend(misc.flatten(t))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001503 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001504 else:
1505 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001506 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001507
Neal Norwitzc1505362006-12-28 06:47:50 +00001508def _nested_names(elt):
1509 for arg in elt.args:
1510 if isinstance(arg, ast.SimpleArg):
1511 yield arg.name
1512 elif isinstance(arg, ast.NestedArgs):
1513 yield tuple(_nested_names(arg))
1514
Guido van Rossum4f72a782006-10-27 23:31:49 +00001515def generateKwonlyArgList(keywordOnlyArgs):
Neal Norwitzc1505362006-12-28 06:47:50 +00001516 kwonlyargs = []
Guido van Rossum4f72a782006-10-27 23:31:49 +00001517 for elt in keywordOnlyArgs:
Neal Norwitzc1505362006-12-28 06:47:50 +00001518 assert isinstance(elt, ast.Kwarg)
1519 kwonlyargs.append(elt.arg.name)
Guido van Rossum4f72a782006-10-27 23:31:49 +00001520 return kwonlyargs
1521
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001522def findOp(node):
1523 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1524 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001525 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001526 return v.op
1527
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001528class OpFinder:
1529 def __init__(self):
1530 self.op = None
1531 def visitAssName(self, node):
1532 if self.op is None:
1533 self.op = node.flags
1534 elif self.op != node.flags:
1535 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001536 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001537 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001538
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001539class Delegator:
1540 """Base class to support delegation for augmented assignment nodes
1541
1542 To generator code for augmented assignments, we use the following
1543 wrapper classes. In visitAugAssign, the left-hand expression node
1544 is visited twice. The first time the visit uses the normal method
1545 for that node . The second time the visit uses a different method
1546 that generates the appropriate code to perform the assignment.
1547 These delegator classes wrap the original AST nodes in order to
1548 support the variant visit methods.
1549 """
1550 def __init__(self, obj):
1551 self.obj = obj
1552
1553 def __getattr__(self, attr):
1554 return getattr(self.obj, attr)
1555
1556class AugGetattr(Delegator):
1557 pass
1558
1559class AugName(Delegator):
1560 pass
1561
1562class AugSlice(Delegator):
1563 pass
1564
1565class AugSubscript(Delegator):
1566 pass
1567
1568wrapper = {
1569 ast.Getattr: AugGetattr,
1570 ast.Name: AugName,
1571 ast.Slice: AugSlice,
1572 ast.Subscript: AugSubscript,
1573 }
1574
1575def wrap_aug(node):
1576 return wrapper[node.__class__](node)
1577
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001578if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001579 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001580 compileFile(file)