blob: 4866e0e8cb6bf69764cdf3280a0ef2a0100346bc [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
Jeremy Hylton71ebc332001-08-30 20:25:55 +000011from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
Jeremy Hylton1e99a772001-09-14 22:49:08 +000012 CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
Jeremy Hylton71ebc332001-08-30 20:25:55 +000013from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000014
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000015# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000016# Do we have Python 1.x or Python 2.x?
17try:
18 VERSION = sys.version_info[0]
19except AttributeError:
20 VERSION = 1
21
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000022callfunc_opcode_info = {
23 # (Have *args, Have **args) : opcode
24 (0,0) : "CALL_FUNCTION",
25 (1,0) : "CALL_FUNCTION_VAR",
26 (0,1) : "CALL_FUNCTION_KW",
27 (1,1) : "CALL_FUNCTION_VAR_KW",
28}
29
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000030LOOP = 1
31EXCEPT = 2
32TRY_FINALLY = 3
33END_FINALLY = 4
34
Jeremy Hylton9dca3642001-09-17 21:02:51 +000035def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000036 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000037 buf = f.read()
38 f.close()
39 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000040 try:
41 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000042 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000043 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000044 else:
45 f = open(filename + "c", "wb")
46 mod.dump(f)
47 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000048
Jeremy Hylton9dca3642001-09-17 21:02:51 +000049def compile(source, filename, mode, flags=None, dont_inherit=None):
50 """Replacement for builtin compile() function"""
51 if flags is not None or dont_inherit is not None:
52 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000053
Jeremy Hylton9dca3642001-09-17 21:02:51 +000054 if mode == "single":
55 gen = Interactive(source, filename)
56 elif mode == "exec":
57 gen = Module(source, filename)
58 elif mode == "eval":
59 gen = Expression(source, filename)
60 else:
61 raise ValueError("compile() 3rd arg must be 'exec' or "
62 "'eval' or 'single'")
63 gen.compile()
64 return gen.code
65
66class AbstractCompileMode:
67
68 mode = None # defined by subclass
69
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000070 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000071 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000072 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000073 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000074
Jeremy Hylton9dca3642001-09-17 21:02:51 +000075 def _get_tree(self):
76 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000077 misc.set_filename(self.filename, tree)
78 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000079 return tree
80
81 def compile(self):
82 pass # implemented by subclass
83
84 def getCode(self):
85 return self.code
86
87class Expression(AbstractCompileMode):
88
89 mode = "eval"
90
91 def compile(self):
92 tree = self._get_tree()
93 gen = ExpressionCodeGenerator(tree)
94 self.code = gen.getCode()
95
96class Interactive(AbstractCompileMode):
97
98 mode = "single"
99
100 def compile(self):
101 tree = self._get_tree()
102 gen = InteractiveCodeGenerator(tree)
103 self.code = gen.getCode()
104
105class Module(AbstractCompileMode):
106
107 mode = "exec"
108
109 def compile(self, display=0):
110 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000111 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000112 if display:
113 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000114 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000115 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000116
117 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000118 f.write(self.getPycHeader())
119 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000120
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000121 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000122
123 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000124 # compile.c uses marshal to write a long directly, with
125 # calling the interface that would also generate a 1-byte code
126 # to indicate the type of the value. simplest way to get the
127 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000128 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000129 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000130 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000131
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000132class LocalNameFinder:
133 """Find local names in scope"""
134 def __init__(self, names=()):
135 self.names = misc.Set()
136 self.globals = misc.Set()
137 for name in names:
138 self.names.add(name)
139
140 # XXX list comprehensions and for loops
141
142 def getLocals(self):
143 for elt in self.globals.elements():
144 if self.names.has_elt(elt):
145 self.names.remove(elt)
146 return self.names
147
148 def visitDict(self, node):
149 pass
150
151 def visitGlobal(self, node):
152 for name in node.names:
153 self.globals.add(name)
154
155 def visitFunction(self, node):
156 self.names.add(node.name)
157
158 def visitLambda(self, node):
159 pass
160
161 def visitImport(self, node):
162 for name, alias in node.names:
163 self.names.add(alias or name)
164
165 def visitFrom(self, node):
166 for name, alias in node.names:
167 self.names.add(alias or name)
168
169 def visitClass(self, node):
170 self.names.add(node.name)
171
172 def visitAssName(self, node):
173 self.names.add(node.name)
174
Jeremy Hylton2afff322001-08-27 21:51:52 +0000175def is_constant_false(node):
176 if isinstance(node, ast.Const):
177 if not node.value:
178 return 1
179 return 0
180
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000181class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000182 """Defines basic code generator for Python bytecode
183
184 This class is an abstract base class. Concrete subclasses must
185 define an __init__() that defines self.graph and then calls the
186 __init__() defined in this class.
187
188 The concrete class must also define the class attributes
189 NameFinder, FunctionGen, and ClassGen. These attributes can be
190 defined in the initClass() method, which is a hook for
191 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000192 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000193 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000194
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000195 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000196 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000197 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000198
Jeremy Hylton37c93512001-09-17 18:03:55 +0000199 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000200 if self.__initialized is None:
201 self.initClass()
202 self.__class__.__initialized = 1
203 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000204 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000205 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000206 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000207 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000208 self._div_op = "BINARY_DIVIDE"
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)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000215 self._div_op = "BINARY_TRUE_DIVIDE"
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000216 elif feature == "generators":
217 self.graph.setFlag(CO_GENERATOR_ALLOWED)
218
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000219 def initClass(self):
220 """This method is called once for each class"""
221
222 def checkClass(self):
223 """Verify that class is constructed correctly"""
224 try:
225 assert hasattr(self, 'graph')
226 assert getattr(self, 'NameFinder')
227 assert getattr(self, 'FunctionGen')
228 assert getattr(self, 'ClassGen')
229 except AssertionError, msg:
230 intro = "Bad class construction for %s" % self.__class__.__name__
231 raise AssertionError, intro
232
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000233 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000234 self.emit = self.graph.emit
235 self.newBlock = self.graph.newBlock
236 self.startBlock = self.graph.startBlock
237 self.nextBlock = self.graph.nextBlock
238 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000239
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000240 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000241 """Return a code object"""
242 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000243
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000244 def mangle(self, name):
245 if self.class_name is not None:
246 return misc.mangle(name, self.class_name)
247 else:
248 return name
249
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000250 def parseSymbols(self, tree):
251 s = symbols.SymbolVisitor()
252 walk(tree, s)
253 return s.scopes
254
255 def get_module(self):
256 raise RuntimeError, "should be implemented by subclasses"
257
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000258 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000259
Jeremy Hylton40245602000-02-08 21:15:48 +0000260 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000261 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000262
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000263 def storeName(self, name):
264 self._nameOp('STORE', name)
265
266 def loadName(self, name):
267 self._nameOp('LOAD', name)
268
269 def delName(self, name):
270 self._nameOp('DELETE', name)
271
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000272 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000273 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000274 scope = self.scope.check_name(name)
275 if scope == SC_LOCAL:
276 if not self.optimized:
277 self.emit(prefix + '_NAME', name)
278 else:
279 self.emit(prefix + '_FAST', name)
280 elif scope == SC_GLOBAL:
281 if not self.optimized:
282 self.emit(prefix + '_NAME', name)
283 else:
284 self.emit(prefix + '_GLOBAL', name)
285 elif scope == SC_FREE or scope == SC_CELL:
286 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000287 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000288 raise RuntimeError, "unsupported scope for var %s: %d" % \
289 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000290
Jeremy Hylton13d70942001-04-12 21:04:43 +0000291 def _implicitNameOp(self, prefix, name):
292 """Emit name ops for names generated implicitly by for loops
293
294 The interpreter generates names that start with a period or
295 dollar sign. The symbol table ignores these names because
296 they aren't present in the program text.
297 """
298 if self.optimized:
299 self.emit(prefix + '_FAST', name)
300 else:
301 self.emit(prefix + '_NAME', name)
302
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000303 # The set_lineno() function and the explicit emit() calls for
304 # SET_LINENO below are only used to generate the line number table.
305 # As of Python 2.3, the interpreter does not have a SET_LINENO
306 # instruction. pyassem treats SET_LINENO opcodes as a special case.
307
308 def set_lineno(self, node, force=False):
309 """Emit SET_LINENO if necessary.
310
311 The instruction is considered necessary if the node has a
312 lineno attribute and it is different than the last lineno
313 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000314
315 Returns true if SET_LINENO was emitted.
316
317 There are no rules for when an AST node should have a lineno
318 attribute. The transformer and AST code need to be reviewed
319 and a consistent policy implemented and documented. Until
320 then, this method works around missing line numbers.
321 """
322 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000323 if lineno is not None and (lineno != self.last_lineno
324 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000325 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000326 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000327 return True
328 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000329
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000330 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000331 # code objects. They use class attributes to determine what
332 # specialized code generators to use.
333
334 NameFinder = LocalNameFinder
335 FunctionGen = None
336 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000337
338 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000339 self.scopes = self.parseSymbols(node)
340 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000341 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000342 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000343 self.emit('LOAD_CONST', node.doc)
344 self.storeName('__doc__')
345 lnf = walk(node.node, self.NameFinder(), verbose=0)
346 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000347 self.visit(node.node)
348 self.emit('LOAD_CONST', None)
349 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000350
Barry Warsaw52acb492001-12-21 20:04:22 +0000351 def visitExpression(self, node):
352 self.set_lineno(node)
353 self.scopes = self.parseSymbols(node)
354 self.scope = self.scopes[node]
355 self.visit(node.node)
356 self.emit('RETURN_VALUE')
357
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000358 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000359 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000360 if node.doc:
361 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000362 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000363
364 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000365 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000366
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000367 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000368 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000369 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000370 self.visit(decorator)
371 ndecorators = len(node.decorators.nodes)
372 else:
373 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000374
Jeremy Hylton37c93512001-09-17 18:03:55 +0000375 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000376 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000377 walk(node.code, gen)
378 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000379 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000380 for default in node.defaults:
381 self.visit(default)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000382 frees = gen.scope.get_free_vars()
383 if frees:
384 for name in frees:
385 self.emit('LOAD_CLOSURE', name)
386 self.emit('LOAD_CONST', gen)
387 self.emit('MAKE_CLOSURE', len(node.defaults))
388 else:
389 self.emit('LOAD_CONST', gen)
390 self.emit('MAKE_FUNCTION', len(node.defaults))
Tim Peters6db15d72004-08-04 02:36:18 +0000391
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000392 for i in range(ndecorators):
393 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000394
395 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000396 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000397 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000398 walk(node.code, gen)
399 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000400 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000401 self.emit('LOAD_CONST', node.name)
402 for base in node.bases:
403 self.visit(base)
404 self.emit('BUILD_TUPLE', len(node.bases))
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000405 frees = gen.scope.get_free_vars()
406 for name in frees:
407 self.emit('LOAD_CLOSURE', name)
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000408 self.emit('LOAD_CONST', gen)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000409 if frees:
410 self.emit('MAKE_CLOSURE', 0)
411 else:
412 self.emit('MAKE_FUNCTION', 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000413 self.emit('CALL_FUNCTION', 0)
414 self.emit('BUILD_CLASS')
415 self.storeName(node.name)
416
417 # The rest are standard visitor methods
418
419 # The next few implement control-flow statements
420
421 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000422 end = self.newBlock()
423 numtests = len(node.tests)
424 for i in range(numtests):
425 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000426 if is_constant_false(test):
427 # XXX will need to check generator stuff here
428 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000429 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000430 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000431 nextTest = self.newBlock()
432 self.emit('JUMP_IF_FALSE', nextTest)
433 self.nextBlock()
434 self.emit('POP_TOP')
435 self.visit(suite)
436 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000437 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000438 self.emit('POP_TOP')
439 if node.else_:
440 self.visit(node.else_)
441 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000442
443 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000444 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000445
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000446 loop = self.newBlock()
447 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000448
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000449 after = self.newBlock()
450 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000451
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000452 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000453 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000454
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000455 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000456 self.visit(node.test)
457 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000458
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000459 self.nextBlock()
460 self.emit('POP_TOP')
461 self.visit(node.body)
462 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000463
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000464 self.startBlock(else_) # or just the POPs if not else clause
465 self.emit('POP_TOP')
466 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000467 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000468 if node.else_:
469 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000470 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000471
472 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000473 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000474 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000475 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000476 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000477
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000478 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000479 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000480 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000481 self.emit('GET_ITER')
482
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000483 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000484 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000485 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000486 self.visit(node.assign)
487 self.visit(node.body)
488 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000489 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000490 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000491 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000492 if node.else_:
493 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000494 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000495
496 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000497 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000498 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000499 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000500 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000501 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000502
503 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000504 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000505 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000506 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000507 kind, block = self.setups.top()
508 if kind == LOOP:
509 self.set_lineno(node)
510 self.emit('JUMP_ABSOLUTE', block)
511 self.nextBlock()
512 elif kind == EXCEPT or kind == TRY_FINALLY:
513 self.set_lineno(node)
514 # find the block that starts the loop
515 top = len(self.setups)
516 while top > 0:
517 top = top - 1
518 kind, loop_block = self.setups[top]
519 if kind == LOOP:
520 break
521 if kind != LOOP:
522 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000523 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000524 self.emit('CONTINUE_LOOP', loop_block)
525 self.nextBlock()
526 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000527 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000528 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000529
530 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000531 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000532 for child in node.nodes[:-1]:
533 self.visit(child)
534 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000535 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000536 self.emit('POP_TOP')
537 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000538 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000539
540 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000541 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000542
543 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000544 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000545
546 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000547 self.visit(node.expr)
548 cleanup = self.newBlock()
549 for op, code in node.ops[:-1]:
550 self.visit(code)
551 self.emit('DUP_TOP')
552 self.emit('ROT_THREE')
553 self.emit('COMPARE_OP', op)
554 self.emit('JUMP_IF_FALSE', cleanup)
555 self.nextBlock()
556 self.emit('POP_TOP')
557 # now do the last comparison
558 if node.ops:
559 op, code = node.ops[-1]
560 self.visit(code)
561 self.emit('COMPARE_OP', op)
562 if len(node.ops) > 1:
563 end = self.newBlock()
564 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000565 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000566 self.emit('ROT_TWO')
567 self.emit('POP_TOP')
568 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000569
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000570 # list comprehensions
571 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000572
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000573 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000574 self.set_lineno(node)
575 # setup list
576 append = "$append%d" % self.__list_count
577 self.__list_count = self.__list_count + 1
578 self.emit('BUILD_LIST', 0)
579 self.emit('DUP_TOP')
580 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000581 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000582
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000583 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000584 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000585 start, anchor = self.visit(for_)
586 cont = None
587 for if_ in for_.ifs:
588 if cont is None:
589 cont = self.newBlock()
590 self.visit(if_, cont)
591 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000592
Jeremy Hylton13d70942001-04-12 21:04:43 +0000593 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000594 self.visit(node.expr)
595 self.emit('CALL_FUNCTION', 1)
596 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000597
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000598 for start, cont, anchor in stack:
599 if cont:
600 skip_one = self.newBlock()
601 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000602 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000603 self.emit('POP_TOP')
604 self.nextBlock(skip_one)
605 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000606 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000607 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000608
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000609 self.__list_count = self.__list_count - 1
610
611 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000612 start = self.newBlock()
613 anchor = self.newBlock()
614
615 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000616 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000618 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000619 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000620 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000621 self.visit(node.assign)
622 return start, anchor
623
624 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000625 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000626 self.visit(node.test)
627 self.emit('JUMP_IF_FALSE', branch)
628 self.newBlock()
629 self.emit('POP_TOP')
630
Raymond Hettinger354433a2004-05-19 08:20:33 +0000631 def visitGenExpr(self, node):
632 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
633 self.get_module())
634 walk(node.code, gen)
635 gen.finish()
636 self.set_lineno(node)
637 frees = gen.scope.get_free_vars()
638 if frees:
639 for name in frees:
640 self.emit('LOAD_CLOSURE', name)
641 self.emit('LOAD_CONST', gen)
642 self.emit('MAKE_CLOSURE', 0)
643 else:
644 self.emit('LOAD_CONST', gen)
645 self.emit('MAKE_FUNCTION', 0)
646
647 # precomputation of outmost iterable
648 self.visit(node.code.quals[0].iter)
649 self.emit('GET_ITER')
650 self.emit('CALL_FUNCTION', 1)
651
652 def visitGenExprInner(self, node):
653 self.set_lineno(node)
654 # setup list
655
656 stack = []
657 for i, for_ in zip(range(len(node.quals)), node.quals):
658 start, anchor = self.visit(for_)
659 cont = None
660 for if_ in for_.ifs:
661 if cont is None:
662 cont = self.newBlock()
663 self.visit(if_, cont)
664 stack.insert(0, (start, cont, anchor))
665
666 self.visit(node.expr)
667 self.emit('YIELD_VALUE')
668
669 for start, cont, anchor in stack:
670 if cont:
671 skip_one = self.newBlock()
672 self.emit('JUMP_FORWARD', skip_one)
673 self.startBlock(cont)
674 self.emit('POP_TOP')
675 self.nextBlock(skip_one)
676 self.emit('JUMP_ABSOLUTE', start)
677 self.startBlock(anchor)
678 self.emit('LOAD_CONST', None)
679
680 def visitGenExprFor(self, node):
681 start = self.newBlock()
682 anchor = self.newBlock()
Tim Peters4e0e1b62004-07-07 20:54:48 +0000683
Raymond Hettinger354433a2004-05-19 08:20:33 +0000684 if node.is_outmost:
685 self.loadName('[outmost-iterable]')
686 else:
687 self.visit(node.iter)
688 self.emit('GET_ITER')
689
690 self.nextBlock(start)
691 self.set_lineno(node, force=True)
692 self.emit('FOR_ITER', anchor)
693 self.nextBlock()
694 self.visit(node.assign)
695 return start, anchor
696
697 def visitGenExprIf(self, node, branch):
698 self.set_lineno(node, force=True)
699 self.visit(node.test)
700 self.emit('JUMP_IF_FALSE', branch)
701 self.newBlock()
702 self.emit('POP_TOP')
703
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000704 # exception related
705
706 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000707 # XXX would be interesting to implement this via a
708 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000709 if __debug__:
710 end = self.newBlock()
711 self.set_lineno(node)
712 # XXX AssertionError appears to be special case -- it is always
713 # loaded as a global even if there is a local name. I guess this
714 # is a sort of renaming op.
715 self.nextBlock()
716 self.visit(node.test)
717 self.emit('JUMP_IF_TRUE', end)
718 self.nextBlock()
719 self.emit('POP_TOP')
720 self.emit('LOAD_GLOBAL', 'AssertionError')
721 if node.fail:
722 self.visit(node.fail)
723 self.emit('RAISE_VARARGS', 2)
724 else:
725 self.emit('RAISE_VARARGS', 1)
726 self.nextBlock(end)
727 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000728
729 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000730 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000731 n = 0
732 if node.expr1:
733 self.visit(node.expr1)
734 n = n + 1
735 if node.expr2:
736 self.visit(node.expr2)
737 n = n + 1
738 if node.expr3:
739 self.visit(node.expr3)
740 n = n + 1
741 self.emit('RAISE_VARARGS', n)
742
743 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000744 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000745 handlers = self.newBlock()
746 end = self.newBlock()
747 if node.else_:
748 lElse = self.newBlock()
749 else:
750 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000751 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000752 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000753 self.nextBlock(body)
754 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000755 self.visit(node.body)
756 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000757 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000758 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000759 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000760
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000761 last = len(node.handlers) - 1
762 for i in range(len(node.handlers)):
763 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000764 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000765 if expr:
766 self.emit('DUP_TOP')
767 self.visit(expr)
768 self.emit('COMPARE_OP', 'exception match')
769 next = self.newBlock()
770 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000771 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000772 self.emit('POP_TOP')
773 self.emit('POP_TOP')
774 if target:
775 self.visit(target)
776 else:
777 self.emit('POP_TOP')
778 self.emit('POP_TOP')
779 self.visit(body)
780 self.emit('JUMP_FORWARD', end)
781 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000782 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000783 else:
784 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000785 if expr: # XXX
786 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000787 self.emit('END_FINALLY')
788 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000789 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000790 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000791 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000792
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000793 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000794 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000795 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000796 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000797 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000798 self.nextBlock(body)
799 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 self.visit(node.body)
801 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000802 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000804 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000805 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000806 self.visit(node.final)
807 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809
810 # misc
811
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000812 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000813 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000814 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000815 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000816
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000817 def visitConst(self, node):
818 self.emit('LOAD_CONST', node.value)
819
820 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000821 self.emit('LOAD_CONST', node.name)
822 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000823
824 def visitGlobal(self, node):
825 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000826 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000827
828 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000829 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000830 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000831
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000832 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000833 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000834
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000835 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000836 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000837 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000838 if VERSION > 1:
839 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000840 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000841 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000842 if alias:
843 self._resolveDots(name)
844 self.storeName(alias)
845 else:
846 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000847
848 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000849 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000850 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000851 if VERSION > 1:
852 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000853 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000854 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000855 if VERSION > 1:
856 if name == '*':
857 self.namespace = 0
858 self.emit('IMPORT_STAR')
859 # There can only be one name w/ from ... import *
860 assert len(node.names) == 1
861 return
862 else:
863 self.emit('IMPORT_FROM', name)
864 self._resolveDots(name)
865 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000866 else:
867 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000868 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000869
Jeremy Hylton20516082000-09-01 20:33:26 +0000870 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000871 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000872 if len(elts) == 1:
873 return
874 for elt in elts[1:]:
875 self.emit('LOAD_ATTR', elt)
876
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000877 def visitGetattr(self, node):
878 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000879 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000880
881 # next five implement assignments
882
883 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000884 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000885 self.visit(node.expr)
886 dups = len(node.nodes) - 1
887 for i in range(len(node.nodes)):
888 elt = node.nodes[i]
889 if i < dups:
890 self.emit('DUP_TOP')
891 if isinstance(elt, ast.Node):
892 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000893
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000894 def visitAssName(self, node):
895 if node.flags == 'OP_ASSIGN':
896 self.storeName(node.name)
897 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000898 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000899 self.delName(node.name)
900 else:
901 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000902
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000903 def visitAssAttr(self, node):
904 self.visit(node.expr)
905 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000906 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000907 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000908 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000909 else:
910 print "warning: unexpected flags:", node.flags
911 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000912
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000913 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000914 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000915 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000916 for child in node.nodes:
917 self.visit(child)
918
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000919 if VERSION > 1:
920 visitAssTuple = _visitAssSequence
921 visitAssList = _visitAssSequence
922 else:
923 def visitAssTuple(self, node):
924 self._visitAssSequence(node, 'UNPACK_TUPLE')
925
926 def visitAssList(self, node):
927 self._visitAssSequence(node, 'UNPACK_LIST')
928
929 # augmented assignment
930
931 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000932 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000933 aug_node = wrap_aug(node.node)
934 self.visit(aug_node, "load")
935 self.visit(node.expr)
936 self.emit(self._augmented_opcode[node.op])
937 self.visit(aug_node, "store")
938
939 _augmented_opcode = {
940 '+=' : 'INPLACE_ADD',
941 '-=' : 'INPLACE_SUBTRACT',
942 '*=' : 'INPLACE_MULTIPLY',
943 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000944 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000945 '%=' : 'INPLACE_MODULO',
946 '**=': 'INPLACE_POWER',
947 '>>=': 'INPLACE_RSHIFT',
948 '<<=': 'INPLACE_LSHIFT',
949 '&=' : 'INPLACE_AND',
950 '^=' : 'INPLACE_XOR',
951 '|=' : 'INPLACE_OR',
952 }
953
954 def visitAugName(self, node, mode):
955 if mode == "load":
956 self.loadName(node.name)
957 elif mode == "store":
958 self.storeName(node.name)
959
960 def visitAugGetattr(self, node, mode):
961 if mode == "load":
962 self.visit(node.expr)
963 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000964 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000965 elif mode == "store":
966 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000967 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000968
969 def visitAugSlice(self, node, mode):
970 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +0000971 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000972 elif mode == "store":
973 slice = 0
974 if node.lower:
975 slice = slice | 1
976 if node.upper:
977 slice = slice | 2
978 if slice == 0:
979 self.emit('ROT_TWO')
980 elif slice == 3:
981 self.emit('ROT_FOUR')
982 else:
983 self.emit('ROT_THREE')
984 self.emit('STORE_SLICE+%d' % slice)
985
986 def visitAugSubscript(self, node, mode):
987 if len(node.subs) > 1:
988 raise SyntaxError, "augmented assignment to tuple is not possible"
989 if mode == "load":
990 self.visitSubscript(node, 1)
991 elif mode == "store":
992 self.emit('ROT_THREE')
993 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000994
995 def visitExec(self, node):
996 self.visit(node.expr)
997 if node.locals is None:
998 self.emit('LOAD_CONST', None)
999 else:
1000 self.visit(node.locals)
1001 if node.globals is None:
1002 self.emit('DUP_TOP')
1003 else:
1004 self.visit(node.globals)
1005 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001006
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001007 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001008 pos = 0
1009 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001010 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001011 self.visit(node.node)
1012 for arg in node.args:
1013 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001014 if isinstance(arg, ast.Keyword):
1015 kw = kw + 1
1016 else:
1017 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001018 if node.star_args is not None:
1019 self.visit(node.star_args)
1020 if node.dstar_args is not None:
1021 self.visit(node.dstar_args)
1022 have_star = node.star_args is not None
1023 have_dstar = node.dstar_args is not None
1024 opcode = callfunc_opcode_info[have_star, have_dstar]
1025 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001026
Jeremy Hylton2afff322001-08-27 21:51:52 +00001027 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001028 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001029 if node.dest:
1030 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001031 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001032 if node.dest:
1033 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001034 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001035 if node.dest:
1036 self.emit('ROT_TWO')
1037 self.emit('PRINT_ITEM_TO')
1038 else:
1039 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001040 if node.dest and not newline:
1041 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001042
1043 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001044 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001045 if node.dest:
1046 self.emit('PRINT_NEWLINE_TO')
1047 else:
1048 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001049
1050 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001051 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001052 self.visit(node.value)
1053 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001054
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001055 def visitYield(self, node):
1056 self.set_lineno(node)
1057 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001058 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001059
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001060 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001061
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001062 def visitSlice(self, node, aug_flag=None):
1063 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001064 self.visit(node.expr)
1065 slice = 0
1066 if node.lower:
1067 self.visit(node.lower)
1068 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001069 if node.upper:
1070 self.visit(node.upper)
1071 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001072 if aug_flag:
1073 if slice == 0:
1074 self.emit('DUP_TOP')
1075 elif slice == 3:
1076 self.emit('DUP_TOPX', 3)
1077 else:
1078 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001079 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001080 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001081 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001082 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001083 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001084 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001085 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001086 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001087 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001088
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001089 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001090 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001091 for sub in node.subs:
1092 self.visit(sub)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001093 if aug_flag:
1094 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001095 if len(node.subs) > 1:
1096 self.emit('BUILD_TUPLE', len(node.subs))
1097 if node.flags == 'OP_APPLY':
1098 self.emit('BINARY_SUBSCR')
1099 elif node.flags == 'OP_ASSIGN':
1100 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001101 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001102 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001103
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001104 # binary ops
1105
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001106 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001107 self.visit(node.left)
1108 self.visit(node.right)
1109 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001110
1111 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001112 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001113
1114 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001115 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001116
1117 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001118 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001119
1120 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001121 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001122
Jeremy Hylton94afe322001-08-29 18:14:39 +00001123 def visitFloorDiv(self, node):
1124 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1125
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001126 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001127 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001128
Jeremy Hylton126960b2000-02-14 21:33:10 +00001129 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001130 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001131
1132 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001133 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001134
1135 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001136 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001137
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001138 # unary ops
1139
1140 def unaryOp(self, node, op):
1141 self.visit(node.expr)
1142 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001143
Jeremy Hylton126960b2000-02-14 21:33:10 +00001144 def visitInvert(self, node):
1145 return self.unaryOp(node, 'UNARY_INVERT')
1146
Jeremy Hylton40245602000-02-08 21:15:48 +00001147 def visitUnarySub(self, node):
1148 return self.unaryOp(node, 'UNARY_NEGATIVE')
1149
1150 def visitUnaryAdd(self, node):
1151 return self.unaryOp(node, 'UNARY_POSITIVE')
1152
1153 def visitUnaryInvert(self, node):
1154 return self.unaryOp(node, 'UNARY_INVERT')
1155
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001156 def visitNot(self, node):
1157 return self.unaryOp(node, 'UNARY_NOT')
1158
Jeremy Hylton40245602000-02-08 21:15:48 +00001159 def visitBackquote(self, node):
1160 return self.unaryOp(node, 'UNARY_CONVERT')
1161
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001162 # bit ops
1163
Jeremy Hyltona5058122000-02-14 14:14:29 +00001164 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001165 self.visit(nodes[0])
1166 for node in nodes[1:]:
1167 self.visit(node)
1168 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001169
1170 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001171 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001172
1173 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001174 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001175
1176 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001177 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001178
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001179 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001180
Jeremy Hyltona5058122000-02-14 14:14:29 +00001181 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001182 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001183
Jeremy Hylton40245602000-02-08 21:15:48 +00001184 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001185 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001186 for elt in node.nodes:
1187 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001188 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001189
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001190 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001191 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001192 for elt in node.nodes:
1193 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001194 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001195
1196 def visitSliceobj(self, node):
1197 for child in node.nodes:
1198 self.visit(child)
1199 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001200
Jeremy Hyltona5058122000-02-14 14:14:29 +00001201 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001202 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001203 self.emit('BUILD_MAP', 0)
1204 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001205 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001206 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001207 self.visit(v)
1208 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001209 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001210
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001211class NestedScopeMixin:
1212 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001213 def initClass(self):
1214 self.__class__.NameFinder = LocalNameFinder
1215 self.__class__.FunctionGen = FunctionCodeGenerator
1216 self.__class__.ClassGen = ClassCodeGenerator
1217
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001218class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001219 __super_init = CodeGenerator.__init__
1220
1221 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001222
Jeremy Hylton37c93512001-09-17 18:03:55 +00001223 def __init__(self, tree):
1224 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001225 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001226 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001227 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001228
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001229 def get_module(self):
1230 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001231
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001232class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1233 __super_init = CodeGenerator.__init__
1234
1235 scopes = None
1236 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001237
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001238 def __init__(self, tree):
1239 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1240 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001241 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001242
1243 def get_module(self):
1244 return self
1245
1246class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1247
1248 __super_init = CodeGenerator.__init__
1249
1250 scopes = None
1251 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001252
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001253 def __init__(self, tree):
1254 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1255 self.__super_init()
1256 self.set_lineno(tree)
1257 walk(tree, self)
1258 self.emit('RETURN_VALUE')
1259
1260 def get_module(self):
1261 return self
Tim Peterse4418602002-02-16 07:34:19 +00001262
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001263 def visitDiscard(self, node):
1264 # XXX Discard means it's an expression. Perhaps this is a bad
1265 # name.
1266 self.visit(node.expr)
1267 self.emit('PRINT_EXPR')
1268
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001269class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001270 optimized = 1
1271 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001272
Jeremy Hylton37c93512001-09-17 18:03:55 +00001273 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001274 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001275 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001276 if isLambda:
1277 klass = FunctionCodeGenerator
1278 name = "<lambda.%d>" % klass.lambdaCount
1279 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001280 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001281 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001282
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001283 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001284 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1285 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001286 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001287 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001288
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001289 if not isLambda and func.doc:
1290 self.setDocstring(func.doc)
1291
Jeremy Hylton2afff322001-08-27 21:51:52 +00001292 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001293 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001294 if func.varargs:
1295 self.graph.setFlag(CO_VARARGS)
1296 if func.kwargs:
1297 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001298 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001299 if hasTupleArg:
1300 self.generateArgUnpack(func.argnames)
1301
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001302 def get_module(self):
1303 return self.module
1304
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001305 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001306 self.graph.startExitBlock()
1307 if not self.isLambda:
1308 self.emit('LOAD_CONST', None)
1309 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001310
1311 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001312 for i in range(len(args)):
1313 arg = args[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001314 if isinstance(arg, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001315 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001316 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001317
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001318 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001319 if VERSION > 1:
1320 self.emit('UNPACK_SEQUENCE', len(tup))
1321 else:
1322 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001323 for elt in tup:
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001324 if isinstance(elt, tuple):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001325 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001326 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001327 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001328
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001329 unpackTuple = unpackSequence
1330
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001331class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001332 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001333 super_init = CodeGenerator.__init__ # call be other init
1334 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001335
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001336 __super_init = AbstractFunctionCode.__init__
1337
Jeremy Hylton37c93512001-09-17 18:03:55 +00001338 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001339 self.scopes = scopes
1340 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001341 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001342 self.graph.setFreeVars(self.scope.get_free_vars())
1343 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001344 if self.scope.generator is not None:
1345 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001346
Raymond Hettinger354433a2004-05-19 08:20:33 +00001347class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1348 CodeGenerator):
1349 super_init = CodeGenerator.__init__ # call be other init
1350 scopes = None
1351
1352 __super_init = AbstractFunctionCode.__init__
1353
1354 def __init__(self, gexp, scopes, class_name, mod):
1355 self.scopes = scopes
1356 self.scope = scopes[gexp]
1357 self.__super_init(gexp, scopes, 1, class_name, mod)
1358 self.graph.setFreeVars(self.scope.get_free_vars())
1359 self.graph.setCellVars(self.scope.get_cell_vars())
1360 self.graph.setFlag(CO_GENERATOR)
1361
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001362class AbstractClassCode:
1363
Jeremy Hylton37c93512001-09-17 18:03:55 +00001364 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001365 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001366 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001367 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001368 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001369 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001370 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001371 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001372 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001373 if klass.doc:
1374 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001375
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001376 def get_module(self):
1377 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001378
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001379 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001380 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001381 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001382 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001383
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001384class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001385 super_init = CodeGenerator.__init__
1386 scopes = None
1387
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001388 __super_init = AbstractClassCode.__init__
1389
Jeremy Hylton37c93512001-09-17 18:03:55 +00001390 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001391 self.scopes = scopes
1392 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001393 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001394 self.graph.setFreeVars(self.scope.get_free_vars())
1395 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001396 self.set_lineno(klass)
1397 self.emit("LOAD_GLOBAL", "__name__")
1398 self.storeName("__module__")
1399 if klass.doc:
1400 self.emit("LOAD_CONST", klass.doc)
1401 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001402
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001403def generateArgList(arglist):
1404 """Generate an arg list marking TupleArgs"""
1405 args = []
1406 extra = []
1407 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001408 for i in range(len(arglist)):
1409 elt = arglist[i]
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001410 if isinstance(elt, str):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001411 args.append(elt)
Neal Norwitzd752f7d2005-11-25 03:17:59 +00001412 elif isinstance(elt, tuple):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001413 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001414 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001415 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001416 else:
1417 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001418 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001419
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001420def findOp(node):
1421 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1422 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001423 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001424 return v.op
1425
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001426class OpFinder:
1427 def __init__(self):
1428 self.op = None
1429 def visitAssName(self, node):
1430 if self.op is None:
1431 self.op = node.flags
1432 elif self.op != node.flags:
1433 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001434 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001435 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001436
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001437class Delegator:
1438 """Base class to support delegation for augmented assignment nodes
1439
1440 To generator code for augmented assignments, we use the following
1441 wrapper classes. In visitAugAssign, the left-hand expression node
1442 is visited twice. The first time the visit uses the normal method
1443 for that node . The second time the visit uses a different method
1444 that generates the appropriate code to perform the assignment.
1445 These delegator classes wrap the original AST nodes in order to
1446 support the variant visit methods.
1447 """
1448 def __init__(self, obj):
1449 self.obj = obj
1450
1451 def __getattr__(self, attr):
1452 return getattr(self.obj, attr)
1453
1454class AugGetattr(Delegator):
1455 pass
1456
1457class AugName(Delegator):
1458 pass
1459
1460class AugSlice(Delegator):
1461 pass
1462
1463class AugSubscript(Delegator):
1464 pass
1465
1466wrapper = {
1467 ast.Getattr: AugGetattr,
1468 ast.Name: AugName,
1469 ast.Slice: AugSlice,
1470 ast.Subscript: AugSubscript,
1471 }
1472
1473def wrap_aug(node):
1474 return wrapper[node.__class__](node)
1475
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001476if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001477 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001478 compileFile(file)