blob: 87558b211b1569525eba0a404d8a496ec690c582 [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 Hyltonad9a86f2000-02-16 00:55:44 +00006import types
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00007from cStringIO import StringIO
8
Jeremy Hylton37c93512001-09-17 18:03:55 +00009from compiler import ast, parse, walk, syntax
Jeremy Hylton364f9b92001-04-12 06:40:42 +000010from compiler import pyassem, misc, future, symbols
11from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
Jeremy Hylton71ebc332001-08-30 20:25:55 +000012from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
Jeremy Hylton1e99a772001-09-14 22:49:08 +000013 CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
Jeremy Hylton71ebc332001-08-30 20:25:55 +000014from compiler.pyassem import TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000015
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000016# XXX The version-specific code can go, since this code only works with 2.x.
Jeremy Hylton9c048f92000-10-13 21:58:13 +000017# Do we have Python 1.x or Python 2.x?
18try:
19 VERSION = sys.version_info[0]
20except AttributeError:
21 VERSION = 1
22
Jeremy Hyltonbe317e62000-05-02 22:32:59 +000023callfunc_opcode_info = {
24 # (Have *args, Have **args) : opcode
25 (0,0) : "CALL_FUNCTION",
26 (1,0) : "CALL_FUNCTION_VAR",
27 (0,1) : "CALL_FUNCTION_KW",
28 (1,1) : "CALL_FUNCTION_VAR_KW",
29}
30
Jeremy Hyltone4685ec2001-08-29 22:30:09 +000031LOOP = 1
32EXCEPT = 2
33TRY_FINALLY = 3
34END_FINALLY = 4
35
Jeremy Hylton9dca3642001-09-17 21:02:51 +000036def compileFile(filename, display=0):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000037 f = open(filename, 'U')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000038 buf = f.read()
39 f.close()
40 mod = Module(buf, filename)
Jeremy Hylton37c93512001-09-17 18:03:55 +000041 try:
42 mod.compile(display)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +000043 except SyntaxError:
Jeremy Hylton2e4cc7e2001-09-17 19:33:48 +000044 raise
Jeremy Hylton37c93512001-09-17 18:03:55 +000045 else:
46 f = open(filename + "c", "wb")
47 mod.dump(f)
48 f.close()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000049
Jeremy Hylton9dca3642001-09-17 21:02:51 +000050def compile(source, filename, mode, flags=None, dont_inherit=None):
51 """Replacement for builtin compile() function"""
52 if flags is not None or dont_inherit is not None:
53 raise RuntimeError, "not implemented yet"
Tim Peterse0c446b2001-10-18 21:57:37 +000054
Jeremy Hylton9dca3642001-09-17 21:02:51 +000055 if mode == "single":
56 gen = Interactive(source, filename)
57 elif mode == "exec":
58 gen = Module(source, filename)
59 elif mode == "eval":
60 gen = Expression(source, filename)
61 else:
62 raise ValueError("compile() 3rd arg must be 'exec' or "
63 "'eval' or 'single'")
64 gen.compile()
65 return gen.code
66
67class AbstractCompileMode:
68
69 mode = None # defined by subclass
70
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000071 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000072 self.source = source
Jeremy Hylton9dca3642001-09-17 21:02:51 +000073 self.filename = filename
Thomas Wouters46cc7c02000-08-12 20:32:46 +000074 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000075
Jeremy Hylton9dca3642001-09-17 21:02:51 +000076 def _get_tree(self):
77 tree = parse(self.source, self.mode)
Jeremy Hylton37c93512001-09-17 18:03:55 +000078 misc.set_filename(self.filename, tree)
79 syntax.check(tree)
Jeremy Hylton9dca3642001-09-17 21:02:51 +000080 return tree
81
82 def compile(self):
83 pass # implemented by subclass
84
85 def getCode(self):
86 return self.code
87
88class Expression(AbstractCompileMode):
89
90 mode = "eval"
91
92 def compile(self):
93 tree = self._get_tree()
94 gen = ExpressionCodeGenerator(tree)
95 self.code = gen.getCode()
96
97class Interactive(AbstractCompileMode):
98
99 mode = "single"
100
101 def compile(self):
102 tree = self._get_tree()
103 gen = InteractiveCodeGenerator(tree)
104 self.code = gen.getCode()
105
106class Module(AbstractCompileMode):
107
108 mode = "exec"
109
110 def compile(self, display=0):
111 tree = self._get_tree()
Jeremy Hylton37c93512001-09-17 18:03:55 +0000112 gen = ModuleCodeGenerator(tree)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000113 if display:
114 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000115 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000116 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000117
118 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000119 f.write(self.getPycHeader())
120 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000121
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000122 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000123
124 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000125 # compile.c uses marshal to write a long directly, with
126 # calling the interface that would also generate a 1-byte code
127 # to indicate the type of the value. simplest way to get the
128 # same effect is to call marshal and then skip the code.
Neal Norwitza312c3a2002-06-06 18:30:10 +0000129 mtime = os.path.getmtime(self.filename)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000130 mtime = struct.pack('<i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000131 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000132
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000133class LocalNameFinder:
134 """Find local names in scope"""
135 def __init__(self, names=()):
136 self.names = misc.Set()
137 self.globals = misc.Set()
138 for name in names:
139 self.names.add(name)
140
141 # XXX list comprehensions and for loops
142
143 def getLocals(self):
144 for elt in self.globals.elements():
145 if self.names.has_elt(elt):
146 self.names.remove(elt)
147 return self.names
148
149 def visitDict(self, node):
150 pass
151
152 def visitGlobal(self, node):
153 for name in node.names:
154 self.globals.add(name)
155
156 def visitFunction(self, node):
157 self.names.add(node.name)
158
159 def visitLambda(self, node):
160 pass
161
162 def visitImport(self, node):
163 for name, alias in node.names:
164 self.names.add(alias or name)
165
166 def visitFrom(self, node):
167 for name, alias in node.names:
168 self.names.add(alias or name)
169
170 def visitClass(self, node):
171 self.names.add(node.name)
172
173 def visitAssName(self, node):
174 self.names.add(node.name)
175
Jeremy Hylton2afff322001-08-27 21:51:52 +0000176def is_constant_false(node):
177 if isinstance(node, ast.Const):
178 if not node.value:
179 return 1
180 return 0
181
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000182class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000183 """Defines basic code generator for Python bytecode
184
185 This class is an abstract base class. Concrete subclasses must
186 define an __init__() that defines self.graph and then calls the
187 __init__() defined in this class.
188
189 The concrete class must also define the class attributes
190 NameFinder, FunctionGen, and ClassGen. These attributes can be
191 defined in the initClass() method, which is a hook for
192 initializing these methods after all the classes have been
Tim Peterse0c446b2001-10-18 21:57:37 +0000193 defined.
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000194 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000195
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000196 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000197 __initialized = None
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000198 class_name = None # provide default for instance variable
Jeremy Hylton3050d512000-02-12 00:12:38 +0000199
Jeremy Hylton37c93512001-09-17 18:03:55 +0000200 def __init__(self):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000201 if self.__initialized is None:
202 self.initClass()
203 self.__class__.__initialized = 1
204 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000205 self.locals = misc.Stack()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000206 self.setups = misc.Stack()
Jeremy Hylton92f39722000-09-01 20:47:37 +0000207 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000208 self._setupGraphDelegation()
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000209 self._div_op = "BINARY_DIVIDE"
Jeremy Hylton53187f32000-02-08 19:01:29 +0000210
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000211 # XXX set flags based on future features
212 futures = self.get_module().futures
213 for feature in futures:
214 if feature == "division":
215 self.graph.setFlag(CO_FUTURE_DIVISION)
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +0000216 self._div_op = "BINARY_TRUE_DIVIDE"
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000217 elif feature == "generators":
218 self.graph.setFlag(CO_GENERATOR_ALLOWED)
219
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000220 def initClass(self):
221 """This method is called once for each class"""
222
223 def checkClass(self):
224 """Verify that class is constructed correctly"""
225 try:
226 assert hasattr(self, 'graph')
227 assert getattr(self, 'NameFinder')
228 assert getattr(self, 'FunctionGen')
229 assert getattr(self, 'ClassGen')
230 except AssertionError, msg:
231 intro = "Bad class construction for %s" % self.__class__.__name__
232 raise AssertionError, intro
233
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000234 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000235 self.emit = self.graph.emit
236 self.newBlock = self.graph.newBlock
237 self.startBlock = self.graph.startBlock
238 self.nextBlock = self.graph.nextBlock
239 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000240
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000241 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000242 """Return a code object"""
243 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000244
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000245 def mangle(self, name):
246 if self.class_name is not None:
247 return misc.mangle(name, self.class_name)
248 else:
249 return name
250
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000251 def parseSymbols(self, tree):
252 s = symbols.SymbolVisitor()
253 walk(tree, s)
254 return s.scopes
255
256 def get_module(self):
257 raise RuntimeError, "should be implemented by subclasses"
258
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000259 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000260
Jeremy Hylton40245602000-02-08 21:15:48 +0000261 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000262 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000263
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000264 def storeName(self, name):
265 self._nameOp('STORE', name)
266
267 def loadName(self, name):
268 self._nameOp('LOAD', name)
269
270 def delName(self, name):
271 self._nameOp('DELETE', name)
272
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000273 def _nameOp(self, prefix, name):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000274 name = self.mangle(name)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000275 scope = self.scope.check_name(name)
276 if scope == SC_LOCAL:
277 if not self.optimized:
278 self.emit(prefix + '_NAME', name)
279 else:
280 self.emit(prefix + '_FAST', name)
281 elif scope == SC_GLOBAL:
282 if not self.optimized:
283 self.emit(prefix + '_NAME', name)
284 else:
285 self.emit(prefix + '_GLOBAL', name)
286 elif scope == SC_FREE or scope == SC_CELL:
287 self.emit(prefix + '_DEREF', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000288 else:
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000289 raise RuntimeError, "unsupported scope for var %s: %d" % \
290 (name, scope)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000291
Jeremy Hylton13d70942001-04-12 21:04:43 +0000292 def _implicitNameOp(self, prefix, name):
293 """Emit name ops for names generated implicitly by for loops
294
295 The interpreter generates names that start with a period or
296 dollar sign. The symbol table ignores these names because
297 they aren't present in the program text.
298 """
299 if self.optimized:
300 self.emit(prefix + '_FAST', name)
301 else:
302 self.emit(prefix + '_NAME', name)
303
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000304 # The set_lineno() function and the explicit emit() calls for
305 # SET_LINENO below are only used to generate the line number table.
306 # As of Python 2.3, the interpreter does not have a SET_LINENO
307 # instruction. pyassem treats SET_LINENO opcodes as a special case.
308
309 def set_lineno(self, node, force=False):
310 """Emit SET_LINENO if necessary.
311
312 The instruction is considered necessary if the node has a
313 lineno attribute and it is different than the last lineno
314 emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000315
316 Returns true if SET_LINENO was emitted.
317
318 There are no rules for when an AST node should have a lineno
319 attribute. The transformer and AST code need to be reviewed
320 and a consistent policy implemented and documented. Until
321 then, this method works around missing line numbers.
322 """
323 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000324 if lineno is not None and (lineno != self.last_lineno
325 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000326 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000327 self.last_lineno = lineno
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000328 return True
329 return False
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000330
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000331 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000332 # code objects. They use class attributes to determine what
333 # specialized code generators to use.
334
335 NameFinder = LocalNameFinder
336 FunctionGen = None
337 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000338
339 def visitModule(self, node):
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000340 self.scopes = self.parseSymbols(node)
341 self.scope = self.scopes[node]
Jeremy Hylton13d70942001-04-12 21:04:43 +0000342 self.emit('SET_LINENO', 0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000343 if node.doc:
Jeremy Hylton2afff322001-08-27 21:51:52 +0000344 self.emit('LOAD_CONST', node.doc)
345 self.storeName('__doc__')
346 lnf = walk(node.node, self.NameFinder(), verbose=0)
347 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000348 self.visit(node.node)
349 self.emit('LOAD_CONST', None)
350 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000351
Barry Warsaw52acb492001-12-21 20:04:22 +0000352 def visitExpression(self, node):
353 self.set_lineno(node)
354 self.scopes = self.parseSymbols(node)
355 self.scope = self.scopes[node]
356 self.visit(node.node)
357 self.emit('RETURN_VALUE')
358
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000359 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000360 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000361 if node.doc:
362 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000363 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000364
365 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000366 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000367
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000368 def _visitFuncOrLambda(self, node, isLambda=0):
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000369 if not isLambda and node.decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +0000370 for decorator in node.decorators.nodes:
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000371 self.visit(decorator)
372 ndecorators = len(node.decorators.nodes)
373 else:
374 ndecorators = 0
Tim Petersa45cacf2004-08-20 03:47:14 +0000375
Jeremy Hylton37c93512001-09-17 18:03:55 +0000376 gen = self.FunctionGen(node, self.scopes, isLambda,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000377 self.class_name, self.get_module())
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000378 walk(node.code, gen)
379 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000380 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000381 for default in node.defaults:
382 self.visit(default)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000383 frees = gen.scope.get_free_vars()
384 if frees:
385 for name in frees:
386 self.emit('LOAD_CLOSURE', name)
387 self.emit('LOAD_CONST', gen)
388 self.emit('MAKE_CLOSURE', len(node.defaults))
389 else:
390 self.emit('LOAD_CONST', gen)
391 self.emit('MAKE_FUNCTION', len(node.defaults))
Tim Peters6db15d72004-08-04 02:36:18 +0000392
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000393 for i in range(ndecorators):
394 self.emit('CALL_FUNCTION', 1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000395
396 def visitClass(self, node):
Jeremy Hylton37c93512001-09-17 18:03:55 +0000397 gen = self.ClassGen(node, self.scopes,
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000398 self.get_module())
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000399 walk(node.code, gen)
400 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000401 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000402 self.emit('LOAD_CONST', node.name)
403 for base in node.bases:
404 self.visit(base)
405 self.emit('BUILD_TUPLE', len(node.bases))
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000406 frees = gen.scope.get_free_vars()
407 for name in frees:
408 self.emit('LOAD_CLOSURE', name)
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000409 self.emit('LOAD_CONST', gen)
Jeremy Hylton1e99a772001-09-14 22:49:08 +0000410 if frees:
411 self.emit('MAKE_CLOSURE', 0)
412 else:
413 self.emit('MAKE_FUNCTION', 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000414 self.emit('CALL_FUNCTION', 0)
415 self.emit('BUILD_CLASS')
416 self.storeName(node.name)
417
418 # The rest are standard visitor methods
419
420 # The next few implement control-flow statements
421
422 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000423 end = self.newBlock()
424 numtests = len(node.tests)
425 for i in range(numtests):
426 test, suite = node.tests[i]
Jeremy Hylton2afff322001-08-27 21:51:52 +0000427 if is_constant_false(test):
428 # XXX will need to check generator stuff here
429 continue
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000430 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000431 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000432 nextTest = self.newBlock()
433 self.emit('JUMP_IF_FALSE', nextTest)
434 self.nextBlock()
435 self.emit('POP_TOP')
436 self.visit(suite)
437 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000438 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000439 self.emit('POP_TOP')
440 if node.else_:
441 self.visit(node.else_)
442 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000443
444 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000445 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000446
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000447 loop = self.newBlock()
448 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000449
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000450 after = self.newBlock()
451 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000452
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000453 self.nextBlock(loop)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000454 self.setups.push((LOOP, loop))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000455
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000456 self.set_lineno(node, force=True)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000457 self.visit(node.test)
458 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000459
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000460 self.nextBlock()
461 self.emit('POP_TOP')
462 self.visit(node.body)
463 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000464
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000465 self.startBlock(else_) # or just the POPs if not else clause
466 self.emit('POP_TOP')
467 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000468 self.setups.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000469 if node.else_:
470 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000471 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000472
473 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000474 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000475 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000476 after = self.newBlock()
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000477 self.setups.push((LOOP, start))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000478
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000479 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000480 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000481 self.visit(node.list)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000482 self.emit('GET_ITER')
483
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000484 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000485 self.set_lineno(node, force=1)
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000486 self.emit('FOR_ITER', anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000487 self.visit(node.assign)
488 self.visit(node.body)
489 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton2ac9c3e2001-08-28 17:28:33 +0000490 self.nextBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000491 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000492 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000493 if node.else_:
494 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000495 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000496
497 def visitBreak(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000498 if not self.setups:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000499 raise SyntaxError, "'break' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000500 (node.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000501 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000502 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000503
504 def visitContinue(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000505 if not self.setups:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000506 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000507 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000508 kind, block = self.setups.top()
509 if kind == LOOP:
510 self.set_lineno(node)
511 self.emit('JUMP_ABSOLUTE', block)
512 self.nextBlock()
513 elif kind == EXCEPT or kind == TRY_FINALLY:
514 self.set_lineno(node)
515 # find the block that starts the loop
516 top = len(self.setups)
517 while top > 0:
518 top = top - 1
519 kind, loop_block = self.setups[top]
520 if kind == LOOP:
521 break
522 if kind != LOOP:
523 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Jeremy Hylton37c93512001-09-17 18:03:55 +0000524 (node.filename, node.lineno)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000525 self.emit('CONTINUE_LOOP', loop_block)
526 self.nextBlock()
527 elif kind == END_FINALLY:
Tim Peterse0c446b2001-10-18 21:57:37 +0000528 msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
Jeremy Hylton37c93512001-09-17 18:03:55 +0000529 raise SyntaxError, msg % (node.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000530
531 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000532 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000533 for child in node.nodes[:-1]:
534 self.visit(child)
535 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000536 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000537 self.emit('POP_TOP')
538 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000539 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000540
541 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000542 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000543
544 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000545 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000546
547 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000548 self.visit(node.expr)
549 cleanup = self.newBlock()
550 for op, code in node.ops[:-1]:
551 self.visit(code)
552 self.emit('DUP_TOP')
553 self.emit('ROT_THREE')
554 self.emit('COMPARE_OP', op)
555 self.emit('JUMP_IF_FALSE', cleanup)
556 self.nextBlock()
557 self.emit('POP_TOP')
558 # now do the last comparison
559 if node.ops:
560 op, code = node.ops[-1]
561 self.visit(code)
562 self.emit('COMPARE_OP', op)
563 if len(node.ops) > 1:
564 end = self.newBlock()
565 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000566 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000567 self.emit('ROT_TWO')
568 self.emit('POP_TOP')
569 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000570
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000571 # list comprehensions
572 __list_count = 0
Tim Peterse0c446b2001-10-18 21:57:37 +0000573
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000574 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000575 self.set_lineno(node)
576 # setup list
577 append = "$append%d" % self.__list_count
578 self.__list_count = self.__list_count + 1
579 self.emit('BUILD_LIST', 0)
580 self.emit('DUP_TOP')
581 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000582 self._implicitNameOp('STORE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000583
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000584 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000585 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000586 start, anchor = self.visit(for_)
587 cont = None
588 for if_ in for_.ifs:
589 if cont is None:
590 cont = self.newBlock()
591 self.visit(if_, cont)
592 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000593
Jeremy Hylton13d70942001-04-12 21:04:43 +0000594 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000595 self.visit(node.expr)
596 self.emit('CALL_FUNCTION', 1)
597 self.emit('POP_TOP')
Tim Peterse0c446b2001-10-18 21:57:37 +0000598
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000599 for start, cont, anchor in stack:
600 if cont:
601 skip_one = self.newBlock()
602 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000603 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000604 self.emit('POP_TOP')
605 self.nextBlock(skip_one)
606 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000607 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000608 self._implicitNameOp('DELETE', append)
Tim Peterse0c446b2001-10-18 21:57:37 +0000609
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000610 self.__list_count = self.__list_count - 1
611
612 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000613 start = self.newBlock()
614 anchor = self.newBlock()
615
616 self.visit(node.list)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000617 self.emit('GET_ITER')
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000618 self.nextBlock(start)
Jeremy Hylton18565412002-12-31 18:26:17 +0000619 self.set_lineno(node, force=True)
Jeremy Hylton71ebc332001-08-30 20:25:55 +0000620 self.emit('FOR_ITER', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000621 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000622 self.visit(node.assign)
623 return start, anchor
624
625 def visitListCompIf(self, node, branch):
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000626 self.set_lineno(node, force=True)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000627 self.visit(node.test)
628 self.emit('JUMP_IF_FALSE', branch)
629 self.newBlock()
630 self.emit('POP_TOP')
631
Raymond Hettinger354433a2004-05-19 08:20:33 +0000632 def visitGenExpr(self, node):
633 gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
634 self.get_module())
635 walk(node.code, gen)
636 gen.finish()
637 self.set_lineno(node)
638 frees = gen.scope.get_free_vars()
639 if frees:
640 for name in frees:
641 self.emit('LOAD_CLOSURE', name)
642 self.emit('LOAD_CONST', gen)
643 self.emit('MAKE_CLOSURE', 0)
644 else:
645 self.emit('LOAD_CONST', gen)
646 self.emit('MAKE_FUNCTION', 0)
647
648 # precomputation of outmost iterable
649 self.visit(node.code.quals[0].iter)
650 self.emit('GET_ITER')
651 self.emit('CALL_FUNCTION', 1)
652
653 def visitGenExprInner(self, node):
654 self.set_lineno(node)
655 # setup list
656
657 stack = []
658 for i, for_ in zip(range(len(node.quals)), node.quals):
659 start, anchor = self.visit(for_)
660 cont = None
661 for if_ in for_.ifs:
662 if cont is None:
663 cont = self.newBlock()
664 self.visit(if_, cont)
665 stack.insert(0, (start, cont, anchor))
666
667 self.visit(node.expr)
668 self.emit('YIELD_VALUE')
669
670 for start, cont, anchor in stack:
671 if cont:
672 skip_one = self.newBlock()
673 self.emit('JUMP_FORWARD', skip_one)
674 self.startBlock(cont)
675 self.emit('POP_TOP')
676 self.nextBlock(skip_one)
677 self.emit('JUMP_ABSOLUTE', start)
678 self.startBlock(anchor)
679 self.emit('LOAD_CONST', None)
680
681 def visitGenExprFor(self, node):
682 start = self.newBlock()
683 anchor = self.newBlock()
Tim Peters4e0e1b62004-07-07 20:54:48 +0000684
Raymond Hettinger354433a2004-05-19 08:20:33 +0000685 if node.is_outmost:
686 self.loadName('[outmost-iterable]')
687 else:
688 self.visit(node.iter)
689 self.emit('GET_ITER')
690
691 self.nextBlock(start)
692 self.set_lineno(node, force=True)
693 self.emit('FOR_ITER', anchor)
694 self.nextBlock()
695 self.visit(node.assign)
696 return start, anchor
697
698 def visitGenExprIf(self, node, branch):
699 self.set_lineno(node, force=True)
700 self.visit(node.test)
701 self.emit('JUMP_IF_FALSE', branch)
702 self.newBlock()
703 self.emit('POP_TOP')
704
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000705 # exception related
706
707 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000708 # XXX would be interesting to implement this via a
709 # transformation of the AST before this stage
Jeremy Hylton2876f5a2004-08-07 19:21:56 +0000710 if __debug__:
711 end = self.newBlock()
712 self.set_lineno(node)
713 # XXX AssertionError appears to be special case -- it is always
714 # loaded as a global even if there is a local name. I guess this
715 # is a sort of renaming op.
716 self.nextBlock()
717 self.visit(node.test)
718 self.emit('JUMP_IF_TRUE', end)
719 self.nextBlock()
720 self.emit('POP_TOP')
721 self.emit('LOAD_GLOBAL', 'AssertionError')
722 if node.fail:
723 self.visit(node.fail)
724 self.emit('RAISE_VARARGS', 2)
725 else:
726 self.emit('RAISE_VARARGS', 1)
727 self.nextBlock(end)
728 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000729
730 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000731 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000732 n = 0
733 if node.expr1:
734 self.visit(node.expr1)
735 n = n + 1
736 if node.expr2:
737 self.visit(node.expr2)
738 n = n + 1
739 if node.expr3:
740 self.visit(node.expr3)
741 n = n + 1
742 self.emit('RAISE_VARARGS', n)
743
744 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000745 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000746 handlers = self.newBlock()
747 end = self.newBlock()
748 if node.else_:
749 lElse = self.newBlock()
750 else:
751 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000752 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000753 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000754 self.nextBlock(body)
755 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000756 self.visit(node.body)
757 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000758 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000759 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000760 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000761
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000762 last = len(node.handlers) - 1
763 for i in range(len(node.handlers)):
764 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000765 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000766 if expr:
767 self.emit('DUP_TOP')
768 self.visit(expr)
769 self.emit('COMPARE_OP', 'exception match')
770 next = self.newBlock()
771 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000772 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000773 self.emit('POP_TOP')
774 self.emit('POP_TOP')
775 if target:
776 self.visit(target)
777 else:
778 self.emit('POP_TOP')
779 self.emit('POP_TOP')
780 self.visit(body)
781 self.emit('JUMP_FORWARD', end)
782 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000783 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000784 else:
785 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000786 if expr: # XXX
787 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000788 self.emit('END_FINALLY')
789 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000790 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000791 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000792 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000793
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000794 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000795 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000796 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000797 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000798 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000799 self.nextBlock(body)
800 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000801 self.visit(node.body)
802 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000803 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000804 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000805 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000806 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000807 self.visit(node.final)
808 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000809 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000810
811 # misc
812
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000813 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000814 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000815 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000816 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000817
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000818 def visitConst(self, node):
819 self.emit('LOAD_CONST', node.value)
820
821 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000822 self.emit('LOAD_CONST', node.name)
823 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000824
825 def visitGlobal(self, node):
826 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000827 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000828
829 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000830 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000831 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000832
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000833 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000834 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000835
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000836 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000837 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000838 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000839 if VERSION > 1:
840 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000841 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000842 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000843 if alias:
844 self._resolveDots(name)
845 self.storeName(alias)
846 else:
847 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000848
849 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000850 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000851 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000852 if VERSION > 1:
853 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000854 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000855 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000856 if VERSION > 1:
857 if name == '*':
858 self.namespace = 0
859 self.emit('IMPORT_STAR')
860 # There can only be one name w/ from ... import *
861 assert len(node.names) == 1
862 return
863 else:
864 self.emit('IMPORT_FROM', name)
865 self._resolveDots(name)
866 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000867 else:
868 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000869 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000870
Jeremy Hylton20516082000-09-01 20:33:26 +0000871 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000872 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000873 if len(elts) == 1:
874 return
875 for elt in elts[1:]:
876 self.emit('LOAD_ATTR', elt)
877
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000878 def visitGetattr(self, node):
879 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000880 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000881
882 # next five implement assignments
883
884 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000885 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000886 self.visit(node.expr)
887 dups = len(node.nodes) - 1
888 for i in range(len(node.nodes)):
889 elt = node.nodes[i]
890 if i < dups:
891 self.emit('DUP_TOP')
892 if isinstance(elt, ast.Node):
893 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000894
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000895 def visitAssName(self, node):
896 if node.flags == 'OP_ASSIGN':
897 self.storeName(node.name)
898 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000899 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000900 self.delName(node.name)
901 else:
902 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000903
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000904 def visitAssAttr(self, node):
905 self.visit(node.expr)
906 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000907 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000908 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000909 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000910 else:
911 print "warning: unexpected flags:", node.flags
912 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000913
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000914 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000915 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000916 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000917 for child in node.nodes:
918 self.visit(child)
919
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000920 if VERSION > 1:
921 visitAssTuple = _visitAssSequence
922 visitAssList = _visitAssSequence
923 else:
924 def visitAssTuple(self, node):
925 self._visitAssSequence(node, 'UNPACK_TUPLE')
926
927 def visitAssList(self, node):
928 self._visitAssSequence(node, 'UNPACK_LIST')
929
930 # augmented assignment
931
932 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000933 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000934 aug_node = wrap_aug(node.node)
935 self.visit(aug_node, "load")
936 self.visit(node.expr)
937 self.emit(self._augmented_opcode[node.op])
938 self.visit(aug_node, "store")
939
940 _augmented_opcode = {
941 '+=' : 'INPLACE_ADD',
942 '-=' : 'INPLACE_SUBTRACT',
943 '*=' : 'INPLACE_MULTIPLY',
944 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000945 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000946 '%=' : 'INPLACE_MODULO',
947 '**=': 'INPLACE_POWER',
948 '>>=': 'INPLACE_RSHIFT',
949 '<<=': 'INPLACE_LSHIFT',
950 '&=' : 'INPLACE_AND',
951 '^=' : 'INPLACE_XOR',
952 '|=' : 'INPLACE_OR',
953 }
954
955 def visitAugName(self, node, mode):
956 if mode == "load":
957 self.loadName(node.name)
958 elif mode == "store":
959 self.storeName(node.name)
960
961 def visitAugGetattr(self, node, mode):
962 if mode == "load":
963 self.visit(node.expr)
964 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000965 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000966 elif mode == "store":
967 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000968 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000969
970 def visitAugSlice(self, node, mode):
971 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +0000972 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000973 elif mode == "store":
974 slice = 0
975 if node.lower:
976 slice = slice | 1
977 if node.upper:
978 slice = slice | 2
979 if slice == 0:
980 self.emit('ROT_TWO')
981 elif slice == 3:
982 self.emit('ROT_FOUR')
983 else:
984 self.emit('ROT_THREE')
985 self.emit('STORE_SLICE+%d' % slice)
986
987 def visitAugSubscript(self, node, mode):
988 if len(node.subs) > 1:
989 raise SyntaxError, "augmented assignment to tuple is not possible"
990 if mode == "load":
991 self.visitSubscript(node, 1)
992 elif mode == "store":
993 self.emit('ROT_THREE')
994 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000995
996 def visitExec(self, node):
997 self.visit(node.expr)
998 if node.locals is None:
999 self.emit('LOAD_CONST', None)
1000 else:
1001 self.visit(node.locals)
1002 if node.globals is None:
1003 self.emit('DUP_TOP')
1004 else:
1005 self.visit(node.globals)
1006 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001007
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001008 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001009 pos = 0
1010 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001011 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001012 self.visit(node.node)
1013 for arg in node.args:
1014 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001015 if isinstance(arg, ast.Keyword):
1016 kw = kw + 1
1017 else:
1018 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001019 if node.star_args is not None:
1020 self.visit(node.star_args)
1021 if node.dstar_args is not None:
1022 self.visit(node.dstar_args)
1023 have_star = node.star_args is not None
1024 have_dstar = node.dstar_args is not None
1025 opcode = callfunc_opcode_info[have_star, have_dstar]
1026 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001027
Jeremy Hylton2afff322001-08-27 21:51:52 +00001028 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001029 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001030 if node.dest:
1031 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001032 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001033 if node.dest:
1034 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001035 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001036 if node.dest:
1037 self.emit('ROT_TWO')
1038 self.emit('PRINT_ITEM_TO')
1039 else:
1040 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001041 if node.dest and not newline:
1042 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001043
1044 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001045 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001046 if node.dest:
1047 self.emit('PRINT_NEWLINE_TO')
1048 else:
1049 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001050
1051 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001052 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001053 self.visit(node.value)
1054 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001055
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001056 def visitYield(self, node):
1057 self.set_lineno(node)
1058 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001059 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001060
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001061 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001062
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001063 def visitSlice(self, node, aug_flag=None):
1064 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001065 self.visit(node.expr)
1066 slice = 0
1067 if node.lower:
1068 self.visit(node.lower)
1069 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001070 if node.upper:
1071 self.visit(node.upper)
1072 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001073 if aug_flag:
1074 if slice == 0:
1075 self.emit('DUP_TOP')
1076 elif slice == 3:
1077 self.emit('DUP_TOPX', 3)
1078 else:
1079 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001080 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001081 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001082 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001083 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001084 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001085 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001086 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001087 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001088 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001089
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001090 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001091 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001092 for sub in node.subs:
1093 self.visit(sub)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001094 if aug_flag:
1095 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001096 if len(node.subs) > 1:
1097 self.emit('BUILD_TUPLE', len(node.subs))
1098 if node.flags == 'OP_APPLY':
1099 self.emit('BINARY_SUBSCR')
1100 elif node.flags == 'OP_ASSIGN':
1101 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001102 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001103 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001104
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001105 # binary ops
1106
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001107 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001108 self.visit(node.left)
1109 self.visit(node.right)
1110 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001111
1112 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001113 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001114
1115 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001116 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001117
1118 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001119 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001120
1121 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001122 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001123
Jeremy Hylton94afe322001-08-29 18:14:39 +00001124 def visitFloorDiv(self, node):
1125 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1126
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001127 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001128 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001129
Jeremy Hylton126960b2000-02-14 21:33:10 +00001130 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001131 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001132
1133 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001134 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001135
1136 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001137 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001138
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001139 # unary ops
1140
1141 def unaryOp(self, node, op):
1142 self.visit(node.expr)
1143 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001144
Jeremy Hylton126960b2000-02-14 21:33:10 +00001145 def visitInvert(self, node):
1146 return self.unaryOp(node, 'UNARY_INVERT')
1147
Jeremy Hylton40245602000-02-08 21:15:48 +00001148 def visitUnarySub(self, node):
1149 return self.unaryOp(node, 'UNARY_NEGATIVE')
1150
1151 def visitUnaryAdd(self, node):
1152 return self.unaryOp(node, 'UNARY_POSITIVE')
1153
1154 def visitUnaryInvert(self, node):
1155 return self.unaryOp(node, 'UNARY_INVERT')
1156
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001157 def visitNot(self, node):
1158 return self.unaryOp(node, 'UNARY_NOT')
1159
Jeremy Hylton40245602000-02-08 21:15:48 +00001160 def visitBackquote(self, node):
1161 return self.unaryOp(node, 'UNARY_CONVERT')
1162
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001163 # bit ops
1164
Jeremy Hyltona5058122000-02-14 14:14:29 +00001165 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001166 self.visit(nodes[0])
1167 for node in nodes[1:]:
1168 self.visit(node)
1169 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001170
1171 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001172 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001173
1174 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001175 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001176
1177 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001178 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001179
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001180 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001181
Jeremy Hyltona5058122000-02-14 14:14:29 +00001182 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001183 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001184
Jeremy Hylton40245602000-02-08 21:15:48 +00001185 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001186 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001187 for elt in node.nodes:
1188 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001189 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001190
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001191 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001192 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001193 for elt in node.nodes:
1194 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001195 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001196
1197 def visitSliceobj(self, node):
1198 for child in node.nodes:
1199 self.visit(child)
1200 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001201
Jeremy Hyltona5058122000-02-14 14:14:29 +00001202 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001203 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001204 self.emit('BUILD_MAP', 0)
1205 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001206 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001207 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001208 self.visit(v)
1209 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001210 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001211
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001212class NestedScopeMixin:
1213 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001214 def initClass(self):
1215 self.__class__.NameFinder = LocalNameFinder
1216 self.__class__.FunctionGen = FunctionCodeGenerator
1217 self.__class__.ClassGen = ClassCodeGenerator
1218
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001219class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001220 __super_init = CodeGenerator.__init__
1221
1222 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001223
Jeremy Hylton37c93512001-09-17 18:03:55 +00001224 def __init__(self, tree):
1225 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001226 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001227 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001228 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001229
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001230 def get_module(self):
1231 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001232
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001233class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1234 __super_init = CodeGenerator.__init__
1235
1236 scopes = None
1237 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001238
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001239 def __init__(self, tree):
1240 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1241 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001242 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001243
1244 def get_module(self):
1245 return self
1246
1247class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1248
1249 __super_init = CodeGenerator.__init__
1250
1251 scopes = None
1252 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001253
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001254 def __init__(self, tree):
1255 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1256 self.__super_init()
1257 self.set_lineno(tree)
1258 walk(tree, self)
1259 self.emit('RETURN_VALUE')
1260
1261 def get_module(self):
1262 return self
Tim Peterse4418602002-02-16 07:34:19 +00001263
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001264 def visitDiscard(self, node):
1265 # XXX Discard means it's an expression. Perhaps this is a bad
1266 # name.
1267 self.visit(node.expr)
1268 self.emit('PRINT_EXPR')
1269
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001270class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001271 optimized = 1
1272 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001273
Jeremy Hylton37c93512001-09-17 18:03:55 +00001274 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001275 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001276 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001277 if isLambda:
1278 klass = FunctionCodeGenerator
1279 name = "<lambda.%d>" % klass.lambdaCount
1280 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001281 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001282 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001283
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001284 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001285 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1286 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001287 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001288 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001289
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001290 if not isLambda and func.doc:
1291 self.setDocstring(func.doc)
1292
Jeremy Hylton2afff322001-08-27 21:51:52 +00001293 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001294 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001295 if func.varargs:
1296 self.graph.setFlag(CO_VARARGS)
1297 if func.kwargs:
1298 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001299 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001300 if hasTupleArg:
1301 self.generateArgUnpack(func.argnames)
1302
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001303 def get_module(self):
1304 return self.module
1305
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001306 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001307 self.graph.startExitBlock()
1308 if not self.isLambda:
1309 self.emit('LOAD_CONST', None)
1310 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001311
1312 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001313 for i in range(len(args)):
1314 arg = args[i]
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001315 if type(arg) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001316 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001317 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001318
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001319 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001320 if VERSION > 1:
1321 self.emit('UNPACK_SEQUENCE', len(tup))
1322 else:
1323 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001324 for elt in tup:
1325 if type(elt) == types.TupleType:
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001326 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001327 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001328 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001329
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001330 unpackTuple = unpackSequence
1331
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001332class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001333 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001334 super_init = CodeGenerator.__init__ # call be other init
1335 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001336
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001337 __super_init = AbstractFunctionCode.__init__
1338
Jeremy Hylton37c93512001-09-17 18:03:55 +00001339 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001340 self.scopes = scopes
1341 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001342 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001343 self.graph.setFreeVars(self.scope.get_free_vars())
1344 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001345 if self.scope.generator is not None:
1346 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001347
Raymond Hettinger354433a2004-05-19 08:20:33 +00001348class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1349 CodeGenerator):
1350 super_init = CodeGenerator.__init__ # call be other init
1351 scopes = None
1352
1353 __super_init = AbstractFunctionCode.__init__
1354
1355 def __init__(self, gexp, scopes, class_name, mod):
1356 self.scopes = scopes
1357 self.scope = scopes[gexp]
1358 self.__super_init(gexp, scopes, 1, class_name, mod)
1359 self.graph.setFreeVars(self.scope.get_free_vars())
1360 self.graph.setCellVars(self.scope.get_cell_vars())
1361 self.graph.setFlag(CO_GENERATOR)
1362
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001363class AbstractClassCode:
1364
Jeremy Hylton37c93512001-09-17 18:03:55 +00001365 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001366 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001367 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001368 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001369 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001370 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001371 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001372 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001373 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001374 if klass.doc:
1375 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001376
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001377 def get_module(self):
1378 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001379
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001380 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001381 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001382 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001383 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001384
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001385class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001386 super_init = CodeGenerator.__init__
1387 scopes = None
1388
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001389 __super_init = AbstractClassCode.__init__
1390
Jeremy Hylton37c93512001-09-17 18:03:55 +00001391 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001392 self.scopes = scopes
1393 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001394 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001395 self.graph.setFreeVars(self.scope.get_free_vars())
1396 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001397 self.set_lineno(klass)
1398 self.emit("LOAD_GLOBAL", "__name__")
1399 self.storeName("__module__")
1400 if klass.doc:
1401 self.emit("LOAD_CONST", klass.doc)
1402 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001403
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001404def generateArgList(arglist):
1405 """Generate an arg list marking TupleArgs"""
1406 args = []
1407 extra = []
1408 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001409 for i in range(len(arglist)):
1410 elt = arglist[i]
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001411 if type(elt) == types.StringType:
1412 args.append(elt)
1413 elif type(elt) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001414 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001415 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001416 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001417 else:
1418 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001419 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001420
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001421def findOp(node):
1422 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1423 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001424 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001425 return v.op
1426
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001427class OpFinder:
1428 def __init__(self):
1429 self.op = None
1430 def visitAssName(self, node):
1431 if self.op is None:
1432 self.op = node.flags
1433 elif self.op != node.flags:
1434 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001435 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001436 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001437
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001438class Delegator:
1439 """Base class to support delegation for augmented assignment nodes
1440
1441 To generator code for augmented assignments, we use the following
1442 wrapper classes. In visitAugAssign, the left-hand expression node
1443 is visited twice. The first time the visit uses the normal method
1444 for that node . The second time the visit uses a different method
1445 that generates the appropriate code to perform the assignment.
1446 These delegator classes wrap the original AST nodes in order to
1447 support the variant visit methods.
1448 """
1449 def __init__(self, obj):
1450 self.obj = obj
1451
1452 def __getattr__(self, attr):
1453 return getattr(self.obj, attr)
1454
1455class AugGetattr(Delegator):
1456 pass
1457
1458class AugName(Delegator):
1459 pass
1460
1461class AugSlice(Delegator):
1462 pass
1463
1464class AugSubscript(Delegator):
1465 pass
1466
1467wrapper = {
1468 ast.Getattr: AugGetattr,
1469 ast.Name: AugName,
1470 ast.Slice: AugSlice,
1471 ast.Subscript: AugSubscript,
1472 }
1473
1474def wrap_aug(node):
1475 return wrapper[node.__class__](node)
1476
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001477if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001478 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001479 compileFile(file)