| 589 | return '[%s]' % ', '.join('%#0*x' % (_sre.CODESIZE*2+2, x) for x in code) |
| 590 | |
| 591 | def dis(code): |
| 592 | import sys |
| 593 | |
| 594 | labels = set() |
| 595 | level = 0 |
| 596 | offset_width = len(str(len(code) - 1)) |
| 597 | |
| 598 | def dis_(start, end): |
| 599 | def print_(*args, to=None): |
| 600 | if to is not None: |
| 601 | labels.add(to) |
| 602 | args += ('(to %d)' % (to,),) |
| 603 | print('%*d%s ' % (offset_width, start, ':' if start in labels else '.'), |
| 604 | end=' '*(level-1)) |
| 605 | print(*args) |
| 606 | |
| 607 | def print_2(*args): |
| 608 | print(end=' '*(offset_width + 2*level)) |
| 609 | print(*args) |
| 610 | |
| 611 | nonlocal level |
| 612 | level += 1 |
| 613 | i = start |
| 614 | while i < end: |
| 615 | start = i |
| 616 | op = code[i] |
| 617 | i += 1 |
| 618 | op = OPCODES[op] |
| 619 | if op in (SUCCESS, FAILURE, ANY, ANY_ALL, |
| 620 | MAX_UNTIL, MIN_UNTIL, NEGATE): |
| 621 | print_(op) |
| 622 | elif op in (LITERAL, NOT_LITERAL, |
| 623 | LITERAL_IGNORE, NOT_LITERAL_IGNORE, |
| 624 | LITERAL_UNI_IGNORE, NOT_LITERAL_UNI_IGNORE, |
| 625 | LITERAL_LOC_IGNORE, NOT_LITERAL_LOC_IGNORE): |
| 626 | arg = code[i] |
| 627 | i += 1 |
| 628 | print_(op, '%#02x (%r)' % (arg, chr(arg))) |
| 629 | elif op is AT: |
| 630 | arg = code[i] |
| 631 | i += 1 |
| 632 | arg = str(ATCODES[arg]) |
| 633 | assert arg[:3] == 'AT_' |
| 634 | print_(op, arg[3:]) |
| 635 | elif op is CATEGORY: |
| 636 | arg = code[i] |
| 637 | i += 1 |
| 638 | arg = str(CHCODES[arg]) |
| 639 | assert arg[:9] == 'CATEGORY_' |
| 640 | print_(op, arg[9:]) |
| 641 | elif op in (IN, IN_IGNORE, IN_UNI_IGNORE, IN_LOC_IGNORE): |
| 642 | skip = code[i] |
| 643 | print_(op, skip, to=i+skip) |
| 644 | dis_(i+1, i+skip) |
| 645 | i += skip |
| 646 | elif op in (RANGE, RANGE_UNI_IGNORE): |
| 647 | lo, hi = code[i: i+2] |
| 648 | i += 2 |