Skip to content

Printer

PrintState dataclass

PrintState(
    ssa_id: IdTable[ir.SSAValue] = IdTable["ir.SSAValue"](),
    block_id: IdTable[ir.Block] = lambda: IdTable[
        "ir.Block"
    ](prefix="^")(),
    indent: int = 0,
    result_width: int = 0,
    indent_marks: list[int] = list(),
    rich_style: str | None = None,
    rich_highlight: bool | None = False,
    messages: list[str] = list(),
)

result_width class-attribute instance-attribute

result_width: int = 0

SSA-value column width in printing

Printer dataclass

Printer(
    console: Console = _default_console(),
    analysis: dict[ir.SSAValue, Any] | None = None,
    hint: str | None = None,
    state: PrintState = PrintState(),
    *,
    show_indent_mark: bool = True,
    theme: Theme | dict | Literal["dark", "light"] = "dark"
)

A IR pretty printer build on top of Rich console.

analysis class-attribute instance-attribute

analysis: dict[SSAValue, Any] | None = None

Analysis results

console class-attribute instance-attribute

console: Console = field(default_factory=_default_console)

Rich console

hint class-attribute instance-attribute

hint: str | None = None

key of the SSAValue hint to print

show_indent_mark class-attribute instance-attribute

show_indent_mark: bool = field(default=True, kw_only=True)

Whether to show indent marks, e.g │

state class-attribute instance-attribute

state: PrintState = field(default_factory=PrintState)

Printing state

theme class-attribute instance-attribute

theme: Theme | dict | Literal["dark", "light"] = field(
    default="dark", kw_only=True
)

Theme to use for printing

align

align(width: int) -> Generator[PrintState, Any, None]

align the result column width, and restore it after the context.

Parameters:

Name Type Description Default
width(int)

width of the column

required

Yields:

Name Type Description
PrintState PrintState

the state with the new column width

Source code in src/kirin/print/printer.py
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
@contextmanager
def align(self, width: int) -> Generator[PrintState, Any, None]:
    """align the result column width, and restore it after the context.

    Args:
        width(int): width of the column

    Yields:
        PrintState: the state with the new column width
    """
    old_width = self.state.result_width
    self.state.result_width = width
    try:
        yield self.state
    finally:
        self.state.result_width = old_width

debug

debug(message: str)

Print a debug message.

Source code in src/kirin/print/printer.py
413
414
415
def debug(self, message: str):
    """Print a debug message."""
    self.state.messages.append(f"DEBUG: {message}")

indent

indent(
    increase: int = 2, mark: bool | None = None
) -> Generator[PrintState, Any, None]

increase the indentation level, and restore it after the context.

Parameters:

Name Type Description Default
increase(int)

amount to increase the indentation level, default to 2

required
mark(bool)

whether to mark the indentation level, default to None

required

Yields:

Name Type Description
PrintState PrintState

the state with the new indentation level.

Source code in src/kirin/print/printer.py
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
@contextmanager
def indent(
    self, increase: int = 2, mark: bool | None = None
) -> Generator[PrintState, Any, None]:
    """increase the indentation level, and restore it after the context.

    Args:
        increase(int): amount to increase the indentation level, default to 2
        mark(bool): whether to mark the indentation level, default to None

    Yields:
        PrintState: the state with the new indentation level.
    """
    mark = mark if mark is not None else self.show_indent_mark
    self.state.indent += increase
    if mark:
        self.state.indent_marks.append(self.state.indent)
    try:
        yield self.state
    finally:
        self.state.indent -= increase
        if mark:
            self.state.indent_marks.pop()

plain_print

plain_print(
    *objects, sep="", end="", style=None, highlight=None
)

print objects without any formatting.

Parameters:

Name Type Description Default
*objects

objects to print

()

Other Parameters:

Name Type Description
sep(str)

separator between objects, default to ""

end(str)

end character, default to ""

style(str)

style to use, default to None

highlight(bool)

whether to highlight the text, default to None

Source code in src/kirin/print/printer.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def plain_print(self, *objects, sep="", end="", style=None, highlight=None):
    """print objects without any formatting.

    Args:
        *objects: objects to print

    Keyword Args:
        sep(str): separator between objects, default to ""
        end(str): end character, default to ""
        style(str): style to use, default to None
        highlight(bool): whether to highlight the text, default to None
    """
    self.console.out(
        *objects,
        sep=sep,
        end=end,
        style=style or self.state.rich_style,
        highlight=highlight or self.state.rich_highlight,
    )

print

print(object)

entry point for printing an object

Parameters:

