blob: e859ac517e2502dfcc594e0a07c97536e9579e0b [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:
370 for decorator in reversed(node.decorators.nodes):
371 self.visit(decorator)
372 ndecorators = len(node.decorators.nodes)
373 else:
374 ndecorators = 0
375
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))
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000392
393 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
710 end = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000711 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000712 # XXX __debug__ and AssertionError appear to be special cases
713 # -- they are always loaded as globals even if there are local
714 # names. I guess this is a sort of renaming op.
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000715 self.emit('LOAD_GLOBAL', '__debug__')
716 self.emit('JUMP_IF_FALSE', end)
717 self.nextBlock()
718 self.emit('POP_TOP')
719 self.visit(node.test)
720 self.emit('JUMP_IF_TRUE', end)
721 self.nextBlock()
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000722 self.emit('POP_TOP')
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000723 self.emit('LOAD_GLOBAL', 'AssertionError')
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000724 if node.fail:
725 self.visit(node.fail)
726 self.emit('RAISE_VARARGS', 2)
727 else:
728 self.emit('RAISE_VARARGS', 1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000729 self.nextBlock(end)
730 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000731
732 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000733 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000734 n = 0
735 if node.expr1:
736 self.visit(node.expr1)
737 n = n + 1
738 if node.expr2:
739 self.visit(node.expr2)
740 n = n + 1
741 if node.expr3:
742 self.visit(node.expr3)
743 n = n + 1
744 self.emit('RAISE_VARARGS', n)
745
746 def visitTryExcept(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000747 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000748 handlers = self.newBlock()
749 end = self.newBlock()
750 if node.else_:
751 lElse = self.newBlock()
752 else:
753 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000754 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000755 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000756 self.nextBlock(body)
757 self.setups.push((EXCEPT, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000758 self.visit(node.body)
759 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000760 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000761 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000762 self.startBlock(handlers)
Tim Peterse0c446b2001-10-18 21:57:37 +0000763
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000764 last = len(node.handlers) - 1
765 for i in range(len(node.handlers)):
766 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000767 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000768 if expr:
769 self.emit('DUP_TOP')
770 self.visit(expr)
771 self.emit('COMPARE_OP', 'exception match')
772 next = self.newBlock()
773 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000774 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000775 self.emit('POP_TOP')
776 self.emit('POP_TOP')
777 if target:
778 self.visit(target)
779 else:
780 self.emit('POP_TOP')
781 self.emit('POP_TOP')
782 self.visit(body)
783 self.emit('JUMP_FORWARD', end)
784 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000785 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000786 else:
787 self.nextBlock()
Jeremy Hyltonf3545752001-08-28 16:35:18 +0000788 if expr: # XXX
789 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000790 self.emit('END_FINALLY')
791 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000792 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000793 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000794 self.nextBlock(end)
Tim Peterse0c446b2001-10-18 21:57:37 +0000795
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000796 def visitTryFinally(self, node):
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000797 body = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000798 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000799 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 self.emit('SETUP_FINALLY', final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000801 self.nextBlock(body)
802 self.setups.push((TRY_FINALLY, body))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 self.visit(node.body)
804 self.emit('POP_BLOCK')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000805 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000806 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000807 self.nextBlock(final)
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000808 self.setups.push((END_FINALLY, final))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809 self.visit(node.final)
810 self.emit('END_FINALLY')
Jeremy Hyltone4685ec2001-08-29 22:30:09 +0000811 self.setups.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000812
813 # misc
814
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000815 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000816 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000817 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000818 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000819
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000820 def visitConst(self, node):
821 self.emit('LOAD_CONST', node.value)
822
823 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000824 self.emit('LOAD_CONST', node.name)
825 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000826
827 def visitGlobal(self, node):
828 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000829 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000830
831 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000832 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000833 self.loadName(node.name)
Tim Peterse0c446b2001-10-18 21:57:37 +0000834
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000835 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000836 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000837
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000838 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000839 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000840 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000841 if VERSION > 1:
842 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000843 self.emit('IMPORT_NAME', name)
Neal Norwitza312c3a2002-06-06 18:30:10 +0000844 mod = name.split(".")[0]
Michael W. Hudson896e5162003-06-27 12:32:39 +0000845 if alias:
846 self._resolveDots(name)
847 self.storeName(alias)
848 else:
849 self.storeName(mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000850
851 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000852 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000853 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000854 if VERSION > 1:
855 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000856 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000857 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000858 if VERSION > 1:
859 if name == '*':
860 self.namespace = 0
861 self.emit('IMPORT_STAR')
862 # There can only be one name w/ from ... import *
863 assert len(node.names) == 1
864 return
865 else:
866 self.emit('IMPORT_FROM', name)
867 self._resolveDots(name)
868 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000869 else:
870 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000871 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000872
Jeremy Hylton20516082000-09-01 20:33:26 +0000873 def _resolveDots(self, name):
Neal Norwitza312c3a2002-06-06 18:30:10 +0000874 elts = name.split(".")
Jeremy Hylton20516082000-09-01 20:33:26 +0000875 if len(elts) == 1:
876 return
877 for elt in elts[1:]:
878 self.emit('LOAD_ATTR', elt)
879
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000880 def visitGetattr(self, node):
881 self.visit(node.expr)
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000882 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000883
884 # next five implement assignments
885
886 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000887 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000888 self.visit(node.expr)
889 dups = len(node.nodes) - 1
890 for i in range(len(node.nodes)):
891 elt = node.nodes[i]
892 if i < dups:
893 self.emit('DUP_TOP')
894 if isinstance(elt, ast.Node):
895 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000896
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000897 def visitAssName(self, node):
898 if node.flags == 'OP_ASSIGN':
899 self.storeName(node.name)
900 elif node.flags == 'OP_DELETE':
Jeremy Hylton94afe322001-08-29 18:14:39 +0000901 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000902 self.delName(node.name)
903 else:
904 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000905
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000906 def visitAssAttr(self, node):
907 self.visit(node.expr)
908 if node.flags == 'OP_ASSIGN':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000909 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000910 elif node.flags == 'OP_DELETE':
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000911 self.emit('DELETE_ATTR', self.mangle(node.attrname))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000912 else:
913 print "warning: unexpected flags:", node.flags
914 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000915
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000916 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000917 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000918 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000919 for child in node.nodes:
920 self.visit(child)
921
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000922 if VERSION > 1:
923 visitAssTuple = _visitAssSequence
924 visitAssList = _visitAssSequence
925 else:
926 def visitAssTuple(self, node):
927 self._visitAssSequence(node, 'UNPACK_TUPLE')
928
929 def visitAssList(self, node):
930 self._visitAssSequence(node, 'UNPACK_LIST')
931
932 # augmented assignment
933
934 def visitAugAssign(self, node):
Jeremy Hylton80ea40d2001-08-27 21:58:09 +0000935 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000936 aug_node = wrap_aug(node.node)
937 self.visit(aug_node, "load")
938 self.visit(node.expr)
939 self.emit(self._augmented_opcode[node.op])
940 self.visit(aug_node, "store")
941
942 _augmented_opcode = {
943 '+=' : 'INPLACE_ADD',
944 '-=' : 'INPLACE_SUBTRACT',
945 '*=' : 'INPLACE_MULTIPLY',
946 '/=' : 'INPLACE_DIVIDE',
Jeremy Hylton94afe322001-08-29 18:14:39 +0000947 '//=': 'INPLACE_FLOOR_DIVIDE',
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000948 '%=' : 'INPLACE_MODULO',
949 '**=': 'INPLACE_POWER',
950 '>>=': 'INPLACE_RSHIFT',
951 '<<=': 'INPLACE_LSHIFT',
952 '&=' : 'INPLACE_AND',
953 '^=' : 'INPLACE_XOR',
954 '|=' : 'INPLACE_OR',
955 }
956
957 def visitAugName(self, node, mode):
958 if mode == "load":
959 self.loadName(node.name)
960 elif mode == "store":
961 self.storeName(node.name)
962
963 def visitAugGetattr(self, node, mode):
964 if mode == "load":
965 self.visit(node.expr)
966 self.emit('DUP_TOP')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000967 self.emit('LOAD_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000968 elif mode == "store":
969 self.emit('ROT_TWO')
Jeremy Hyltonc59e2202001-08-27 22:56:16 +0000970 self.emit('STORE_ATTR', self.mangle(node.attrname))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000971
972 def visitAugSlice(self, node, mode):
973 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +0000974 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000975 elif mode == "store":
976 slice = 0
977 if node.lower:
978 slice = slice | 1
979 if node.upper:
980 slice = slice | 2
981 if slice == 0:
982 self.emit('ROT_TWO')
983 elif slice == 3:
984 self.emit('ROT_FOUR')
985 else:
986 self.emit('ROT_THREE')
987 self.emit('STORE_SLICE+%d' % slice)
988
989 def visitAugSubscript(self, node, mode):
990 if len(node.subs) > 1:
991 raise SyntaxError, "augmented assignment to tuple is not possible"
992 if mode == "load":
993 self.visitSubscript(node, 1)
994 elif mode == "store":
995 self.emit('ROT_THREE')
996 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000997
998 def visitExec(self, node):
999 self.visit(node.expr)
1000 if node.locals is None:
1001 self.emit('LOAD_CONST', None)
1002 else:
1003 self.visit(node.locals)
1004 if node.globals is None:
1005 self.emit('DUP_TOP')
1006 else:
1007 self.visit(node.globals)
1008 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +00001009
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001010 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +00001011 pos = 0
1012 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001013 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001014 self.visit(node.node)
1015 for arg in node.args:
1016 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +00001017 if isinstance(arg, ast.Keyword):
1018 kw = kw + 1
1019 else:
1020 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001021 if node.star_args is not None:
1022 self.visit(node.star_args)
1023 if node.dstar_args is not None:
1024 self.visit(node.dstar_args)
1025 have_star = node.star_args is not None
1026 have_dstar = node.dstar_args is not None
1027 opcode = callfunc_opcode_info[have_star, have_dstar]
1028 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001029
Jeremy Hylton2afff322001-08-27 21:51:52 +00001030 def visitPrint(self, node, newline=0):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001031 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001032 if node.dest:
1033 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001034 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001035 if node.dest:
1036 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001037 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001038 if node.dest:
1039 self.emit('ROT_TWO')
1040 self.emit('PRINT_ITEM_TO')
1041 else:
1042 self.emit('PRINT_ITEM')
Jeremy Hylton2afff322001-08-27 21:51:52 +00001043 if node.dest and not newline:
1044 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001045
1046 def visitPrintnl(self, node):
Jeremy Hylton2afff322001-08-27 21:51:52 +00001047 self.visitPrint(node, newline=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001048 if node.dest:
1049 self.emit('PRINT_NEWLINE_TO')
1050 else:
1051 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001052
1053 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001054 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001055 self.visit(node.value)
1056 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +00001057
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001058 def visitYield(self, node):
1059 self.set_lineno(node)
1060 self.visit(node.value)
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001061 self.emit('YIELD_VALUE')
Jeremy Hylton1048aa92001-09-14 23:17:55 +00001062
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001063 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001064
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001065 def visitSlice(self, node, aug_flag=None):
1066 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001067 self.visit(node.expr)
1068 slice = 0
1069 if node.lower:
1070 self.visit(node.lower)
1071 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001072 if node.upper:
1073 self.visit(node.upper)
1074 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001075 if aug_flag:
1076 if slice == 0:
1077 self.emit('DUP_TOP')
1078 elif slice == 3:
1079 self.emit('DUP_TOPX', 3)
1080 else:
1081 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001082 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001083 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001084 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001085 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001086 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +00001087 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001088 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +00001089 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001090 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001091
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001092 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +00001093 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001094 for sub in node.subs:
1095 self.visit(sub)
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001096 if aug_flag:
1097 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001098 if len(node.subs) > 1:
1099 self.emit('BUILD_TUPLE', len(node.subs))
1100 if node.flags == 'OP_APPLY':
1101 self.emit('BINARY_SUBSCR')
1102 elif node.flags == 'OP_ASSIGN':
1103 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001104 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001105 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001106
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001107 # binary ops
1108
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001109 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001110 self.visit(node.left)
1111 self.visit(node.right)
1112 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001113
1114 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001115 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001116
1117 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001118 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001119
1120 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001121 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001122
1123 def visitDiv(self, node):
Jeremy Hyltonaee0bfe2001-09-17 16:41:02 +00001124 return self.binaryOp(node, self._div_op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001125
Jeremy Hylton94afe322001-08-29 18:14:39 +00001126 def visitFloorDiv(self, node):
1127 return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
1128
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001129 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001130 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001131
Jeremy Hylton126960b2000-02-14 21:33:10 +00001132 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001133 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001134
1135 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001136 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001137
1138 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001139 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +00001140
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001141 # unary ops
1142
1143 def unaryOp(self, node, op):
1144 self.visit(node.expr)
1145 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001146
Jeremy Hylton126960b2000-02-14 21:33:10 +00001147 def visitInvert(self, node):
1148 return self.unaryOp(node, 'UNARY_INVERT')
1149
Jeremy Hylton40245602000-02-08 21:15:48 +00001150 def visitUnarySub(self, node):
1151 return self.unaryOp(node, 'UNARY_NEGATIVE')
1152
1153 def visitUnaryAdd(self, node):
1154 return self.unaryOp(node, 'UNARY_POSITIVE')
1155
1156 def visitUnaryInvert(self, node):
1157 return self.unaryOp(node, 'UNARY_INVERT')
1158
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001159 def visitNot(self, node):
1160 return self.unaryOp(node, 'UNARY_NOT')
1161
Jeremy Hylton40245602000-02-08 21:15:48 +00001162 def visitBackquote(self, node):
1163 return self.unaryOp(node, 'UNARY_CONVERT')
1164
Jeremy Hylton7fab23e2000-03-06 19:10:54 +00001165 # bit ops
1166
Jeremy Hyltona5058122000-02-14 14:14:29 +00001167 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001168 self.visit(nodes[0])
1169 for node in nodes[1:]:
1170 self.visit(node)
1171 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001172
1173 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001174 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001175
1176 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001177 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001178
1179 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001180 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001181
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001182 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +00001183
Jeremy Hyltona5058122000-02-14 14:14:29 +00001184 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001185 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001186
Jeremy Hylton40245602000-02-08 21:15:48 +00001187 def visitTuple(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001188 self.set_lineno(node)
Jeremy Hylton40245602000-02-08 21:15:48 +00001189 for elt in node.nodes:
1190 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001191 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001192
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001193 def visitList(self, node):
Jeremy Hylton19367452001-08-29 20:57:43 +00001194 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001195 for elt in node.nodes:
1196 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +00001197 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001198
1199 def visitSliceobj(self, node):
1200 for child in node.nodes:
1201 self.visit(child)
1202 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +00001203
Jeremy Hyltona5058122000-02-14 14:14:29 +00001204 def visitDict(self, node):
Jeremy Hylton18565412002-12-31 18:26:17 +00001205 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001206 self.emit('BUILD_MAP', 0)
1207 for k, v in node.items:
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001208 self.emit('DUP_TOP')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001209 self.visit(k)
Gustavo Niemeyer78429a62002-12-16 13:54:02 +00001210 self.visit(v)
1211 self.emit('ROT_THREE')
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001212 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +00001213
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001214class NestedScopeMixin:
1215 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001216 def initClass(self):
1217 self.__class__.NameFinder = LocalNameFinder
1218 self.__class__.FunctionGen = FunctionCodeGenerator
1219 self.__class__.ClassGen = ClassCodeGenerator
1220
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001221class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001222 __super_init = CodeGenerator.__init__
1223
1224 scopes = None
Tim Peterse0c446b2001-10-18 21:57:37 +00001225
Jeremy Hylton37c93512001-09-17 18:03:55 +00001226 def __init__(self, tree):
1227 self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001228 self.futures = future.find_futures(tree)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001229 self.__super_init()
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001230 walk(tree, self)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001231
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001232 def get_module(self):
1233 return self
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001234
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001235class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
1236 __super_init = CodeGenerator.__init__
1237
1238 scopes = None
1239 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001240
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001241 def __init__(self, tree):
1242 self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
1243 self.__super_init()
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001244 walk(tree, self)
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001245
1246 def get_module(self):
1247 return self
1248
1249class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
1250
1251 __super_init = CodeGenerator.__init__
1252
1253 scopes = None
1254 futures = ()
Tim Peterse0c446b2001-10-18 21:57:37 +00001255
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001256 def __init__(self, tree):
1257 self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
1258 self.__super_init()
1259 self.set_lineno(tree)
1260 walk(tree, self)
1261 self.emit('RETURN_VALUE')
1262
1263 def get_module(self):
1264 return self
Tim Peterse4418602002-02-16 07:34:19 +00001265
Jeremy Hylton9dca3642001-09-17 21:02:51 +00001266 def visitDiscard(self, node):
1267 # XXX Discard means it's an expression. Perhaps this is a bad
1268 # name.
1269 self.visit(node.expr)
1270 self.emit('PRINT_EXPR')
1271
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001272class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001273 optimized = 1
1274 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001275
Jeremy Hylton37c93512001-09-17 18:03:55 +00001276 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001277 self.class_name = class_name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001278 self.module = mod
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001279 if isLambda:
1280 klass = FunctionCodeGenerator
1281 name = "<lambda.%d>" % klass.lambdaCount
1282 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001283 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001284 name = func.name
Raymond Hettinger354433a2004-05-19 08:20:33 +00001285
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001286 args, hasTupleArg = generateArgList(func.argnames)
Tim Peterse0c446b2001-10-18 21:57:37 +00001287 self.graph = pyassem.PyFlowGraph(name, func.filename, args,
1288 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001289 self.isLambda = isLambda
Jeremy Hylton37c93512001-09-17 18:03:55 +00001290 self.super_init()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001291
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001292 if not isLambda and func.doc:
1293 self.setDocstring(func.doc)
1294
Jeremy Hylton2afff322001-08-27 21:51:52 +00001295 lnf = walk(func.code, self.NameFinder(args), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001296 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001297 if func.varargs:
1298 self.graph.setFlag(CO_VARARGS)
1299 if func.kwargs:
1300 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001301 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001302 if hasTupleArg:
1303 self.generateArgUnpack(func.argnames)
1304
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001305 def get_module(self):
1306 return self.module
1307
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001308 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001309 self.graph.startExitBlock()
1310 if not self.isLambda:
1311 self.emit('LOAD_CONST', None)
1312 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001313
1314 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001315 for i in range(len(args)):
1316 arg = args[i]
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001317 if type(arg) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001318 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001319 self.unpackSequence(arg)
Tim Peterse0c446b2001-10-18 21:57:37 +00001320
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001321 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001322 if VERSION > 1:
1323 self.emit('UNPACK_SEQUENCE', len(tup))
1324 else:
1325 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001326 for elt in tup:
1327 if type(elt) == types.TupleType:
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001328 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001329 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001330 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001331
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001332 unpackTuple = unpackSequence
1333
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001334class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
Tim Peterse0c446b2001-10-18 21:57:37 +00001335 CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001336 super_init = CodeGenerator.__init__ # call be other init
1337 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001338
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001339 __super_init = AbstractFunctionCode.__init__
1340
Jeremy Hylton37c93512001-09-17 18:03:55 +00001341 def __init__(self, func, scopes, isLambda, class_name, mod):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001342 self.scopes = scopes
1343 self.scope = scopes[func]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001344 self.__super_init(func, scopes, isLambda, class_name, mod)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001345 self.graph.setFreeVars(self.scope.get_free_vars())
1346 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001347 if self.scope.generator is not None:
1348 self.graph.setFlag(CO_GENERATOR)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001349
Raymond Hettinger354433a2004-05-19 08:20:33 +00001350class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
1351 CodeGenerator):
1352 super_init = CodeGenerator.__init__ # call be other init
1353 scopes = None
1354
1355 __super_init = AbstractFunctionCode.__init__
1356
1357 def __init__(self, gexp, scopes, class_name, mod):
1358 self.scopes = scopes
1359 self.scope = scopes[gexp]
1360 self.__super_init(gexp, scopes, 1, class_name, mod)
1361 self.graph.setFreeVars(self.scope.get_free_vars())
1362 self.graph.setCellVars(self.scope.get_cell_vars())
1363 self.graph.setFlag(CO_GENERATOR)
1364
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001365class AbstractClassCode:
1366
Jeremy Hylton37c93512001-09-17 18:03:55 +00001367 def __init__(self, klass, scopes, module):
Jeremy Hyltonc59e2202001-08-27 22:56:16 +00001368 self.class_name = klass.name
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001369 self.module = module
Jeremy Hylton37c93512001-09-17 18:03:55 +00001370 self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
Jeremy Hylton94afe322001-08-29 18:14:39 +00001371 optimized=0, klass=1)
Jeremy Hylton37c93512001-09-17 18:03:55 +00001372 self.super_init()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001373 lnf = walk(klass.code, self.NameFinder(), verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001374 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001375 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001376 if klass.doc:
1377 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001378
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001379 def get_module(self):
1380 return self.module
Jeremy Hylton660cc772001-04-12 06:49:00 +00001381
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001382 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001383 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001384 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001385 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001386
Jeremy Hylton1e99a772001-09-14 22:49:08 +00001387class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001388 super_init = CodeGenerator.__init__
1389 scopes = None
1390
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001391 __super_init = AbstractClassCode.__init__
1392
Jeremy Hylton37c93512001-09-17 18:03:55 +00001393 def __init__(self, klass, scopes, module):
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001394 self.scopes = scopes
1395 self.scope = scopes[klass]
Jeremy Hylton37c93512001-09-17 18:03:55 +00001396 self.__super_init(klass, scopes, module)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001397 self.graph.setFreeVars(self.scope.get_free_vars())
1398 self.graph.setCellVars(self.scope.get_cell_vars())
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +00001399 self.set_lineno(klass)
1400 self.emit("LOAD_GLOBAL", "__name__")
1401 self.storeName("__module__")
1402 if klass.doc:
1403 self.emit("LOAD_CONST", klass.doc)
1404 self.storeName('__doc__')
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001405
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001406def generateArgList(arglist):
1407 """Generate an arg list marking TupleArgs"""
1408 args = []
1409 extra = []
1410 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001411 for i in range(len(arglist)):
1412 elt = arglist[i]
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001413 if type(elt) == types.StringType:
1414 args.append(elt)
1415 elif type(elt) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001416 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001417 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001418 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001419 else:
1420 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001421 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001422
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001423def findOp(node):
1424 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1425 v = OpFinder()
Jeremy Hylton2afff322001-08-27 21:51:52 +00001426 walk(node, v, verbose=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001427 return v.op
1428
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001429class OpFinder:
1430 def __init__(self):
1431 self.op = None
1432 def visitAssName(self, node):
1433 if self.op is None:
1434 self.op = node.flags
1435 elif self.op != node.flags:
1436 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001437 visitAssAttr = visitAssName
Jeremy Hylton6383c2d2001-11-09 16:24:34 +00001438 visitSubscript = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001439
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001440class Delegator:
1441 """Base class to support delegation for augmented assignment nodes
1442
1443 To generator code for augmented assignments, we use the following
1444 wrapper classes. In visitAugAssign, the left-hand expression node
1445 is visited twice. The first time the visit uses the normal method
1446 for that node . The second time the visit uses a different method
1447 that generates the appropriate code to perform the assignment.
1448 These delegator classes wrap the original AST nodes in order to
1449 support the variant visit methods.
1450 """
1451 def __init__(self, obj):
1452 self.obj = obj
1453
1454 def __getattr__(self, attr):
1455 return getattr(self.obj, attr)
1456
1457class AugGetattr(Delegator):
1458 pass
1459
1460class AugName(Delegator):
1461 pass
1462
1463class AugSlice(Delegator):
1464 pass
1465
1466class AugSubscript(Delegator):
1467 pass
1468
1469wrapper = {
1470 ast.Getattr: AugGetattr,
1471 ast.Name: AugName,
1472 ast.Slice: AugSlice,
1473 ast.Subscript: AugSubscript,
1474 }
1475
1476def wrap_aug(node):
1477 return wrapper[node.__class__](node)
1478
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001479if __name__ == "__main__":
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001480 for file in sys.argv[1:]:
Jeremy Hylton57911ae2001-11-27 23:35:10 +00001481 compileFile(file)