Internal visitor that pretty-prints ops.
| 68 | |
| 69 | |
| 70 | class IRPrettyPrintVisitor(OpVisitor[str]): |
| 71 | """Internal visitor that pretty-prints ops.""" |
| 72 | |
| 73 | def __init__(self, names: dict[Value, str]) -> None: |
| 74 | # This should contain a name for all values that are shown as |
| 75 | # registers in the output. This is not just for Register |
| 76 | # instances -- all Ops that produce values need (generated) names. |
| 77 | self.names = names |
| 78 | |
| 79 | def visit_goto(self, op: Goto) -> str: |
| 80 | return self.format("goto %l", op.label) |
| 81 | |
| 82 | branch_op_names: Final = {Branch.BOOL: ("%r", "bool"), Branch.IS_ERROR: ("is_error(%r)", "")} |
| 83 | |
| 84 | def visit_branch(self, op: Branch) -> str: |
| 85 | fmt, typ = self.branch_op_names[op.op] |
| 86 | if op.negated: |
| 87 | fmt = f"not {fmt}" |
| 88 | |
| 89 | cond = self.format(fmt, op.value) |
| 90 | tb = "" |
| 91 | if op.traceback_entry: |
| 92 | tb = " (error at %s:%d)" % op.traceback_entry |
| 93 | fmt = f"if {cond} goto %l{tb} else goto %l" |
| 94 | if typ: |
| 95 | fmt += f" :: {typ}" |
| 96 | return self.format(fmt, op.true, op.false) |
| 97 | |
| 98 | def visit_return(self, op: Return) -> str: |
| 99 | return self.format("return %r", op.value) |
| 100 | |
| 101 | def visit_unreachable(self, op: Unreachable) -> str: |
| 102 | return "unreachable" |
| 103 | |
| 104 | def visit_assign(self, op: Assign) -> str: |
| 105 | return self.format("%r = %r", op.dest, op.src) |
| 106 | |
| 107 | def visit_assign_multi(self, op: AssignMulti) -> str: |
| 108 | return self.format("%r = [%s]", op.dest, ", ".join(self.format("%r", v) for v in op.src)) |
| 109 | |
| 110 | def visit_load_error_value(self, op: LoadErrorValue) -> str: |
| 111 | return self.format("%r = <error> :: %s", op, op.type) |
| 112 | |
| 113 | def visit_load_literal(self, op: LoadLiteral) -> str: |
| 114 | prefix = "" |
| 115 | # For values that have a potential unboxed representation, make |
| 116 | # it explicit that this is a Python object. |
| 117 | if isinstance(op.value, int): |
| 118 | prefix = "object " |
| 119 | |
| 120 | rvalue = repr(op.value) |
| 121 | if isinstance(op.value, frozenset): |
| 122 | # We need to generate a string representation that won't vary |
| 123 | # run-to-run because sets are unordered, otherwise we may get |
| 124 | # spurious irbuild test failures. |
| 125 | # |
| 126 | # Sorting by the item's string representation is a bit of a |
| 127 | # hack, but it's stable and won't cause TypeErrors. |
no outgoing calls
no test coverage detected
searching dependent graphs…