blob: a19fb102202313eeb555bdee291faae309d84d03 [file] [log] [blame]
Jeremy Hyltonfa974a92000-03-06 18:50:48 +00001"""Parse tree transformation module.
2
3Transforms Python source code into an abstract syntax tree (AST)
4defined in the ast module.
5
6The simplest ways to invoke this module are via parse and parseFile.
7parse(buf) -> AST
8parseFile(path) -> AST
9"""
10
Jeremy Hylton9c048f92000-10-13 21:58:13 +000011# Original version written by Greg Stein (gstein@lyra.org)
12# and Bill Tutt (rassilon@lima.mudlib.org)
13# February 1997.
Jeremy Hyltonf968e852000-02-04 00:25:23 +000014#
Jeremy Hylton9c048f92000-10-13 21:58:13 +000015# Modifications and improvements for Python 2.0 by Jeremy Hylton and
16# Mark Hammond
17
18# Portions of this file are:
19# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved.
20#
21# This module is provided under a BSD-ish license. See
22# http://www.opensource.org/licenses/bsd-license.html
23# and replace OWNER, ORGANIZATION, and YEAR as appropriate.
24
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000025from ast import *
Jeremy Hyltonf968e852000-02-04 00:25:23 +000026import parser
Jeremy Hylton9c048f92000-10-13 21:58:13 +000027# Care must be taken to use only symbols and tokens defined in Python
28# 1.5.2 for code branches executed in 1.5.2
Jeremy Hyltonf968e852000-02-04 00:25:23 +000029import symbol
30import token
31import string
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000032import sys
Jeremy Hyltonf968e852000-02-04 00:25:23 +000033
Jeremy Hyltonf968e852000-02-04 00:25:23 +000034error = 'walker.error'
35
Jeremy Hylton9605c112000-02-08 18:57:32 +000036from consts import CO_VARARGS, CO_VARKEYWORDS
37from consts import OP_ASSIGN, OP_DELETE, OP_APPLY
Jeremy Hyltonf968e852000-02-04 00:25:23 +000038
Jeremy Hyltonfa974a92000-03-06 18:50:48 +000039def parseFile(path):
40 f = open(path)
41 src = f.read()
42 f.close()
43 return parse(src)
44
45def parse(buf):
46 return Transformer().parsesuite(buf)
47
Jeremy Hyltonf968e852000-02-04 00:25:23 +000048def asList(nodes):
Jeremy Hylton572bdce2000-09-20 02:47:28 +000049 l = []
50 for item in nodes:
51 if hasattr(item, "asList"):
52 l.append(item.asList())
53 else:
54 if type(item) is type( (None, None) ):
55 l.append(tuple(asList(item)))
56 elif type(item) is type( [] ):
57 l.append(asList(item))
58 else:
59 l.append(item)
60 return l
Jeremy Hyltonf968e852000-02-04 00:25:23 +000061
62def Node(*args):
Jeremy Hylton572bdce2000-09-20 02:47:28 +000063 kind = args[0]
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000064 if nodes.has_key(kind):
Jeremy Hylton572bdce2000-09-20 02:47:28 +000065 try:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000066 return apply(nodes[kind], args[1:])
Jeremy Hylton572bdce2000-09-20 02:47:28 +000067 except TypeError:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000068 print nodes[kind], len(args), args
Jeremy Hylton572bdce2000-09-20 02:47:28 +000069 raise
70 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +000071 raise error, "Can't find appropriate Node type: %s" % str(args)
Jeremy Hylton572bdce2000-09-20 02:47:28 +000072 #return apply(ast.Node, args)
Jeremy Hyltonf968e852000-02-04 00:25:23 +000073
74class Transformer:
Jeremy Hylton572bdce2000-09-20 02:47:28 +000075 """Utility object for transforming Python parse trees.
Jeremy Hyltonf968e852000-02-04 00:25:23 +000076
Jeremy Hylton572bdce2000-09-20 02:47:28 +000077 Exposes the following methods:
78 tree = transform(ast_tree)
79 tree = parsesuite(text)
80 tree = parseexpr(text)
81 tree = parsefile(fileob | filename)
82 """
Jeremy Hyltonf968e852000-02-04 00:25:23 +000083
Jeremy Hylton572bdce2000-09-20 02:47:28 +000084 def __init__(self):
85 self._dispatch = { }
86 for value, name in symbol.sym_name.items():
87 if hasattr(self, name):
88 self._dispatch[value] = getattr(self, name)
Jeremy Hyltonf968e852000-02-04 00:25:23 +000089
Jeremy Hylton572bdce2000-09-20 02:47:28 +000090 def transform(self, tree):
91 """Transform an AST into a modified parse tree."""
92 if type(tree) != type(()) and type(tree) != type([]):
93 tree = parser.ast2tuple(tree,1)
94 return self.compile_node(tree)
Jeremy Hyltonf968e852000-02-04 00:25:23 +000095
Jeremy Hylton572bdce2000-09-20 02:47:28 +000096 def parsesuite(self, text):
97 """Return a modified parse tree for the given suite text."""
98 # Hack for handling non-native line endings on non-DOS like OSs.
99 text = string.replace(text, '\x0d', '')
100 return self.transform(parser.suite(text))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000101
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000102 def parseexpr(self, text):
103 """Return a modified parse tree for the given expression text."""
104 return self.transform(parser.expr(text))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000105
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000106 def parsefile(self, file):
107 """Return a modified parse tree for the contents of the given file."""
108 if type(file) == type(''):
109 file = open(file)
110 return self.parsesuite(file.read())
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000111
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000112 # --------------------------------------------------------------
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000113 #
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000114 # PRIVATE METHODS
115 #
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000116
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000117 def compile_node(self, node):
118 ### emit a line-number node?
119 n = node[0]
120 if n == symbol.single_input:
121 return self.single_input(node[1:])
122 if n == symbol.file_input:
123 return self.file_input(node[1:])
124 if n == symbol.eval_input:
125 return self.eval_input(node[1:])
126 if n == symbol.lambdef:
127 return self.lambdef(node[1:])
128 if n == symbol.funcdef:
129 return self.funcdef(node[1:])
130 if n == symbol.classdef:
131 return self.classdef(node[1:])
132
133 raise error, ('unexpected node type', n)
134
135 def single_input(self, node):
136 ### do we want to do anything about being "interactive" ?
137
138 # NEWLINE | simple_stmt | compound_stmt NEWLINE
139 n = node[0][0]
140 if n != token.NEWLINE:
141 return self.com_stmt(node[0])
142
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000143 return Pass()
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000144
145 def file_input(self, nodelist):
146 doc = self.get_docstring(nodelist, symbol.file_input)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000147 stmts = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000148 for node in nodelist:
149 if node[0] != token.ENDMARKER and node[0] != token.NEWLINE:
150 self.com_append_stmt(stmts, node)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000151 return Module(doc, Stmt(stmts))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000152
153 def eval_input(self, nodelist):
154 # from the built-in function input()
155 ### is this sufficient?
156 return self.com_node(nodelist[0])
157
158 def funcdef(self, nodelist):
159 # funcdef: 'def' NAME parameters ':' suite
160 # parameters: '(' [varargslist] ')'
161
162 lineno = nodelist[1][2]
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000163 name = nodelist[1][1]
164 args = nodelist[2][2]
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000165
166 if args[0] == symbol.varargslist:
167 names, defaults, flags = self.com_arglist(args[1:])
168 else:
169 names = defaults = ()
170 flags = 0
171 doc = self.get_docstring(nodelist[4])
172
173 # code for function
174 code = self.com_node(nodelist[4])
175
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000176 n = Function(name, names, defaults, flags, doc, code)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000177 n.lineno = lineno
178 return n
179
180 def lambdef(self, nodelist):
181 # lambdef: 'lambda' [varargslist] ':' test
182 if nodelist[2][0] == symbol.varargslist:
183 names, defaults, flags = self.com_arglist(nodelist[2][1:])
184 else:
185 names = defaults = ()
186 flags = 0
187
188 # code for lambda
189 code = self.com_node(nodelist[-1])
190
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000191 n = Lambda(names, defaults, flags, code)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000192 n.lineno = nodelist[1][2]
193 return n
194
195 def classdef(self, nodelist):
196 # classdef: 'class' NAME ['(' testlist ')'] ':' suite
197
198 name = nodelist[1][1]
199 doc = self.get_docstring(nodelist[-1])
200 if nodelist[2][0] == token.COLON:
201 bases = []
202 else:
203 bases = self.com_bases(nodelist[3])
204
205 # code for class
206 code = self.com_node(nodelist[-1])
207
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000208 n = Class(name, bases, doc, code)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000209 n.lineno = nodelist[1][2]
210 return n
211
212 def stmt(self, nodelist):
213 return self.com_stmt(nodelist[0])
214
215 small_stmt = stmt
216 flow_stmt = stmt
217 compound_stmt = stmt
218
219 def simple_stmt(self, nodelist):
220 # small_stmt (';' small_stmt)* [';'] NEWLINE
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000221 stmts = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000222 for i in range(0, len(nodelist), 2):
223 self.com_append_stmt(stmts, nodelist[i])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000224 return Stmt(stmts)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000225
226 def parameters(self, nodelist):
227 raise error
228
229 def varargslist(self, nodelist):
230 raise error
231
232 def fpdef(self, nodelist):
233 raise error
234
235 def fplist(self, nodelist):
236 raise error
237
238 def dotted_name(self, nodelist):
239 raise error
240
241 def comp_op(self, nodelist):
242 raise error
243
244 def trailer(self, nodelist):
245 raise error
246
247 def sliceop(self, nodelist):
248 raise error
249
250 def argument(self, nodelist):
251 raise error
252
253 # --------------------------------------------------------------
254 #
255 # STATEMENT NODES (invoked by com_node())
256 #
257
258 def expr_stmt(self, nodelist):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000259 # augassign testlist | testlist ('=' testlist)*
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000260 exprNode = self.com_node(nodelist[-1])
261 if len(nodelist) == 1:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000262 return Discard(exprNode)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000263 if nodelist[1][0] == token.EQUAL:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000264 nodes = []
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000265 for i in range(0, len(nodelist) - 2, 2):
266 nodes.append(self.com_assign(nodelist[i], OP_ASSIGN))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000267 n = Assign(nodes, exprNode)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000268 n.lineno = nodelist[1][2]
269 else:
270 lval = self.com_augassign(nodelist[0])
271 op = self.com_augassign_op(nodelist[1])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000272 n = AugAssign(lval, op[1], exprNode)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000273 n.lineno = op[2]
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000274 return n
275
276 def print_stmt(self, nodelist):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000277 # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000278 items = []
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000279 if len(nodelist) == 1:
280 start = 1
281 dest = None
282 elif nodelist[1][0] == token.RIGHTSHIFT:
283 assert len(nodelist) == 3 \
284 or nodelist[3][0] == token.COMMA
285 dest = self.com_node(nodelist[2])
286 start = 4
287 else:
288 dest = None
289 start = 1
290 for i in range(start, len(nodelist), 2):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000291 items.append(self.com_node(nodelist[i]))
292 if nodelist[-1][0] == token.COMMA:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000293 n = Print(items, dest)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000294 n.lineno = nodelist[0][2]
295 return n
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000296 n = Printnl(items, dest)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000297 n.lineno = nodelist[0][2]
298 return n
299
300 def del_stmt(self, nodelist):
301 return self.com_assign(nodelist[1], OP_DELETE)
302
303 def pass_stmt(self, nodelist):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000304 n = Pass()
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000305 n.lineno = nodelist[0][2]
306 return n
307
308 def break_stmt(self, nodelist):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000309 n = Break()
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000310 n.lineno = nodelist[0][2]
311 return n
312
313 def continue_stmt(self, nodelist):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000314 n = Continue()
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000315 n.lineno = nodelist[0][2]
316 return n
317
318 def return_stmt(self, nodelist):
319 # return: [testlist]
320 if len(nodelist) < 2:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000321 n = Return(Const(None))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000322 n.lineno = nodelist[0][2]
323 return n
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000324 n = Return(self.com_node(nodelist[1]))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000325 n.lineno = nodelist[0][2]
326 return n
327
328 def raise_stmt(self, nodelist):
329 # raise: [test [',' test [',' test]]]
330 if len(nodelist) > 5:
331 expr3 = self.com_node(nodelist[5])
332 else:
333 expr3 = None
334 if len(nodelist) > 3:
335 expr2 = self.com_node(nodelist[3])
336 else:
337 expr2 = None
338 if len(nodelist) > 1:
339 expr1 = self.com_node(nodelist[1])
340 else:
341 expr1 = None
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000342 n = Raise(expr1, expr2, expr3)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000343 n.lineno = nodelist[0][2]
344 return n
345
346 def import_stmt(self, nodelist):
347 # import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
348 # from: 'from' dotted_name 'import'
349 # ('*' | import_as_name (',' import_as_name)*)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000350 if nodelist[0][1] == 'from':
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000351 names = []
352 if nodelist[3][0] == token.NAME:
353 for i in range(3, len(nodelist), 2):
354 names.append((nodelist[i][1], None))
355 else:
356 for i in range(3, len(nodelist), 2):
357 names.append(self.com_import_as_name(nodelist[i][1]))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000358 n = From(self.com_dotted_name(nodelist[1]), names)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000359 n.lineno = nodelist[0][2]
360 return n
361
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000362 if nodelist[1][0] == symbol.dotted_name:
363 names = [(self.com_dotted_name(nodelist[1][1:]), None)]
364 else:
365 names = []
366 for i in range(1, len(nodelist), 2):
367 names.append(self.com_dotted_as_name(nodelist[i]))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000368 n = Import(names)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000369 n.lineno = nodelist[0][2]
370 return n
371
372 def global_stmt(self, nodelist):
373 # global: NAME (',' NAME)*
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000374 names = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000375 for i in range(1, len(nodelist), 2):
376 names.append(nodelist[i][1])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000377 n = Global(names)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000378 n.lineno = nodelist[0][2]
379 return n
380
381 def exec_stmt(self, nodelist):
382 # exec_stmt: 'exec' expr ['in' expr [',' expr]]
383 expr1 = self.com_node(nodelist[1])
384 if len(nodelist) >= 4:
385 expr2 = self.com_node(nodelist[3])
386 if len(nodelist) >= 6:
387 expr3 = self.com_node(nodelist[5])
388 else:
389 expr3 = None
390 else:
391 expr2 = expr3 = None
392
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000393 n = Exec(expr1, expr2, expr3)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000394 n.lineno = nodelist[0][2]
395 return n
396
397 def assert_stmt(self, nodelist):
398 # 'assert': test, [',' test]
399 expr1 = self.com_node(nodelist[1])
400 if (len(nodelist) == 4):
401 expr2 = self.com_node(nodelist[3])
402 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000403 expr2 = Name('None')
404 n = Assert(expr1, expr2)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000405 n.lineno = nodelist[0][2]
406 return n
407
408 def if_stmt(self, nodelist):
409 # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000410 tests = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000411 for i in range(0, len(nodelist) - 3, 4):
412 testNode = self.com_node(nodelist[i + 1])
413 suiteNode = self.com_node(nodelist[i + 3])
414 tests.append((testNode, suiteNode))
415
416 if len(nodelist) % 4 == 3:
417 elseNode = self.com_node(nodelist[-1])
418## elseNode.lineno = nodelist[-1][1][2]
419 else:
420 elseNode = None
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000421 n = If(tests, elseNode)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000422 n.lineno = nodelist[0][2]
423 return n
424
425 def while_stmt(self, nodelist):
426 # 'while' test ':' suite ['else' ':' suite]
427
428 testNode = self.com_node(nodelist[1])
429 bodyNode = self.com_node(nodelist[3])
430
431 if len(nodelist) > 4:
432 elseNode = self.com_node(nodelist[6])
433 else:
434 elseNode = None
435
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000436 n = While(testNode, bodyNode, elseNode)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000437 n.lineno = nodelist[0][2]
438 return n
439
440 def for_stmt(self, nodelist):
441 # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
442
443 assignNode = self.com_assign(nodelist[1], OP_ASSIGN)
444 listNode = self.com_node(nodelist[3])
445 bodyNode = self.com_node(nodelist[5])
446
447 if len(nodelist) > 8:
448 elseNode = self.com_node(nodelist[8])
449 else:
450 elseNode = None
451
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000452 n = For(assignNode, listNode, bodyNode, elseNode)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000453 n.lineno = nodelist[0][2]
454 return n
455
456 def try_stmt(self, nodelist):
457 # 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
458 # | 'try' ':' suite 'finally' ':' suite
459 if nodelist[3][0] != symbol.except_clause:
460 return self.com_try_finally(nodelist)
461
462 return self.com_try_except(nodelist)
463
464 def suite(self, nodelist):
465 # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
466 if len(nodelist) == 1:
467 return self.com_stmt(nodelist[0])
468
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000469 stmts = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000470 for node in nodelist:
471 if node[0] == symbol.stmt:
472 self.com_append_stmt(stmts, node)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000473 return Stmt(stmts)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000474
475 # --------------------------------------------------------------
476 #
477 # EXPRESSION NODES (invoked by com_node())
478 #
479
480 def testlist(self, nodelist):
481 # testlist: expr (',' expr)* [',']
482 # exprlist: expr (',' expr)* [',']
483 return self.com_binary('tuple', nodelist)
484
485 exprlist = testlist
486
487 def test(self, nodelist):
488 # and_test ('or' and_test)* | lambdef
489 if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
490 return self.lambdef(nodelist[0])
491 return self.com_binary('or', nodelist)
492
493 def and_test(self, nodelist):
494 # not_test ('and' not_test)*
495 return self.com_binary('and', nodelist)
496
497 def not_test(self, nodelist):
498 # 'not' not_test | comparison
499 result = self.com_node(nodelist[-1])
500 if len(nodelist) == 2:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000501 n = Not(result)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000502 n.lineno = nodelist[0][2]
503 return n
504 return result
505
506 def comparison(self, nodelist):
507 # comparison: expr (comp_op expr)*
508 node = self.com_node(nodelist[0])
509 if len(nodelist) == 1:
510 return node
511
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000512 results = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000513 for i in range(2, len(nodelist), 2):
514 nl = nodelist[i-1]
515
516 # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
517 # | 'in' | 'not' 'in' | 'is' | 'is' 'not'
518 n = nl[1]
519 if n[0] == token.NAME:
520 type = n[1]
521 if len(nl) == 3:
522 if type == 'not':
523 type = 'not in'
524 else:
525 type = 'is not'
526 else:
527 type = _cmp_types[n[0]]
528
529 lineno = nl[1][2]
530 results.append((type, self.com_node(nodelist[i])))
531
532 # we need a special "compare" node so that we can distinguish
533 # 3 < x < 5 from (3 < x) < 5
534 # the two have very different semantics and results (note that the
535 # latter form is always true)
536
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000537 n = Compare(node, results)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000538 n.lineno = lineno
539 return n
540
541 def expr(self, nodelist):
542 # xor_expr ('|' xor_expr)*
543 return self.com_binary('bitor', nodelist)
544
545 def xor_expr(self, nodelist):
546 # xor_expr ('^' xor_expr)*
547 return self.com_binary('bitxor', nodelist)
548
549 def and_expr(self, nodelist):
550 # xor_expr ('&' xor_expr)*
551 return self.com_binary('bitand', nodelist)
552
553 def shift_expr(self, nodelist):
554 # shift_expr ('<<'|'>>' shift_expr)*
555 node = self.com_node(nodelist[0])
556 for i in range(2, len(nodelist), 2):
557 right = self.com_node(nodelist[i])
558 if nodelist[i-1][0] == token.LEFTSHIFT:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000559 node = LeftShift([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000560 node.lineno = nodelist[1][2]
561 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000562 node = RightShift([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000563 node.lineno = nodelist[1][2]
564 return node
565
566 def arith_expr(self, nodelist):
567 node = self.com_node(nodelist[0])
568 for i in range(2, len(nodelist), 2):
569 right = self.com_node(nodelist[i])
570 if nodelist[i-1][0] == token.PLUS:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000571 node = Add([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000572 node.lineno = nodelist[1][2]
573 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000574 node = Sub([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000575 node.lineno = nodelist[1][2]
576 return node
577
578 def term(self, nodelist):
579 node = self.com_node(nodelist[0])
580 for i in range(2, len(nodelist), 2):
581 right = self.com_node(nodelist[i])
582 if nodelist[i-1][0] == token.STAR:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000583 node = Mul([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000584 node.lineno = nodelist[1][2]
585 elif nodelist[i-1][0] == token.SLASH:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000586 node = Div([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000587 node.lineno = nodelist[1][2]
588 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000589 node = Mod([node, right])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000590 node.lineno = nodelist[1][2]
591 return node
592
593 def factor(self, nodelist):
594 t = nodelist[0][0]
595 node = self.com_node(nodelist[-1])
596 if t == token.PLUS:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000597 node = UnaryAdd(node)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000598 node.lineno = nodelist[0][2]
599 elif t == token.MINUS:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000600 node = UnarySub(node)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000601 node.lineno = nodelist[0][2]
602 elif t == token.TILDE:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000603 node = Invert(node)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000604 node.lineno = nodelist[0][2]
605 return node
606
607 def power(self, nodelist):
608 # power: atom trailer* ('**' factor)*
609 node = self.com_node(nodelist[0])
610 for i in range(1, len(nodelist)):
611 if nodelist[i][0] == token.DOUBLESTAR:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000612 n = Power([node, self.com_node(nodelist[i+1])])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000613 n.lineno = nodelist[i][2]
614 return n
615
616 node = self.com_apply_trailer(node, nodelist[i])
617
618 return node
619
620 def atom(self, nodelist):
621 t = nodelist[0][0]
622 if t == token.LPAR:
623 if nodelist[1][0] == token.RPAR:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000624 n = Tuple(())
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000625 n.lineno = nodelist[0][2]
626 return n
627 return self.com_node(nodelist[1])
628
629 if t == token.LSQB:
630 if nodelist[1][0] == token.RSQB:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000631 n = List(())
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000632 n.lineno = nodelist[0][2]
633 return n
634 return self.com_list_constructor(nodelist[1])
635
636 if t == token.LBRACE:
637 if nodelist[1][0] == token.RBRACE:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000638 return Dict(())
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000639 return self.com_dictmaker(nodelist[1])
640
641 if t == token.BACKQUOTE:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000642 n = Backquote(self.com_node(nodelist[1]))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000643 n.lineno = nodelist[0][2]
644 return n
645
646 if t == token.NUMBER:
647 ### need to verify this matches compile.c
648 k = eval(nodelist[0][1])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000649 n = Const(k)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000650 n.lineno = nodelist[0][2]
651 return n
652
653 if t == token.STRING:
654 ### need to verify this matches compile.c
655 k = ''
656 for node in nodelist:
657 k = k + eval(node[1])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000658 n = Const(k)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000659 n.lineno = nodelist[0][2]
660 return n
661
662 if t == token.NAME:
663 ### any processing to do?
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000664 n = Name(nodelist[0][1])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000665 n.lineno = nodelist[0][2]
666 return n
667
668 raise error, "unknown node type"
669
670 # --------------------------------------------------------------
671 #
672 # INTERNAL PARSING UTILITIES
673 #
674
675 def com_node(self, node):
676 # Note: compile.c has handling in com_node for del_stmt, pass_stmt,
677 # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt,
678 # and compound_stmt.
679 # We'll just dispatch them.
680
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000681 # A ';' at the end of a line can make a NEWLINE token appear
682 # here, Render it harmless. (genc discards ('discard',
683 # ('const', xxxx)) Nodes)
684 key = node[0]
685
686 meth = self._dispatch.get(key, None)
687 if meth:
688 return meth(node[1:])
689 else:
690 if key == token.NEWLINE:
691 return Discard(Const(None))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000692
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000693 raise error, 'illegal node passed to com_node: %s' % `node`
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000694
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000695 def com_arglist(self, nodelist):
696 # varargslist:
697 # (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
698 # | fpdef ['=' test] (',' fpdef ['=' test])* [',']
699 # | ('**'|'*' '*') NAME)
700 # fpdef: NAME | '(' fplist ')'
701 # fplist: fpdef (',' fpdef)* [',']
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000702 names = []
703 defaults = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000704 flags = 0
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000705
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000706 i = 0
707 while i < len(nodelist):
708 node = nodelist[i]
709 if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
710 if node[0] == token.STAR:
711 node = nodelist[i+1]
712 if node[0] == token.NAME:
713 names.append(node[1])
714 flags = flags | CO_VARARGS
715 i = i + 3
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000716
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000717 if i < len(nodelist):
718 # should be DOUBLESTAR or STAR STAR
719 if nodelist[i][0] == token.DOUBLESTAR:
720 node = nodelist[i+1]
721 else:
722 node = nodelist[i+2]
723 names.append(node[1])
724 flags = flags | CO_VARKEYWORDS
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000725
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000726 break
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000727
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000728 # fpdef: NAME | '(' fplist ')'
729 names.append(self.com_fpdef(node))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000730
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000731 i = i + 1
732 if i >= len(nodelist):
733 break
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000734
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000735 if nodelist[i][0] == token.EQUAL:
736 defaults.append(self.com_node(nodelist[i + 1]))
737 i = i + 2
738 elif len(defaults):
739 # Treat "(a=1, b)" as "(a=1, b=None)"
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000740 defaults.append(Const(None))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000741
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000742 i = i + 1
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000743
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000744 return names, defaults, flags
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000745
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000746 def com_fpdef(self, node):
747 # fpdef: NAME | '(' fplist ')'
748 if node[1][0] == token.LPAR:
749 return self.com_fplist(node[2])
750 return node[1][1]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000751
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000752 def com_fplist(self, node):
753 # fplist: fpdef (',' fpdef)* [',']
754 if len(node) == 2:
755 return self.com_fpdef(node[1])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000756 list = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000757 for i in range(1, len(node), 2):
758 list.append(self.com_fpdef(node[i]))
759 return tuple(list)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000760
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000761 def com_dotted_name(self, node):
762 # String together the dotted names and return the string
763 name = ""
764 for n in node:
765 if type(n) == type(()) and n[0] == 1:
766 name = name + n[1] + '.'
767 return name[:-1]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000768
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000769 def com_dotted_as_name(self, node):
770 dot = self.com_dotted_name(node[1])
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000771 if len(node) <= 2:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000772 return dot, None
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000773 if node[0] == symbol.dotted_name:
774 pass
775 else:
776 assert node[2][1] == 'as'
777 assert node[3][0] == token.NAME
778 return dot, node[3][1]
Jeremy Hylton20516082000-09-01 20:33:26 +0000779
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000780 def com_import_as_name(self, node):
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000781 if node == '*':
782 return '*', None
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000783 if node[0] == token.NAME:
784 return node[1], None
785 assert len(node) == 4
786 assert node[2][1] == 'as'
787 assert node[3][0] == token.NAME
788 return node[1][1], node[3][1]
Jeremy Hylton20516082000-09-01 20:33:26 +0000789
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000790 def com_bases(self, node):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000791 bases = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000792 for i in range(1, len(node), 2):
793 bases.append(self.com_node(node[i]))
794 return bases
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000795
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000796 def com_try_finally(self, nodelist):
797 # try_fin_stmt: "try" ":" suite "finally" ":" suite
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000798 n = TryFinally(self.com_node(nodelist[2]),
799 self.com_node(nodelist[5]))
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000800 n.lineno = nodelist[0][2]
801 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000802
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000803 def com_try_except(self, nodelist):
804 # try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite]
805 #tryexcept: [TryNode, [except_clauses], elseNode)]
806 stmt = self.com_node(nodelist[2])
807 clauses = []
808 elseNode = None
809 for i in range(3, len(nodelist), 3):
810 node = nodelist[i]
811 if node[0] == symbol.except_clause:
812 # except_clause: 'except' [expr [',' expr]] */
813 if len(node) > 2:
814 expr1 = self.com_node(node[2])
815 if len(node) > 4:
816 expr2 = self.com_assign(node[4], OP_ASSIGN)
817 else:
818 expr2 = None
819 else:
820 expr1 = expr2 = None
821 clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000822
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000823 if node[0] == token.NAME:
824 elseNode = self.com_node(nodelist[i+2])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000825 n = TryExcept(self.com_node(nodelist[2]), clauses, elseNode)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000826 n.lineno = nodelist[0][2]
827 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000828
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000829 def com_augassign_op(self, node):
830 assert node[0] == symbol.augassign
831 return node[1]
832
833 def com_augassign(self, node):
834 """Return node suitable for lvalue of augmented assignment
835
836 Names, slices, and attributes are the only allowable nodes.
837 """
838 l = self.com_node(node)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000839 if l.__class__ in (Name, Slice, Subscript, Getattr):
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000840 return l
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000841 raise SyntaxError, "can't assign to %s" % l.__class__.__name__
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000842
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000843 def com_assign(self, node, assigning):
844 # return a node suitable for use as an "lvalue"
845 # loop to avoid trivial recursion
846 while 1:
847 t = node[0]
848 if t == symbol.exprlist or t == symbol.testlist:
849 if len(node) > 2:
850 return self.com_assign_tuple(node, assigning)
851 node = node[1]
852 elif t in _assign_types:
853 if len(node) > 2:
854 raise SyntaxError, "can't assign to operator"
855 node = node[1]
856 elif t == symbol.power:
857 if node[1][0] != symbol.atom:
858 raise SyntaxError, "can't assign to operator"
859 if len(node) > 2:
860 primary = self.com_node(node[1])
861 for i in range(2, len(node)-1):
862 ch = node[i]
863 if ch[0] == token.DOUBLESTAR:
864 raise SyntaxError, "can't assign to operator"
865 primary = self.com_apply_trailer(primary, ch)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000866 return self.com_assign_trailer(primary, node[-1],
867 assigning)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000868 node = node[1]
869 elif t == symbol.atom:
870 t = node[1][0]
871 if t == token.LPAR:
872 node = node[2]
873 if node[0] == token.RPAR:
874 raise SyntaxError, "can't assign to ()"
875 elif t == token.LSQB:
876 node = node[2]
877 if node[0] == token.RSQB:
878 raise SyntaxError, "can't assign to []"
879 return self.com_assign_list(node, assigning)
880 elif t == token.NAME:
881 return self.com_assign_name(node[1], assigning)
882 else:
883 raise SyntaxError, "can't assign to literal"
884 else:
885 raise SyntaxError, "bad assignment"
886
887 def com_assign_tuple(self, node, assigning):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000888 assigns = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000889 for i in range(1, len(node), 2):
890 assigns.append(self.com_assign(node[i], assigning))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000891 return AssTuple(assigns)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000892
893 def com_assign_list(self, node, assigning):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000894 assigns = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000895 for i in range(1, len(node), 2):
896 assigns.append(self.com_assign(node[i], assigning))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000897 return AssList(assigns)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000898
899 def com_assign_name(self, node, assigning):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000900 n = AssName(node[1], assigning)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000901 n.lineno = node[2]
902 return n
903
904 def com_assign_trailer(self, primary, node, assigning):
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000905 t = node[1][0]
906 if t == token.LPAR:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000907 raise SyntaxError, "can't assign to function call"
908 if t == token.DOT:
909 return self.com_assign_attr(primary, node[2], assigning)
910 if t == token.LSQB:
911 return self.com_subscriptlist(primary, node[2], assigning)
912 raise SyntaxError, "unknown trailer type: %s" % t
913
914 def com_assign_attr(self, primary, node, assigning):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000915 return AssAttr(primary, node[1], assigning)
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000916
917 def com_binary(self, type, nodelist):
918 "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])."
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000919 l = len(nodelist)
920 if l == 1:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000921 return self.com_node(nodelist[0])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000922 items = []
923 for i in range(0, l, 2):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000924 items.append(self.com_node(nodelist[i]))
925 return Node(type, items)
926
927 def com_stmt(self, node):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000928 result = self.com_node(node)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000929 assert result is not None
930 if isinstance(result, Stmt):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000931 return result
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000932 return Stmt([result])
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000933
934 def com_append_stmt(self, stmts, node):
935 result = self.com_node(node)
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000936 assert result is not None
937 if isinstance(result, Stmt):
938 stmts.extend(result.nodes)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000939 else:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000940 stmts.append(result)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000941
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000942 if hasattr(symbol, 'list_for'):
943 def com_list_constructor(self, nodelist):
944 # listmaker: test ( list_for | (',' test)* [','] )
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000945 values = []
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000946 for i in range(1, len(nodelist)):
947 if nodelist[i][0] == symbol.list_for:
948 assert len(nodelist[i:]) == 1
949 return self.com_list_comprehension(values[0],
950 nodelist[i])
951 elif nodelist[i][0] == token.COMMA:
952 continue
953 values.append(self.com_node(nodelist[i]))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000954 return List(values)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000955
956 def com_list_comprehension(self, expr, node):
957 # list_iter: list_for | list_if
958 # list_for: 'for' exprlist 'in' testlist [list_iter]
959 # list_if: 'if' test [list_iter]
960 lineno = node[1][2]
961 fors = []
962 while node:
963 if node[1][1] == 'for':
964 assignNode = self.com_assign(node[2], OP_ASSIGN)
965 listNode = self.com_node(node[4])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000966 newfor = ListCompFor(assignNode, listNode, [])
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000967 newfor.lineno = node[1][2]
968 fors.append(newfor)
969 if len(node) == 5:
970 node = None
971 else:
972 node = self.com_list_iter(node[5])
973 elif node[1][1] == 'if':
974 test = self.com_node(node[2])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000975 newif = ListCompIf(test)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000976 newif.lineno = node[1][2]
977 newfor.ifs.append(newif)
978 if len(node) == 3:
979 node = None
980 else:
981 node = self.com_list_iter(node[3])
982 else:
983 raise SyntaxError, \
984 ("unexpected list comprehension element: %s %d"
985 % (node, lineno))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000986 n = ListComp(expr, fors)
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000987 n.lineno = lineno
988 return n
989
990 def com_list_iter(self, node):
991 assert node[0] == symbol.list_iter
992 return node[1]
993 else:
994 def com_list_constructor(self, nodelist):
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000995 values = []
Jeremy Hylton9c048f92000-10-13 21:58:13 +0000996 for i in range(1, len(nodelist), 2):
997 values.append(self.com_node(nodelist[i]))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +0000998 return List(values)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000999
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001000 def com_dictmaker(self, nodelist):
1001 # dictmaker: test ':' test (',' test ':' value)* [',']
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001002 items = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001003 for i in range(1, len(nodelist), 4):
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001004 items.append((self.com_node(nodelist[i]),
1005 self.com_node(nodelist[i+2])))
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001006 return Dict(items)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001007
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001008 def com_apply_trailer(self, primaryNode, nodelist):
1009 t = nodelist[1][0]
1010 if t == token.LPAR:
1011 return self.com_call_function(primaryNode, nodelist[2])
1012 if t == token.DOT:
1013 return self.com_select_member(primaryNode, nodelist[2])
1014 if t == token.LSQB:
1015 return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001016
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001017 raise SyntaxError, 'unknown node type: %s' % t
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001018
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001019 def com_select_member(self, primaryNode, nodelist):
1020 if nodelist[0] != token.NAME:
1021 raise SyntaxError, "member must be a name"
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001022 n = Getattr(primaryNode, nodelist[1])
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001023 n.lineno = nodelist[2]
1024 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001025
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001026 def com_call_function(self, primaryNode, nodelist):
1027 if nodelist[0] == token.RPAR:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001028 return CallFunc(primaryNode, [])
1029 args = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001030 kw = 0
1031 len_nodelist = len(nodelist)
1032 for i in range(1, len_nodelist, 2):
1033 node = nodelist[i]
1034 if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
1035 break
1036 kw, result = self.com_argument(node, kw)
1037 args.append(result)
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001038 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001039 # No broken by star arg, so skip the last one we processed.
1040 i = i + 1
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001041 if i < len_nodelist and nodelist[i][0] == token.COMMA:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001042 # need to accept an application that looks like "f(a, b,)"
1043 i = i + 1
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001044 star_node = dstar_node = None
1045 while i < len_nodelist:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001046 tok = nodelist[i]
1047 ch = nodelist[i+1]
1048 i = i + 3
1049 if tok[0]==token.STAR:
1050 if star_node is not None:
1051 raise SyntaxError, 'already have the varargs indentifier'
1052 star_node = self.com_node(ch)
1053 elif tok[0]==token.DOUBLESTAR:
1054 if dstar_node is not None:
1055 raise SyntaxError, 'already have the kwargs indentifier'
1056 dstar_node = self.com_node(ch)
1057 else:
1058 raise SyntaxError, 'unknown node type: %s' % tok
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001059
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001060 return CallFunc(primaryNode, args, star_node, dstar_node)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001061
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001062 def com_argument(self, nodelist, kw):
1063 if len(nodelist) == 2:
1064 if kw:
1065 raise SyntaxError, "non-keyword arg after keyword arg"
1066 return 0, self.com_node(nodelist[1])
1067 result = self.com_node(nodelist[3])
1068 n = nodelist[1]
1069 while len(n) == 2 and n[0] != token.NAME:
1070 n = n[1]
1071 if n[0] != token.NAME:
1072 raise SyntaxError, "keyword can't be an expression (%s)"%n[0]
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001073 node = Keyword(n[1], result)
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001074 node.lineno = n[2]
1075 return 1, node
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001076
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001077 def com_subscriptlist(self, primary, nodelist, assigning):
1078 # slicing: simple_slicing | extended_slicing
1079 # simple_slicing: primary "[" short_slice "]"
1080 # extended_slicing: primary "[" slice_list "]"
1081 # slice_list: slice_item ("," slice_item)* [","]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001082
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001083 # backwards compat slice for '[i:j]'
1084 if len(nodelist) == 2:
1085 sub = nodelist[1]
1086 if (sub[1][0] == token.COLON or \
1087 (len(sub) > 2 and sub[2][0] == token.COLON)) and \
1088 sub[-1][0] != symbol.sliceop:
1089 return self.com_slice(primary, sub, assigning)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001090
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001091 subscripts = []
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001092 for i in range(1, len(nodelist), 2):
1093 subscripts.append(self.com_subscript(nodelist[i]))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001094
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001095 return Subscript(primary, assigning, subscripts)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001096
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001097 def com_subscript(self, node):
1098 # slice_item: expression | proper_slice | ellipsis
1099 ch = node[1]
1100 if ch[0] == token.DOT and node[2][0] == token.DOT:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001101 return Ellipsis()
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001102 if ch[0] == token.COLON or len(node) > 2:
1103 return self.com_sliceobj(node)
1104 return self.com_node(ch)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001105
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001106 def com_sliceobj(self, node):
1107 # proper_slice: short_slice | long_slice
1108 # short_slice: [lower_bound] ":" [upper_bound]
1109 # long_slice: short_slice ":" [stride]
1110 # lower_bound: expression
1111 # upper_bound: expression
1112 # stride: expression
1113 #
1114 # Note: a stride may be further slicing...
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001115
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001116 items = []
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001117
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001118 if node[1][0] == token.COLON:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001119 items.append(Const(None))
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001120 i = 2
1121 else:
1122 items.append(self.com_node(node[1]))
1123 # i == 2 is a COLON
1124 i = 3
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001125
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001126 if i < len(node) and node[i][0] == symbol.test:
1127 items.append(self.com_node(node[i]))
1128 i = i + 1
1129 else:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001130 items.append(Const(None))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001131
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001132 # a short_slice has been built. look for long_slice now by looking
1133 # for strides...
1134 for j in range(i, len(node)):
1135 ch = node[j]
1136 if len(ch) == 2:
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001137 items.append(Const(None))
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001138 else:
1139 items.append(self.com_node(ch[2]))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001140
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001141 return Sliceobj(items)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001142
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001143 def com_slice(self, primary, node, assigning):
1144 # short_slice: [lower_bound] ":" [upper_bound]
1145 lower = upper = None
1146 if len(node) == 3:
1147 if node[1][0] == token.COLON:
1148 upper = self.com_node(node[2])
1149 else:
1150 lower = self.com_node(node[1])
1151 elif len(node) == 4:
1152 lower = self.com_node(node[1])
1153 upper = self.com_node(node[3])
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001154 return Slice(primary, assigning, lower, upper)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001155
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001156 def get_docstring(self, node, n=None):
1157 if n is None:
1158 n = node[0]
1159 node = node[1:]
1160 if n == symbol.suite:
1161 if len(node) == 1:
1162 return self.get_docstring(node[0])
1163 for sub in node:
1164 if sub[0] == symbol.stmt:
1165 return self.get_docstring(sub)
1166 return None
1167 if n == symbol.file_input:
1168 for sub in node:
1169 if sub[0] == symbol.stmt:
1170 return self.get_docstring(sub)
1171 return None
1172 if n == symbol.atom:
1173 if node[0][0] == token.STRING:
1174 s = ''
1175 for t in node:
1176 s = s + eval(t[1])
1177 return s
1178 return None
Jeremy Hylton7cff7fe2000-10-25 18:10:32 +00001179 if n == symbol.stmt or n == symbol.simple_stmt \
1180 or n == symbol.small_stmt:
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001181 return self.get_docstring(node[0])
1182 if n in _doc_nodes and len(node) == 1:
1183 return self.get_docstring(node[0])
1184 return None
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001185
1186
1187_doc_nodes = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001188 symbol.expr_stmt,
1189 symbol.testlist,
1190 symbol.test,
1191 symbol.and_test,
1192 symbol.not_test,
1193 symbol.comparison,
1194 symbol.expr,
1195 symbol.xor_expr,
1196 symbol.and_expr,
1197 symbol.shift_expr,
1198 symbol.arith_expr,
1199 symbol.term,
1200 symbol.factor,
1201 symbol.power,
1202 ]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001203
1204# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
1205# | 'in' | 'not' 'in' | 'is' | 'is' 'not'
1206_cmp_types = {
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001207 token.LESS : '<',
1208 token.GREATER : '>',
1209 token.EQEQUAL : '==',
1210 token.EQUAL : '==',
1211 token.LESSEQUAL : '<=',
1212 token.GREATEREQUAL : '>=',
1213 token.NOTEQUAL : '!=',
1214 }
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001215
1216_legal_node_types = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001217 symbol.funcdef,
1218 symbol.classdef,
1219 symbol.stmt,
1220 symbol.small_stmt,
1221 symbol.flow_stmt,
1222 symbol.simple_stmt,
1223 symbol.compound_stmt,
1224 symbol.expr_stmt,
1225 symbol.print_stmt,
1226 symbol.del_stmt,
1227 symbol.pass_stmt,
1228 symbol.break_stmt,
1229 symbol.continue_stmt,
1230 symbol.return_stmt,
1231 symbol.raise_stmt,
1232 symbol.import_stmt,
1233 symbol.global_stmt,
1234 symbol.exec_stmt,
1235 symbol.assert_stmt,
1236 symbol.if_stmt,
1237 symbol.while_stmt,
1238 symbol.for_stmt,
1239 symbol.try_stmt,
1240 symbol.suite,
1241 symbol.testlist,
1242 symbol.test,
1243 symbol.and_test,
1244 symbol.not_test,
1245 symbol.comparison,
1246 symbol.exprlist,
1247 symbol.expr,
1248 symbol.xor_expr,
1249 symbol.and_expr,
1250 symbol.shift_expr,
1251 symbol.arith_expr,
1252 symbol.term,
1253 symbol.factor,
1254 symbol.power,
1255 symbol.atom,
1256 ]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001257
1258_assign_types = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001259 symbol.test,
1260 symbol.and_test,
1261 symbol.not_test,
1262 symbol.comparison,
1263 symbol.expr,
1264 symbol.xor_expr,
1265 symbol.and_expr,
1266 symbol.shift_expr,
1267 symbol.arith_expr,
1268 symbol.term,
1269 symbol.factor,
1270 ]
Jeremy Hylton9c048f92000-10-13 21:58:13 +00001271
1272import types
1273_names = {}
1274for k, v in symbol.sym_name.items():
1275 _names[k] = v
1276for k, v in token.tok_name.items():
1277 _names[k] = v
1278
1279def debug_tree(tree):
1280 l = []
1281 for elt in tree:
1282 if type(elt) == types.IntType:
1283 l.append(_names.get(elt, elt))
1284 elif type(elt) == types.StringType:
1285 l.append(elt)
1286 else:
1287 l.append(debug_tree(elt))
1288 return l