Show More
@@ -258,6 +258,18 b' def _build(tmplspec, *repls):' | |||||
258 | template = _cachedtree(tmplspec) |
|
258 | template = _cachedtree(tmplspec) | |
259 | return parser.buildtree(template, ('symbol', '_'), *repls) |
|
259 | return parser.buildtree(template, ('symbol', '_'), *repls) | |
260 |
|
260 | |||
|
261 | def _match(patspec, tree): | |||
|
262 | """Test if a tree matches the given pattern statement; return the matches | |||
|
263 | ||||
|
264 | >>> _match('f(_)', parse('f()')) | |||
|
265 | >>> _match('f(_)', parse('f(1)')) | |||
|
266 | [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')] | |||
|
267 | >>> _match('f(_)', parse('f(1, 2)')) | |||
|
268 | """ | |||
|
269 | pattern = _cachedtree(patspec) | |||
|
270 | return parser.matchtree(pattern, tree, ('symbol', '_'), | |||
|
271 | {'keyvalue', 'list'}) | |||
|
272 | ||||
261 | def _isnamedfunc(x, funcname): |
|
273 | def _isnamedfunc(x, funcname): | |
262 | """Check if given tree matches named function""" |
|
274 | """Check if given tree matches named function""" | |
263 | return x and x[0] == 'func' and getsymbol(x[1]) == funcname |
|
275 | return x and x[0] == 'func' and getsymbol(x[1]) == funcname | |
@@ -278,15 +290,7 b' def _matchnamedfunc(x, funcname):' | |||||
278 | return x[2] |
|
290 | return x[2] | |
279 |
|
291 | |||
280 | def _matchonly(revs, bases): |
|
292 | def _matchonly(revs, bases): | |
281 | """ |
|
293 | return _match('ancestors(_) and not ancestors(_)', ('and', revs, bases)) | |
282 | >>> f = lambda *args: _matchonly(*map(parse, args)) |
|
|||
283 | >>> f('ancestors(A)', 'not ancestors(B)') |
|
|||
284 | ('list', ('symbol', 'A'), ('symbol', 'B')) |
|
|||
285 | """ |
|
|||
286 | ta = _matchnamedfunc(revs, 'ancestors') |
|
|||
287 | tb = bases and bases[0] == 'not' and _matchnamedfunc(bases[1], 'ancestors') |
|
|||
288 | if _isposargs(ta, 1) and _isposargs(tb, 1): |
|
|||
289 | return ('list', ta, tb) |
|
|||
290 |
|
294 | |||
291 | def _fixops(x): |
|
295 | def _fixops(x): | |
292 | """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be |
|
296 | """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be | |
@@ -389,8 +393,9 b' def _optimize(x, small):' | |||||
389 | if m: |
|
393 | if m: | |
390 | return w, _build('only(_, _)', *m[1:]) |
|
394 | return w, _build('only(_, _)', *m[1:]) | |
391 |
|
395 | |||
392 | if tb is not None and tb[0] == 'not': |
|
396 | m = _match('not _', tb) | |
393 | return wa, ('difference', ta, tb[1]) |
|
397 | if m: | |
|
398 | return wa, ('difference', ta, m[1]) | |||
394 | if wa > wb: |
|
399 | if wa > wb: | |
395 | op = 'andsmally' |
|
400 | op = 'andsmally' | |
396 | return w, (op, ta, tb) |
|
401 | return w, (op, ta, tb) | |
@@ -424,7 +429,7 b' def _optimize(x, small):' | |||||
424 | return max(ws), (op, ('list',) + tuple(ts)) |
|
429 | return max(ws), (op, ('list',) + tuple(ts)) | |
425 | elif op == 'not': |
|
430 | elif op == 'not': | |
426 | # Optimize not public() to _notpublic() because we have a fast version |
|
431 | # Optimize not public() to _notpublic() because we have a fast version | |
427 | if x[1][:3] == ('func', ('symbol', 'public'), None): |
|
432 | if _match('public()', x[1]): | |
428 | o = _optimize(_build('_notpublic()'), not small) |
|
433 | o = _optimize(_build('_notpublic()'), not small) | |
429 | return o[0], o[1] |
|
434 | return o[0], o[1] | |
430 | else: |
|
435 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now