234 |
234 |
235 def getargsdict(x, funcname, keys): |
235 def getargsdict(x, funcname, keys): |
236 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), |
236 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), |
237 keyvaluenode='keyvalue', keynode='symbol') |
237 keyvaluenode='keyvalue', keynode='symbol') |
238 |
238 |
|
239 def _isnamedfunc(x, funcname): |
|
240 """Check if given tree matches named function""" |
|
241 return x and x[0] == 'func' and getsymbol(x[1]) == funcname |
|
242 |
|
243 def _matchnamedfunc(x, funcname): |
|
244 """Return args tree if given tree matches named function; otherwise None |
|
245 |
|
246 This can't be used for testing a nullary function since its args tree |
|
247 is also None. Use _isnamedfunc() instead. |
|
248 """ |
|
249 if not _isnamedfunc(x, funcname): |
|
250 return |
|
251 return x[2] |
|
252 |
239 # Constants for ordering requirement, used in _analyze(): |
253 # Constants for ordering requirement, used in _analyze(): |
240 # |
254 # |
241 # If 'define', any nested functions and operations can change the ordering of |
255 # If 'define', any nested functions and operations can change the ordering of |
242 # the entries in the set. If 'follow', any nested functions and operations |
256 # the entries in the set. If 'follow', any nested functions and operations |
243 # should take the ordering specified by the first operand to the '&' operator. |
257 # should take the ordering specified by the first operand to the '&' operator. |
284 """ |
298 """ |
285 >>> f = lambda *args: _matchonly(*map(parse, args)) |
299 >>> f = lambda *args: _matchonly(*map(parse, args)) |
286 >>> f('ancestors(A)', 'not ancestors(B)') |
300 >>> f('ancestors(A)', 'not ancestors(B)') |
287 ('list', ('symbol', 'A'), ('symbol', 'B')) |
301 ('list', ('symbol', 'A'), ('symbol', 'B')) |
288 """ |
302 """ |
289 if (revs is not None |
303 ta = _matchnamedfunc(revs, 'ancestors') |
290 and revs[0] == 'func' |
304 tb = bases and bases[0] == 'not' and _matchnamedfunc(bases[1], 'ancestors') |
291 and getsymbol(revs[1]) == 'ancestors' |
305 if ta and tb: |
292 and bases is not None |
306 return ('list', ta, tb) |
293 and bases[0] == 'not' |
|
294 and bases[1][0] == 'func' |
|
295 and getsymbol(bases[1][1]) == 'ancestors'): |
|
296 return ('list', revs[2], bases[1][2]) |
|
297 |
307 |
298 def _fixops(x): |
308 def _fixops(x): |
299 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be |
309 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be |
300 handled well by our simple top-down parser""" |
310 handled well by our simple top-down parser""" |
301 if not isinstance(x, tuple): |
311 if not isinstance(x, tuple): |