Name Type Description Default
object

object to print.

required
Source code in src/kirin/print/printer.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def print(self, object):
    """entry point for printing an object

    Args:
        object: object to print.
    """
    if isinstance(object, Printable):
        object.print_impl(self)
    else:
        fn = getattr(self, f"print_{object.__class__.__name__}", None)
        if fn is None:
            raise NotImplementedError(
                f"Printer for {object.__class__.__name__} not found"
            )
        fn(object)

print_dialect_path

print_dialect_path(
    node: Union[ir.Attribute, ir.Statement],
    prefix: str = "",
) -> None

print the dialect path of a node.

Parameters:

Name Type Description Default
node(ir.Attribute | ir.Statement

node to print

required
prefix(str)

prefix to print before the dialect path, default to ""

required
Source code in src/kirin/print/printer.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def print_dialect_path(
    self, node: Union["ir.Attribute", "ir.Statement"], prefix: str = ""
) -> None:
    """print the dialect path of a node.

    Args:
        node(ir.Attribute | ir.Statement): node to print
        prefix(str): prefix to print before the dialect path, default to ""
    """
    if node.dialect:  # not None
        self.plain_print(prefix)
        self.plain_print(node.dialect.name, style="dialect")
    else:
        self.plain_print(prefix)

print_indent

print_indent()

print the current indentation level optionally with indent marks.

Source code in src/kirin/print/printer.py
214
215
216
217
218
219
220
221
222
223
224
225
226
def print_indent(self):
    """print the current indentation level optionally with indent marks."""
    indent_str = ""
    if self.show_indent_mark and self.state.indent_marks:
        indent_str = "".join(
            "│" if i in self.state.indent_marks else " "
            for i in range(self.state.indent)
        )
        with self.rich(style="comment"):
            self.plain_print(indent_str)
    else:
        indent_str = " " * self.state.indent
        self.plain_print(indent_str)

print_mapping

print_mapping(
    elems: dict[KeyType, ValueType],
    *,
    emit: Callable[[ValueType], None] | None = None,
    delim: str = ", "
) -> None

print a mapping of key-value pairs.

Parameters:

Name Type Description Default
elems(dict[KeyType, ValueType]

mapping to print

required

Other Parameters:

Name Type Description
emit(Callable[[ValueType], None]

function to print each value, default to None

delim(str)

delimiter between key-value pairs, default to ", "

Source code in src/kirin/print/printer.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
def print_mapping(
    self,
    elems: dict[KeyType, ValueType],
    *,
    emit: Callable[[ValueType], None] | None = None,
    delim: str = ", ",
) -> None:
    """print a mapping of key-value pairs.

    Args:
        elems(dict[KeyType, ValueType]): mapping to print

    Keyword Args:
        emit(Callable[[ValueType], None]): function to print each value, default to None
        delim(str): delimiter between key-value pairs, default to ", "
    """
    emit = emit or self.print
    for i, (key, value) in enumerate(elems.items()):
        if i > 0:
            self.plain_print(delim)
        self.plain_print(f"{key}=")
        emit(value)

print_name

print_name(
    node: Union[ir.Attribute, ir.Statement],
    prefix: str = "",
) -> None

print the name of a node

Parameters:

Name Type Description Default
node(ir.Attribute | ir.Statement

node to print

required
prefix(str)

prefix to print before the name, default to ""

required
Source code in src/kirin/print/printer.py
118
119
120
121
122
123
124
125
126
127
128
129
130
def print_name(
    self, node: Union["ir.Attribute", "ir.Statement"], prefix: str = ""
) -> None:
    """print the name of a node

    Args:
        node(ir.Attribute | ir.Statement): node to print
        prefix(str): prefix to print before the name, default to ""
    """
    self.print_dialect_path(node, prefix=prefix)
    if node.dialect:
        self.plain_print(".")
    self.plain_print(node.name)

print_newline

print_newline()

print a newline character.

This method also prints any messages in the state for debugging.

Source code in src/kirin/print/printer.py
200
201
202
203
204
205
206
207
208
209
210
211
212
def print_newline(self):
    """print a newline character.

    This method also prints any messages in the state for debugging.
    """
    self.plain_print("\n")

    if self.state.messages:
        for message in self.state.messages:
            self.plain_print(message)
            self.plain_print("\n")
        self.state.messages.clear()
    self.print_indent()

print_seq

print_seq(
    seq: Iterable[ElemType],
    *,
    emit: Callable[[ElemType], None] | None = None,
    delim: str = ", ",
    prefix: str = "",
    suffix: str = "",
    style=None,
    highlight=None
) -> None

print a sequence of objects.

Parameters:

Name Type Description Default
seq(Iterable[ElemType])

sequence of objects to print

required

Other Parameters:

Name Type Description
emit(Callable[[ElemType], None]

function to print each element, default to None

delim(str)

delimiter between elements, default to ", "

prefix(str)

prefix to print before the sequence, default to ""

suffix(str)

suffix to print after the sequence, default to ""

style(str)

style to use, default to None

highlight(bool)

whether to highlight the text, default to None

Source code in src/kirin/print/printer.py
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
def print_seq(
    self,
    seq: Iterable[ElemType],
    *,
    emit: Callable[[ElemType], None] | None = None,
    delim: str = ", ",
    prefix: str = "",
    suffix: str = "",
    style=None,
    highlight=None,
) -> None:
    """print a sequence of objects.

    Args:
        seq(Iterable[ElemType]): sequence of objects to print

    Keyword Args:
        emit(Callable[[ElemType], None]): function to print each element, default to None
        delim(str): delimiter between elements, default to ", "
        prefix(str): prefix to print before the sequence, default to ""
        suffix(str): suffix to print after the sequence, default to ""
        style(str): style to use, default to None
        highlight(bool): whether to highlight the text, default to None
    """
    emit = emit or self.print
    self.plain_print(prefix, style=style, highlight=highlight)
    for idx, item in enumerate(seq):
        if idx > 0:
            self.plain_print(delim, style=style)
        emit(item)
    self.plain_print(suffix, style=style, highlight=highlight)

result_str

result_str(results: list[ir.ResultValue]) -> str

return the string representation of a list of result values.

Parameters:

Name Type Description Default
results(list[ir.ResultValue])

list of result values to print

required
Source code in src/kirin/print/printer.py
402
403
404
405
406
407
408
409
410
411
def result_str(self, results: list["ir.ResultValue"]) -> str:
    """return the string representation of a list of result values.

    Args:
        results(list[ir.ResultValue]): list of result values to print
    """
    with self.string_io() as stream:
        self.print_seq(results, delim=", ")
        result_str = stream.getvalue()
    return result_str

result_width

result_width(stmts: Iterable[ir.Statement]) -> int

return the maximum width of the result column for a sequence of statements.

Parameters:

Name Type Description Default
stmts(Iterable[ir.Statement])

sequence of statements

required

Returns:

Name Type Description
int int

maximum width of the result column

Source code in src/kirin/print/printer.py
308
309
310
311
312
313
314
315
316
317
318
319
320
def result_width(self, stmts: Iterable["ir.Statement"]) -> int:
    """return the maximum width of the result column for a sequence of statements.

    Args:
        stmts(Iterable[ir.Statement]): sequence of statements

    Returns:
        int: maximum width of the result column
    """
    result_width = 0
    for stmt in stmts:
        result_width = max(result_width, len(self.result_str(stmt._results)))
    return result_width

rich

rich(
    style: str | None = None, highlight: bool = False
) -> Generator[PrintState, Any, None]

set the rich style and highlight, and restore them after the context.

Parameters:

Name Type Description Default
style(str | None

style to use, default to None

required
highlight(bool)

whether to highlight the text, default to False

required

Yields:

Name Type Description
PrintState PrintState

the state with the new style and highlight.

Source code in src/kirin/print/printer.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
@contextmanager
def rich(
    self, style: str | None = None, highlight: bool = False
) -> Generator[PrintState, Any, None]:
    """set the rich style and highlight, and restore them after the context.

    Args:
        style(str | None): style to use, default to None
        highlight(bool): whether to highlight the text, default to False

    Yields:
        PrintState: the state with the new style and highlight.
    """
    old_style = self.state.rich_style
    old_highlight = self.state.rich_highlight
    self.state.rich_style = style
    self.state.rich_highlight = highlight
    try:
        yield self.state
    finally:
        self.state.rich_style = old_style
        self.state.rich_highlight = old_highlight

string_io

string_io() -> Generator[io.StringIO, Any, None]

Temporary string IO for capturing output.

Yields:

Type Description
StringIO

io.StringIO: the string IO object.

Source code in src/kirin/print/printer.py
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
@contextmanager
def string_io(self) -> Generator[io.StringIO, Any, None]:
    """Temporary string IO for capturing output.

    Yields:
        io.StringIO: the string IO object.
    """
    stream = io.StringIO()
    old_file = self.console.file
    self.console.file = stream
    try:
        yield stream
    finally:
        self.console.file = old_file
        stream.close()