blob: 9f580675562092247a040ccf96c1a8b494ead16e [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 stat
Jeremy Hylton20516082000-09-01 20:33:26 +00005import string
Jeremy Hylton53187f32000-02-08 19:01:29 +00006import struct
Jeremy Hylton9c048f92000-10-13 21:58:13 +00007import sys
Jeremy Hyltonad9a86f2000-02-16 00:55:44 +00008import types
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00009from cStringIO import StringIO
10
11from compiler import ast, parse, walk
Jeremy Hylton364f9b92001-04-12 06:40:42 +000012from compiler import pyassem, misc, future, symbols
13from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
14from compiler.pyassem import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
15 CO_NESTED, TupleArg
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000016
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 Hylton9c048f92000-10-13 21:58:13 +000031def compile(filename, display=0):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000032 f = open(filename)
33 buf = f.read()
34 f.close()
35 mod = Module(buf, filename)
Jeremy Hylton9c048f92000-10-13 21:58:13 +000036 mod.compile(display)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000037 f = open(filename + "c", "wb")
38 mod.dump(f)
39 f.close()
40
41class Module:
42 def __init__(self, source, filename):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000043 self.filename = filename
44 self.source = source
45 self.code = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000046
Jeremy Hylton9c048f92000-10-13 21:58:13 +000047 def compile(self, display=0):
Jeremy Hylton80e29bd2001-04-09 04:28:48 +000048 tree = parse(self.source)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000049 root, filename = os.path.split(self.filename)
Jeremy Hylton84ec1f92001-04-11 16:43:13 +000050 if "nested_scopes" in future.find_futures(tree):
Jeremy Hylton364f9b92001-04-12 06:40:42 +000051 gen = NestedScopeModuleCodeGenerator(filename)
Jeremy Hylton84ec1f92001-04-11 16:43:13 +000052 else:
53 gen = ModuleCodeGenerator(filename)
Jeremy Hylton80e29bd2001-04-09 04:28:48 +000054 walk(tree, gen, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +000055 if display:
56 import pprint
Jeremy Hylton80e29bd2001-04-09 04:28:48 +000057 print pprint.pprint(tree)
Thomas Wouters46cc7c02000-08-12 20:32:46 +000058 self.code = gen.getCode()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000059
60 def dump(self, f):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000061 f.write(self.getPycHeader())
62 marshal.dump(self.code, f)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000063
Jeremy Hylton9c048f92000-10-13 21:58:13 +000064 MAGIC = imp.get_magic()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +000065
66 def getPycHeader(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +000067 # compile.c uses marshal to write a long directly, with
68 # calling the interface that would also generate a 1-byte code
69 # to indicate the type of the value. simplest way to get the
70 # same effect is to call marshal and then skip the code.
Thomas Wouters46cc7c02000-08-12 20:32:46 +000071 mtime = os.stat(self.filename)[stat.ST_MTIME]
72 mtime = struct.pack('i', mtime)
Jeremy Hylton9c048f92000-10-13 21:58:13 +000073 return self.MAGIC + mtime
Jeremy Hylton8b6323d2000-02-04 00:28:21 +000074
Jeremy Hylton364f9b92001-04-12 06:40:42 +000075class LocalNameFinder:
76 """Find local names in scope"""
77 def __init__(self, names=()):
78 self.names = misc.Set()
79 self.globals = misc.Set()
80 for name in names:
81 self.names.add(name)
82
83 # XXX list comprehensions and for loops
84
85 def getLocals(self):
86 for elt in self.globals.elements():
87 if self.names.has_elt(elt):
88 self.names.remove(elt)
89 return self.names
90
91 def visitDict(self, node):
92 pass
93
94 def visitGlobal(self, node):
95 for name in node.names:
96 self.globals.add(name)
97
98 def visitFunction(self, node):
99 self.names.add(node.name)
100
101 def visitLambda(self, node):
102 pass
103
104 def visitImport(self, node):
105 for name, alias in node.names:
106 self.names.add(alias or name)
107
108 def visitFrom(self, node):
109 for name, alias in node.names:
110 self.names.add(alias or name)
111
112 def visitClass(self, node):
113 self.names.add(node.name)
114
115 def visitAssName(self, node):
116 self.names.add(node.name)
117
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000118class CodeGenerator:
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000119 """Defines basic code generator for Python bytecode
120
121 This class is an abstract base class. Concrete subclasses must
122 define an __init__() that defines self.graph and then calls the
123 __init__() defined in this class.
124
125 The concrete class must also define the class attributes
126 NameFinder, FunctionGen, and ClassGen. These attributes can be
127 defined in the initClass() method, which is a hook for
128 initializing these methods after all the classes have been
129 defined.
130 """
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000131
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000132 optimized = 0 # is namespace access optimized?
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000133 __initialized = None
Jeremy Hylton3050d512000-02-12 00:12:38 +0000134
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000135 def __init__(self, filename):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000136 if self.__initialized is None:
137 self.initClass()
138 self.__class__.__initialized = 1
139 self.checkClass()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000140 self.filename = filename
141 self.locals = misc.Stack()
142 self.loops = misc.Stack()
143 self.curStack = 0
144 self.maxStack = 0
Jeremy Hylton92f39722000-09-01 20:47:37 +0000145 self.last_lineno = None
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000146 self._setupGraphDelegation()
Jeremy Hylton53187f32000-02-08 19:01:29 +0000147
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000148 def initClass(self):
149 """This method is called once for each class"""
150
151 def checkClass(self):
152 """Verify that class is constructed correctly"""
153 try:
154 assert hasattr(self, 'graph')
155 assert getattr(self, 'NameFinder')
156 assert getattr(self, 'FunctionGen')
157 assert getattr(self, 'ClassGen')
158 except AssertionError, msg:
159 intro = "Bad class construction for %s" % self.__class__.__name__
160 raise AssertionError, intro
161
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000162 def _setupGraphDelegation(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000163 self.emit = self.graph.emit
164 self.newBlock = self.graph.newBlock
165 self.startBlock = self.graph.startBlock
166 self.nextBlock = self.graph.nextBlock
167 self.setDocstring = self.graph.setDocstring
Jeremy Hyltona5058122000-02-14 14:14:29 +0000168
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000169 def getCode(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000170 """Return a code object"""
171 return self.graph.getCode()
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000172
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000173 # Next five methods handle name access
Jeremy Hylton53187f32000-02-08 19:01:29 +0000174
Jeremy Hylton40245602000-02-08 21:15:48 +0000175 def isLocalName(self, name):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000176 return self.locals.top().has_elt(name)
Jeremy Hylton40245602000-02-08 21:15:48 +0000177
Jeremy Hylton3e0910c2000-02-10 17:20:39 +0000178 def storeName(self, name):
179 self._nameOp('STORE', name)
180
181 def loadName(self, name):
182 self._nameOp('LOAD', name)
183
184 def delName(self, name):
185 self._nameOp('DELETE', name)
186
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000187 def _nameOp(self, prefix, name):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000188 if not self.optimized:
189 self.emit(prefix + '_NAME', name)
190 return
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000191 if self.isLocalName(name):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000192 self.emit(prefix + '_FAST', name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000193 else:
194 self.emit(prefix + '_GLOBAL', name)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000195
Jeremy Hylton13d70942001-04-12 21:04:43 +0000196 def _implicitNameOp(self, prefix, name):
197 """Emit name ops for names generated implicitly by for loops
198
199 The interpreter generates names that start with a period or
200 dollar sign. The symbol table ignores these names because
201 they aren't present in the program text.
202 """
203 if self.optimized:
204 self.emit(prefix + '_FAST', name)
205 else:
206 self.emit(prefix + '_NAME', name)
207
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000208 def set_lineno(self, node, force=0):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000209 """Emit SET_LINENO if node has lineno attribute and it is
210 different than the last lineno emitted.
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000211
212 Returns true if SET_LINENO was emitted.
213
214 There are no rules for when an AST node should have a lineno
215 attribute. The transformer and AST code need to be reviewed
216 and a consistent policy implemented and documented. Until
217 then, this method works around missing line numbers.
218 """
219 lineno = getattr(node, 'lineno', None)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000220 if lineno is not None and (lineno != self.last_lineno
221 or force):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000222 self.emit('SET_LINENO', lineno)
Jeremy Hylton92f39722000-09-01 20:47:37 +0000223 self.last_lineno = lineno
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000224 return 1
225 return 0
226
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000227 # The first few visitor methods handle nodes that generator new
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000228 # code objects. They use class attributes to determine what
229 # specialized code generators to use.
230
231 NameFinder = LocalNameFinder
232 FunctionGen = None
233 ClassGen = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000234
235 def visitModule(self, node):
Jeremy Hylton13d70942001-04-12 21:04:43 +0000236 self.emit('SET_LINENO', 0)
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000237 lnf = walk(node.node, self.NameFinder(), 0)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000238 self.locals.push(lnf.getLocals())
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000239 if node.doc:
240 self.fixDocstring(node.node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000241 self.visit(node.node)
242 self.emit('LOAD_CONST', None)
243 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000244
245 def visitFunction(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000246 self._visitFuncOrLambda(node, isLambda=0)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000247 if node.doc:
248 self.setDocstring(node.doc)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000249 self.storeName(node.name)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000250
251 def visitLambda(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000252 self._visitFuncOrLambda(node, isLambda=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000253
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000254 def _visitFuncOrLambda(self, node, isLambda=0):
255 gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000256 walk(node.code, gen)
257 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000258 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000259 for default in node.defaults:
260 self.visit(default)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000261 self.emit('LOAD_CONST', gen)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000262 self.emit('MAKE_FUNCTION', len(node.defaults))
263
264 def visitClass(self, node):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000265 gen = self.ClassGen(node, self.filename, self.scopes)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000266 if node.doc:
267 self.fixDocstring(node.code)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000268 walk(node.code, gen)
269 gen.finish()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000270 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000271 self.emit('LOAD_CONST', node.name)
272 for base in node.bases:
273 self.visit(base)
274 self.emit('BUILD_TUPLE', len(node.bases))
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000275 self.emit('LOAD_CONST', gen)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000276 self.emit('MAKE_FUNCTION', 0)
277 self.emit('CALL_FUNCTION', 0)
278 self.emit('BUILD_CLASS')
279 self.storeName(node.name)
280
Jeremy Hylton9ab019b2001-04-11 16:24:30 +0000281 def fixDocstring(self, node):
282 """Rewrite the ast for a class with a docstring.
283
284 The AST includes a Discard(Const(docstring)) node. Replace
285 this with an Assign([AssName('__doc__', ...])
286 """
287 assert isinstance(node, ast.Stmt)
288 stmts = node.nodes
289 discard = stmts[0]
290 assert isinstance(discard, ast.Discard)
291 stmts[0] = ast.Assign([ast.AssName('__doc__', 'OP_ASSIGN')],
292 discard.expr)
293 stmts[0].lineno = discard.lineno
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000294 # The rest are standard visitor methods
295
296 # The next few implement control-flow statements
297
298 def visitIf(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000299 end = self.newBlock()
300 numtests = len(node.tests)
301 for i in range(numtests):
302 test, suite = node.tests[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000303 self.set_lineno(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000304 self.visit(test)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000305 nextTest = self.newBlock()
306 self.emit('JUMP_IF_FALSE', nextTest)
307 self.nextBlock()
308 self.emit('POP_TOP')
309 self.visit(suite)
310 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000311 self.startBlock(nextTest)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000312 self.emit('POP_TOP')
313 if node.else_:
314 self.visit(node.else_)
315 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000316
317 def visitWhile(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000318 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000319
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000320 loop = self.newBlock()
321 else_ = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000322
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000323 after = self.newBlock()
324 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000325
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000326 self.nextBlock(loop)
327 self.loops.push(loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000328
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000329 self.set_lineno(node, force=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000330 self.visit(node.test)
331 self.emit('JUMP_IF_FALSE', else_ or after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000332
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000333 self.nextBlock()
334 self.emit('POP_TOP')
335 self.visit(node.body)
336 self.emit('JUMP_ABSOLUTE', loop)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000337
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000338 self.startBlock(else_) # or just the POPs if not else clause
339 self.emit('POP_TOP')
340 self.emit('POP_BLOCK')
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000341 self.loops.pop()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000342 if node.else_:
343 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000344 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000345
346 def visitFor(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000347 start = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000348 anchor = self.newBlock()
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000349 after = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000350 self.loops.push(start)
351
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000352 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000353 self.emit('SETUP_LOOP', after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000354 self.visit(node.list)
355 self.visit(ast.Const(0))
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000356 self.nextBlock(start)
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000357 self.set_lineno(node, force=1)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000358 self.emit('FOR_LOOP', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000359 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000360 self.visit(node.assign)
361 self.visit(node.body)
362 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000363 self.startBlock(anchor)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000364 self.emit('POP_BLOCK')
Jeremy Hyltonbb0bae62001-04-12 21:54:41 +0000365 self.loops.pop()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000366 if node.else_:
367 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000368 self.nextBlock(after)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000369
370 def visitBreak(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000371 if not self.loops:
372 raise SyntaxError, "'break' outside loop (%s, %d)" % \
373 (self.filename, node.lineno)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000374 self.set_lineno(node)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000375 self.emit('BREAK_LOOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000376
377 def visitContinue(self, node):
378 if not self.loops:
379 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000380 (self.filename, node.lineno)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000381 l = self.loops.top()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000382 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000383 self.emit('JUMP_ABSOLUTE', l)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000384 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000385
386 def visitTest(self, node, jump):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000387 end = self.newBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000388 for child in node.nodes[:-1]:
389 self.visit(child)
390 self.emit(jump, end)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000391 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000392 self.emit('POP_TOP')
393 self.visit(node.nodes[-1])
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000394 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000395
396 def visitAnd(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000397 self.visitTest(node, 'JUMP_IF_FALSE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000398
399 def visitOr(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000400 self.visitTest(node, 'JUMP_IF_TRUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000401
402 def visitCompare(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000403 self.visit(node.expr)
404 cleanup = self.newBlock()
405 for op, code in node.ops[:-1]:
406 self.visit(code)
407 self.emit('DUP_TOP')
408 self.emit('ROT_THREE')
409 self.emit('COMPARE_OP', op)
410 self.emit('JUMP_IF_FALSE', cleanup)
411 self.nextBlock()
412 self.emit('POP_TOP')
413 # now do the last comparison
414 if node.ops:
415 op, code = node.ops[-1]
416 self.visit(code)
417 self.emit('COMPARE_OP', op)
418 if len(node.ops) > 1:
419 end = self.newBlock()
420 self.emit('JUMP_FORWARD', end)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000421 self.startBlock(cleanup)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000422 self.emit('ROT_TWO')
423 self.emit('POP_TOP')
424 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000425
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000426 # list comprehensions
427 __list_count = 0
428
429 def visitListComp(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000430 self.set_lineno(node)
431 # setup list
432 append = "$append%d" % self.__list_count
433 self.__list_count = self.__list_count + 1
434 self.emit('BUILD_LIST', 0)
435 self.emit('DUP_TOP')
436 self.emit('LOAD_ATTR', 'append')
Jeremy Hylton13d70942001-04-12 21:04:43 +0000437 self._implicitNameOp('STORE', append)
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000438
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000439 stack = []
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000440 for i, for_ in zip(range(len(node.quals)), node.quals):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000441 start, anchor = self.visit(for_)
442 cont = None
443 for if_ in for_.ifs:
444 if cont is None:
445 cont = self.newBlock()
446 self.visit(if_, cont)
447 stack.insert(0, (start, cont, anchor))
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000448
Jeremy Hylton13d70942001-04-12 21:04:43 +0000449 self._implicitNameOp('LOAD', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000450 self.visit(node.expr)
451 self.emit('CALL_FUNCTION', 1)
452 self.emit('POP_TOP')
453
454 for start, cont, anchor in stack:
455 if cont:
456 skip_one = self.newBlock()
457 self.emit('JUMP_FORWARD', skip_one)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000458 self.startBlock(cont)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000459 self.emit('POP_TOP')
460 self.nextBlock(skip_one)
461 self.emit('JUMP_ABSOLUTE', start)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000462 self.startBlock(anchor)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000463 self._implicitNameOp('DELETE', append)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000464
465 self.__list_count = self.__list_count - 1
466
467 def visitListCompFor(self, node):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000468 start = self.newBlock()
469 anchor = self.newBlock()
470
471 self.visit(node.list)
472 self.visit(ast.Const(0))
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000473 self.nextBlock(start)
Jeremy Hylton13d70942001-04-12 21:04:43 +0000474 self.emit('SET_LINENO', node.lineno)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000475 self.emit('FOR_LOOP', anchor)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000476 self.nextBlock()
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000477 self.visit(node.assign)
478 return start, anchor
479
480 def visitListCompIf(self, node, branch):
Jeremy Hylton542b11a2001-04-12 20:21:39 +0000481 self.set_lineno(node, force=1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000482 self.visit(node.test)
483 self.emit('JUMP_IF_FALSE', branch)
484 self.newBlock()
485 self.emit('POP_TOP')
486
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000487 # exception related
488
489 def visitAssert(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000490 # XXX would be interesting to implement this via a
491 # transformation of the AST before this stage
492 end = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000493 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000494 # XXX __debug__ and AssertionError appear to be special cases
495 # -- they are always loaded as globals even if there are local
496 # names. I guess this is a sort of renaming op.
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000497 self.emit('LOAD_GLOBAL', '__debug__')
498 self.emit('JUMP_IF_FALSE', end)
499 self.nextBlock()
500 self.emit('POP_TOP')
501 self.visit(node.test)
502 self.emit('JUMP_IF_TRUE', end)
503 self.nextBlock()
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000504 self.emit('POP_TOP')
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000505 self.emit('LOAD_GLOBAL', 'AssertionError')
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000506 if node.fail:
507 self.visit(node.fail)
508 self.emit('RAISE_VARARGS', 2)
509 else:
510 self.emit('RAISE_VARARGS', 1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000511 self.nextBlock(end)
512 self.emit('POP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000513
514 def visitRaise(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000515 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000516 n = 0
517 if node.expr1:
518 self.visit(node.expr1)
519 n = n + 1
520 if node.expr2:
521 self.visit(node.expr2)
522 n = n + 1
523 if node.expr3:
524 self.visit(node.expr3)
525 n = n + 1
526 self.emit('RAISE_VARARGS', n)
527
528 def visitTryExcept(self, node):
529 handlers = self.newBlock()
530 end = self.newBlock()
531 if node.else_:
532 lElse = self.newBlock()
533 else:
534 lElse = end
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000535 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000536 self.emit('SETUP_EXCEPT', handlers)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000537 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000538 self.visit(node.body)
539 self.emit('POP_BLOCK')
540 self.emit('JUMP_FORWARD', lElse)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000541 self.startBlock(handlers)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000542
543 last = len(node.handlers) - 1
544 for i in range(len(node.handlers)):
545 expr, target, body = node.handlers[i]
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000546 self.set_lineno(expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000547 if expr:
548 self.emit('DUP_TOP')
549 self.visit(expr)
550 self.emit('COMPARE_OP', 'exception match')
551 next = self.newBlock()
552 self.emit('JUMP_IF_FALSE', next)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000553 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000554 self.emit('POP_TOP')
555 self.emit('POP_TOP')
556 if target:
557 self.visit(target)
558 else:
559 self.emit('POP_TOP')
560 self.emit('POP_TOP')
561 self.visit(body)
562 self.emit('JUMP_FORWARD', end)
563 if expr:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000564 self.nextBlock(next)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000565 else:
566 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000567 self.emit('POP_TOP')
568 self.emit('END_FINALLY')
569 if node.else_:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000570 self.nextBlock(lElse)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000571 self.visit(node.else_)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000572 self.nextBlock(end)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000573
574 def visitTryFinally(self, node):
575 final = self.newBlock()
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000576 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000577 self.emit('SETUP_FINALLY', final)
Jeremy Hylton314e3fb2000-11-06 03:43:11 +0000578 self.nextBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000579 self.visit(node.body)
580 self.emit('POP_BLOCK')
581 self.emit('LOAD_CONST', None)
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000582 self.nextBlock(final)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000583 self.visit(node.final)
584 self.emit('END_FINALLY')
585
586 # misc
587
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000588 def visitDiscard(self, node):
Jeremy Hylton01d12932001-04-11 16:36:25 +0000589 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000590 self.visit(node.expr)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000591 self.emit('POP_TOP')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000592
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000593 def visitConst(self, node):
594 self.emit('LOAD_CONST', node.value)
595
596 def visitKeyword(self, node):
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000597 self.emit('LOAD_CONST', node.name)
598 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000599
600 def visitGlobal(self, node):
601 # no code to generate
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000602 pass
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000603
604 def visitName(self, node):
Jeremy Hylton92f39722000-09-01 20:47:37 +0000605 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000606 self.loadName(node.name)
607
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000608 def visitPass(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000609 self.set_lineno(node)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000610
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000611 def visitImport(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000612 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000613 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000614 if VERSION > 1:
615 self.emit('LOAD_CONST', None)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000616 self.emit('IMPORT_NAME', name)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000617 mod = string.split(name, ".")[0]
618 self.storeName(alias or mod)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000619
620 def visitFrom(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000621 self.set_lineno(node)
Jeremy Hylton20516082000-09-01 20:33:26 +0000622 fromlist = map(lambda (name, alias): name, node.names)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000623 if VERSION > 1:
624 self.emit('LOAD_CONST', tuple(fromlist))
Jeremy Hyltona5058122000-02-14 14:14:29 +0000625 self.emit('IMPORT_NAME', node.modname)
Jeremy Hylton20516082000-09-01 20:33:26 +0000626 for name, alias in node.names:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000627 if VERSION > 1:
628 if name == '*':
629 self.namespace = 0
630 self.emit('IMPORT_STAR')
631 # There can only be one name w/ from ... import *
632 assert len(node.names) == 1
633 return
634 else:
635 self.emit('IMPORT_FROM', name)
636 self._resolveDots(name)
637 self.storeName(alias or name)
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000638 else:
639 self.emit('IMPORT_FROM', name)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000640 self.emit('POP_TOP')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000641
Jeremy Hylton20516082000-09-01 20:33:26 +0000642 def _resolveDots(self, name):
643 elts = string.split(name, ".")
644 if len(elts) == 1:
645 return
646 for elt in elts[1:]:
647 self.emit('LOAD_ATTR', elt)
648
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000649 def visitGetattr(self, node):
650 self.visit(node.expr)
651 self.emit('LOAD_ATTR', node.attrname)
652
653 # next five implement assignments
654
655 def visitAssign(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000656 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000657 self.visit(node.expr)
658 dups = len(node.nodes) - 1
659 for i in range(len(node.nodes)):
660 elt = node.nodes[i]
661 if i < dups:
662 self.emit('DUP_TOP')
663 if isinstance(elt, ast.Node):
664 self.visit(elt)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000665
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000666 def visitAssName(self, node):
667 if node.flags == 'OP_ASSIGN':
668 self.storeName(node.name)
669 elif node.flags == 'OP_DELETE':
670 self.delName(node.name)
671 else:
672 print "oops", node.flags
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000673
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000674 def visitAssAttr(self, node):
675 self.visit(node.expr)
676 if node.flags == 'OP_ASSIGN':
677 self.emit('STORE_ATTR', node.attrname)
678 elif node.flags == 'OP_DELETE':
679 self.emit('DELETE_ATTR', node.attrname)
680 else:
681 print "warning: unexpected flags:", node.flags
682 print node
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000683
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000684 def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000685 if findOp(node) != 'OP_DELETE':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000686 self.emit(op, len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000687 for child in node.nodes:
688 self.visit(child)
689
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000690 if VERSION > 1:
691 visitAssTuple = _visitAssSequence
692 visitAssList = _visitAssSequence
693 else:
694 def visitAssTuple(self, node):
695 self._visitAssSequence(node, 'UNPACK_TUPLE')
696
697 def visitAssList(self, node):
698 self._visitAssSequence(node, 'UNPACK_LIST')
699
700 # augmented assignment
701
702 def visitAugAssign(self, node):
703 aug_node = wrap_aug(node.node)
704 self.visit(aug_node, "load")
705 self.visit(node.expr)
706 self.emit(self._augmented_opcode[node.op])
707 self.visit(aug_node, "store")
708
709 _augmented_opcode = {
710 '+=' : 'INPLACE_ADD',
711 '-=' : 'INPLACE_SUBTRACT',
712 '*=' : 'INPLACE_MULTIPLY',
713 '/=' : 'INPLACE_DIVIDE',
714 '%=' : 'INPLACE_MODULO',
715 '**=': 'INPLACE_POWER',
716 '>>=': 'INPLACE_RSHIFT',
717 '<<=': 'INPLACE_LSHIFT',
718 '&=' : 'INPLACE_AND',
719 '^=' : 'INPLACE_XOR',
720 '|=' : 'INPLACE_OR',
721 }
722
723 def visitAugName(self, node, mode):
724 if mode == "load":
725 self.loadName(node.name)
726 elif mode == "store":
727 self.storeName(node.name)
728
729 def visitAugGetattr(self, node, mode):
730 if mode == "load":
731 self.visit(node.expr)
732 self.emit('DUP_TOP')
733 self.emit('LOAD_ATTR', node.attrname)
734 elif mode == "store":
735 self.emit('ROT_TWO')
736 self.emit('STORE_ATTR', node.attrname)
737
738 def visitAugSlice(self, node, mode):
739 if mode == "load":
Jeremy Hylton84ec1f92001-04-11 16:43:13 +0000740 self.visitSlice(node, 1)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000741 elif mode == "store":
742 slice = 0
743 if node.lower:
744 slice = slice | 1
745 if node.upper:
746 slice = slice | 2
747 if slice == 0:
748 self.emit('ROT_TWO')
749 elif slice == 3:
750 self.emit('ROT_FOUR')
751 else:
752 self.emit('ROT_THREE')
753 self.emit('STORE_SLICE+%d' % slice)
754
755 def visitAugSubscript(self, node, mode):
756 if len(node.subs) > 1:
757 raise SyntaxError, "augmented assignment to tuple is not possible"
758 if mode == "load":
759 self.visitSubscript(node, 1)
760 elif mode == "store":
761 self.emit('ROT_THREE')
762 self.emit('STORE_SUBSCR')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000763
764 def visitExec(self, node):
765 self.visit(node.expr)
766 if node.locals is None:
767 self.emit('LOAD_CONST', None)
768 else:
769 self.visit(node.locals)
770 if node.globals is None:
771 self.emit('DUP_TOP')
772 else:
773 self.visit(node.globals)
774 self.emit('EXEC_STMT')
Jeremy Hylton76d01b82000-02-11 20:27:07 +0000775
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000776 def visitCallFunc(self, node):
Jeremy Hylton3050d512000-02-12 00:12:38 +0000777 pos = 0
778 kw = 0
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000779 self.set_lineno(node)
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000780 self.visit(node.node)
781 for arg in node.args:
782 self.visit(arg)
Jeremy Hylton3050d512000-02-12 00:12:38 +0000783 if isinstance(arg, ast.Keyword):
784 kw = kw + 1
785 else:
786 pos = pos + 1
Jeremy Hyltonbe317e62000-05-02 22:32:59 +0000787 if node.star_args is not None:
788 self.visit(node.star_args)
789 if node.dstar_args is not None:
790 self.visit(node.dstar_args)
791 have_star = node.star_args is not None
792 have_dstar = node.dstar_args is not None
793 opcode = callfunc_opcode_info[have_star, have_dstar]
794 self.emit(opcode, kw << 8 | pos)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000795
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000796 def visitPrint(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000797 self.set_lineno(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000798 if node.dest:
799 self.visit(node.dest)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000800 for child in node.nodes:
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000801 if node.dest:
802 self.emit('DUP_TOP')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000803 self.visit(child)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000804 if node.dest:
805 self.emit('ROT_TWO')
806 self.emit('PRINT_ITEM_TO')
807 else:
808 self.emit('PRINT_ITEM')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000809
810 def visitPrintnl(self, node):
811 self.visitPrint(node)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000812 if node.dest:
813 self.emit('PRINT_NEWLINE_TO')
814 else:
815 self.emit('PRINT_NEWLINE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000816
817 def visitReturn(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000818 self.set_lineno(node)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000819 self.visit(node.value)
820 self.emit('RETURN_VALUE')
Jeremy Hylton40245602000-02-08 21:15:48 +0000821
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000822 # slice and subscript stuff
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000823
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000824 def visitSlice(self, node, aug_flag=None):
825 # aug_flag is used by visitAugSlice
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000826 self.visit(node.expr)
827 slice = 0
828 if node.lower:
829 self.visit(node.lower)
830 slice = slice | 1
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000831 if node.upper:
832 self.visit(node.upper)
833 slice = slice | 2
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000834 if aug_flag:
835 if slice == 0:
836 self.emit('DUP_TOP')
837 elif slice == 3:
838 self.emit('DUP_TOPX', 3)
839 else:
840 self.emit('DUP_TOPX', 2)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000841 if node.flags == 'OP_APPLY':
Jeremy Hyltona5058122000-02-14 14:14:29 +0000842 self.emit('SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000843 elif node.flags == 'OP_ASSIGN':
Jeremy Hyltona5058122000-02-14 14:14:29 +0000844 self.emit('STORE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000845 elif node.flags == 'OP_DELETE':
Jeremy Hyltona5058122000-02-14 14:14:29 +0000846 self.emit('DELETE_SLICE+%d' % slice)
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000847 else:
Jeremy Hylton4f6bcd82000-02-15 23:45:26 +0000848 print "weird slice", node.flags
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000849 raise
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000850
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000851 def visitSubscript(self, node, aug_flag=None):
Jeremy Hylton40245602000-02-08 21:15:48 +0000852 self.visit(node.expr)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000853 for sub in node.subs:
854 self.visit(sub)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000855 if aug_flag:
856 self.emit('DUP_TOPX', 2)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000857 if len(node.subs) > 1:
858 self.emit('BUILD_TUPLE', len(node.subs))
859 if node.flags == 'OP_APPLY':
860 self.emit('BINARY_SUBSCR')
861 elif node.flags == 'OP_ASSIGN':
862 self.emit('STORE_SUBSCR')
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +0000863 elif node.flags == 'OP_DELETE':
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000864 self.emit('DELETE_SUBSCR')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000865
Jeremy Hylton7fab23e2000-03-06 19:10:54 +0000866 # binary ops
867
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000868 def binaryOp(self, node, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000869 self.visit(node.left)
870 self.visit(node.right)
871 self.emit(op)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000872
873 def visitAdd(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000874 return self.binaryOp(node, 'BINARY_ADD')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000875
876 def visitSub(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000877 return self.binaryOp(node, 'BINARY_SUBTRACT')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000878
879 def visitMul(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000880 return self.binaryOp(node, 'BINARY_MULTIPLY')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000881
882 def visitDiv(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000883 return self.binaryOp(node, 'BINARY_DIVIDE')
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000884
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000885 def visitMod(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000886 return self.binaryOp(node, 'BINARY_MODULO')
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000887
Jeremy Hylton126960b2000-02-14 21:33:10 +0000888 def visitPower(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000889 return self.binaryOp(node, 'BINARY_POWER')
Jeremy Hylton126960b2000-02-14 21:33:10 +0000890
891 def visitLeftShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000892 return self.binaryOp(node, 'BINARY_LSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +0000893
894 def visitRightShift(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000895 return self.binaryOp(node, 'BINARY_RSHIFT')
Jeremy Hylton126960b2000-02-14 21:33:10 +0000896
Jeremy Hylton7fab23e2000-03-06 19:10:54 +0000897 # unary ops
898
899 def unaryOp(self, node, op):
900 self.visit(node.expr)
901 self.emit(op)
Jeremy Hylton7fab23e2000-03-06 19:10:54 +0000902
Jeremy Hylton126960b2000-02-14 21:33:10 +0000903 def visitInvert(self, node):
904 return self.unaryOp(node, 'UNARY_INVERT')
905
Jeremy Hylton40245602000-02-08 21:15:48 +0000906 def visitUnarySub(self, node):
907 return self.unaryOp(node, 'UNARY_NEGATIVE')
908
909 def visitUnaryAdd(self, node):
910 return self.unaryOp(node, 'UNARY_POSITIVE')
911
912 def visitUnaryInvert(self, node):
913 return self.unaryOp(node, 'UNARY_INVERT')
914
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000915 def visitNot(self, node):
916 return self.unaryOp(node, 'UNARY_NOT')
917
Jeremy Hylton40245602000-02-08 21:15:48 +0000918 def visitBackquote(self, node):
919 return self.unaryOp(node, 'UNARY_CONVERT')
920
Jeremy Hylton7fab23e2000-03-06 19:10:54 +0000921 # bit ops
922
Jeremy Hyltona5058122000-02-14 14:14:29 +0000923 def bitOp(self, nodes, op):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000924 self.visit(nodes[0])
925 for node in nodes[1:]:
926 self.visit(node)
927 self.emit(op)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000928
929 def visitBitand(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000930 return self.bitOp(node.nodes, 'BINARY_AND')
Jeremy Hyltona5058122000-02-14 14:14:29 +0000931
932 def visitBitor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000933 return self.bitOp(node.nodes, 'BINARY_OR')
Jeremy Hyltona5058122000-02-14 14:14:29 +0000934
935 def visitBitxor(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000936 return self.bitOp(node.nodes, 'BINARY_XOR')
Jeremy Hyltona5058122000-02-14 14:14:29 +0000937
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000938 # object constructors
Jeremy Hylton40245602000-02-08 21:15:48 +0000939
Jeremy Hyltona5058122000-02-14 14:14:29 +0000940 def visitEllipsis(self, node):
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000941 self.emit('LOAD_CONST', Ellipsis)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000942
Jeremy Hylton40245602000-02-08 21:15:48 +0000943 def visitTuple(self, node):
944 for elt in node.nodes:
945 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000946 self.emit('BUILD_TUPLE', len(node.nodes))
Jeremy Hylton8b6323d2000-02-04 00:28:21 +0000947
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000948 def visitList(self, node):
949 for elt in node.nodes:
950 self.visit(elt)
Jeremy Hyltona5058122000-02-14 14:14:29 +0000951 self.emit('BUILD_LIST', len(node.nodes))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +0000952
953 def visitSliceobj(self, node):
954 for child in node.nodes:
955 self.visit(child)
956 self.emit('BUILD_SLICE', len(node.nodes))
Jeremy Hylton5e0ce532000-02-10 00:47:08 +0000957
Jeremy Hyltona5058122000-02-14 14:14:29 +0000958 def visitDict(self, node):
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000959 lineno = getattr(node, 'lineno', None)
960 if lineno:
961 set.emit('SET_LINENO', lineno)
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000962 self.emit('BUILD_MAP', 0)
963 for k, v in node.items:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000964 lineno2 = getattr(node, 'lineno', None)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +0000965 if lineno2 is not None and lineno != lineno2:
Thomas Wouters46cc7c02000-08-12 20:32:46 +0000966 self.emit('SET_LINENO', lineno2)
967 lineno = lineno2
Jeremy Hylton873bdc12000-02-17 17:56:29 +0000968 self.emit('DUP_TOP')
969 self.visit(v)
970 self.emit('ROT_TWO')
971 self.visit(k)
972 self.emit('STORE_SUBSCR')
Jeremy Hyltona5058122000-02-14 14:14:29 +0000973
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000974class NestedScopeCodeGenerator(CodeGenerator):
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000975 __super_visitModule = CodeGenerator.visitModule
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000976 __super_visitClass = CodeGenerator.visitClass
977 __super__visitFuncOrLambda = CodeGenerator._visitFuncOrLambda
978
979 def parseSymbols(self, tree):
980 s = symbols.SymbolVisitor()
981 walk(tree, s)
982 return s.scopes
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000983
984 def visitModule(self, node):
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000985 self.scopes = self.parseSymbols(node)
986 self.scope = self.scopes[node]
Jeremy Hylton80e29bd2001-04-09 04:28:48 +0000987 self.__super_visitModule(node)
988
Jeremy Hylton364f9b92001-04-12 06:40:42 +0000989 def _nameOp(self, prefix, name):
990 scope = self.scope.check_name(name)
991 if scope == SC_LOCAL:
992 if not self.optimized:
993 self.emit(prefix + '_NAME', name)
994 else:
995 self.emit(prefix + '_FAST', name)
996 elif scope == SC_GLOBAL:
997 self.emit(prefix + '_GLOBAL', name)
998 elif scope == SC_FREE or scope == SC_CELL:
999 self.emit(prefix + '_DEREF', name)
1000 else:
1001 raise RuntimeError, "unsupported scope for var %s: %d" % \
1002 (name, scope)
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001003
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001004 def _visitFuncOrLambda(self, node, isLambda=0):
1005 gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
1006 walk(node.code, gen)
1007 gen.finish()
1008 self.set_lineno(node)
1009 for default in node.defaults:
1010 self.visit(default)
1011 frees = gen.scope.get_free_vars()
1012 if frees:
1013 for name in frees:
1014 self.emit('LOAD_CLOSURE', name)
1015 self.emit('LOAD_CONST', gen)
1016 self.emit('MAKE_CLOSURE', len(node.defaults))
1017 else:
1018 self.emit('LOAD_CONST', gen)
1019 self.emit('MAKE_FUNCTION', len(node.defaults))
Jeremy Hylton84ec1f92001-04-11 16:43:13 +00001020
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001021 def visitClass(self, node):
1022 gen = self.ClassGen(node, self.filename, self.scopes)
1023 if node.doc:
1024 self.fixDocstring(node.code)
1025 walk(node.code, gen)
1026 gen.finish()
1027 self.set_lineno(node)
1028 self.emit('LOAD_CONST', node.name)
1029 for base in node.bases:
1030 self.visit(base)
1031 self.emit('BUILD_TUPLE', len(node.bases))
1032 frees = gen.scope.get_free_vars()
1033 for name in frees:
1034 self.emit('LOAD_CLOSURE', name)
1035 self.emit('LOAD_CONST', gen)
1036 if frees:
1037 self.emit('MAKE_CLOSURE', 0)
1038 else:
1039 self.emit('MAKE_FUNCTION', 0)
1040 self.emit('CALL_FUNCTION', 0)
1041 self.emit('BUILD_CLASS')
1042 self.storeName(node.name)
1043
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001044
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001045class LGBScopeMixin:
1046 """Defines initClass() for Python 2.1-compatible scoping"""
1047 def initClass(self):
1048 self.__class__.NameFinder = LocalNameFinder
1049 self.__class__.FunctionGen = FunctionCodeGenerator
1050 self.__class__.ClassGen = ClassCodeGenerator
1051
1052class NestedScopeMixin:
1053 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
1054 def initClass(self):
1055 self.__class__.NameFinder = LocalNameFinder
1056 self.__class__.FunctionGen = NestedFunctionCodeGenerator
1057 self.__class__.ClassGen = NestedClassCodeGenerator
1058
1059class ModuleCodeGenerator(LGBScopeMixin, CodeGenerator):
1060 __super_init = CodeGenerator.__init__
1061
1062 scopes = None
1063
1064 def __init__(self, filename):
1065 self.graph = pyassem.PyFlowGraph("<module>", filename)
1066 self.__super_init(filename)
1067
1068class NestedScopeModuleCodeGenerator(NestedScopeMixin,
1069 NestedScopeCodeGenerator):
1070 __super_init = CodeGenerator.__init__
1071
1072 def __init__(self, filename):
1073 self.graph = pyassem.PyFlowGraph("<module>", filename)
1074 self.__super_init(filename)
1075 self.graph.setFlag(CO_NESTED)
1076
1077class AbstractFunctionCode:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001078 optimized = 1
1079 lambdaCount = 0
Jeremy Hylton8b6323d2000-02-04 00:28:21 +00001080
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001081 def __init__(self, func, filename, scopes, isLambda):
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001082 if isLambda:
1083 klass = FunctionCodeGenerator
1084 name = "<lambda.%d>" % klass.lambdaCount
1085 klass.lambdaCount = klass.lambdaCount + 1
Jeremy Hylton873bdc12000-02-17 17:56:29 +00001086 else:
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001087 name = func.name
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001088 args, hasTupleArg = generateArgList(func.argnames)
1089 self.graph = pyassem.PyFlowGraph(name, filename, args,
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001090 optimized=1)
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001091 self.isLambda = isLambda
1092 self.super_init(filename)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001093
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001094 if not isLambda and func.doc:
1095 self.setDocstring(func.doc)
1096
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001097 lnf = walk(func.code, self.NameFinder(args), 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001098 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001099 if func.varargs:
1100 self.graph.setFlag(CO_VARARGS)
1101 if func.kwargs:
1102 self.graph.setFlag(CO_VARKEYWORDS)
Jeremy Hylton7daf04d2000-08-04 16:56:51 +00001103 self.set_lineno(func)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001104 if hasTupleArg:
1105 self.generateArgUnpack(func.argnames)
1106
1107 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001108 self.graph.startExitBlock()
1109 if not self.isLambda:
1110 self.emit('LOAD_CONST', None)
1111 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001112
1113 def generateArgUnpack(self, args):
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001114 for i in range(len(args)):
1115 arg = args[i]
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001116 if type(arg) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001117 self.emit('LOAD_FAST', '.%d' % (i * 2))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001118 self.unpackSequence(arg)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001119
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001120 def unpackSequence(self, tup):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001121 if VERSION > 1:
1122 self.emit('UNPACK_SEQUENCE', len(tup))
1123 else:
1124 self.emit('UNPACK_TUPLE', len(tup))
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001125 for elt in tup:
1126 if type(elt) == types.TupleType:
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001127 self.unpackSequence(elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001128 else:
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001129 self._nameOp('STORE', elt)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001130
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001131 unpackTuple = unpackSequence
1132
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001133class FunctionCodeGenerator(LGBScopeMixin, AbstractFunctionCode,
1134 CodeGenerator):
1135 super_init = CodeGenerator.__init__ # call be other init
1136 scopes = None
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001137
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001138class NestedFunctionCodeGenerator(AbstractFunctionCode,
1139 NestedScopeMixin,
1140 NestedScopeCodeGenerator):
1141 super_init = NestedScopeCodeGenerator.__init__ # call be other init
1142 __super_init = AbstractFunctionCode.__init__
1143
1144 def __init__(self, func, filename, scopes, isLambda):
1145 self.scopes = scopes
1146 self.scope = scopes[func]
1147 self.__super_init(func, filename, scopes, isLambda)
1148 self.graph.setFreeVars(self.scope.get_free_vars())
1149 self.graph.setCellVars(self.scope.get_cell_vars())
1150 self.graph.setFlag(CO_NESTED)
1151
1152class AbstractClassCode:
1153
1154 def __init__(self, klass, filename, scopes):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001155 self.graph = pyassem.PyFlowGraph(klass.name, filename,
1156 optimized=0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001157 self.super_init(filename)
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001158 lnf = walk(klass.code, self.NameFinder(), 0)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001159 self.locals.push(lnf.getLocals())
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001160 self.graph.setFlag(CO_NEWLOCALS)
Jeremy Hylton9ab019b2001-04-11 16:24:30 +00001161 if klass.doc:
1162 self.setDocstring(klass.doc)
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001163
Jeremy Hylton660cc772001-04-12 06:49:00 +00001164 def _nameOp(self, prefix, name):
Jeremy Hylton3f76b7e2001-04-12 06:52:27 +00001165 # Class namespaces are always unoptimized
Jeremy Hylton660cc772001-04-12 06:49:00 +00001166 self.emit(prefix + '_NAME', name)
1167
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001168 def finish(self):
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001169 self.graph.startExitBlock()
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001170 self.emit('LOAD_LOCALS')
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001171 self.emit('RETURN_VALUE')
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001172
Jeremy Hylton364f9b92001-04-12 06:40:42 +00001173class ClassCodeGenerator(LGBScopeMixin, AbstractClassCode, CodeGenerator):
1174 super_init = CodeGenerator.__init__
1175 scopes = None
1176
1177class NestedClassCodeGenerator(AbstractClassCode,
1178 NestedScopeMixin,
1179 NestedScopeCodeGenerator):
1180 super_init = NestedScopeCodeGenerator.__init__ # call be other init
1181 __super_init = AbstractClassCode.__init__
1182
1183 def __init__(self, klass, filename, scopes):
1184 self.scopes = scopes
1185 self.scope = scopes[klass]
1186 self.__super_init(klass, filename, scopes)
1187 self.graph.setFreeVars(self.scope.get_free_vars())
1188 self.graph.setCellVars(self.scope.get_cell_vars())
1189 self.graph.setFlag(CO_NESTED)
1190
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001191def generateArgList(arglist):
1192 """Generate an arg list marking TupleArgs"""
1193 args = []
1194 extra = []
1195 count = 0
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001196 for i in range(len(arglist)):
1197 elt = arglist[i]
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001198 if type(elt) == types.StringType:
1199 args.append(elt)
1200 elif type(elt) == types.TupleType:
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001201 args.append(TupleArg(i * 2, elt))
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001202 extra.extend(misc.flatten(elt))
Jeremy Hyltonbfb0cf82001-04-12 17:33:34 +00001203 count = count + 1
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001204 else:
1205 raise ValueError, "unexpect argument type:", elt
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001206 return args + extra, count
Jeremy Hyltona5058122000-02-14 14:14:29 +00001207
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001208def findOp(node):
1209 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
1210 v = OpFinder()
1211 walk(node, v, 0)
1212 return v.op
1213
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001214class OpFinder:
1215 def __init__(self):
1216 self.op = None
1217 def visitAssName(self, node):
1218 if self.op is None:
1219 self.op = node.flags
1220 elif self.op != node.flags:
1221 raise ValueError, "mixed ops in stmt"
Jeremy Hylton614e87f2001-04-12 20:24:26 +00001222 visitAssAttr = visitAssName
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001223
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001224class Delegator:
1225 """Base class to support delegation for augmented assignment nodes
1226
1227 To generator code for augmented assignments, we use the following
1228 wrapper classes. In visitAugAssign, the left-hand expression node
1229 is visited twice. The first time the visit uses the normal method
1230 for that node . The second time the visit uses a different method
1231 that generates the appropriate code to perform the assignment.
1232 These delegator classes wrap the original AST nodes in order to
1233 support the variant visit methods.
1234 """
1235 def __init__(self, obj):
1236 self.obj = obj
1237
1238 def __getattr__(self, attr):
1239 return getattr(self.obj, attr)
1240
1241class AugGetattr(Delegator):
1242 pass
1243
1244class AugName(Delegator):
1245 pass
1246
1247class AugSlice(Delegator):
1248 pass
1249
1250class AugSubscript(Delegator):
1251 pass
1252
1253wrapper = {
1254 ast.Getattr: AugGetattr,
1255 ast.Name: AugName,
1256 ast.Slice: AugSlice,
1257 ast.Subscript: AugSubscript,
1258 }
1259
1260def wrap_aug(node):
1261 return wrapper[node.__class__](node)
1262
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001263if __name__ == "__main__":
1264 import sys
Jeremy Hylton3ec7e2c2000-02-17 22:09:35 +00001265
Jeremy Hylton36cc6a22000-03-16 20:06:59 +00001266 for file in sys.argv[1:]:
Thomas Wouters46cc7c02000-08-12 20:32:46 +00001267 compile(file)