Source code for srdatalog.ir.print_iir

'''Print_i — canonical s-expression form for IIR ops.

See ``docs/stage3a_execution_plan.md`` §1 for the binding vocabulary.
Print is one of three distinct operations on IR data:

    Lowering  D1.Op → D2.Op*  (data → data, framework-dispatched)
    Render    D.Op  → str     (data → target text, codegen-dispatched)
    Print     D.Op  → s-expr  (data → canonical text, dialect-owned)

This module is the top-level dispatcher for IIR Print. Each
IIR-contributing dialect (iir.cf, relation.sorted_array, relation.d2l,
parallel.data) ships a `print.py` with:

    OPS:      tuple[type, ...]                 # op classes the module handles
    print_op(op, indent: int = 0) -> str       # per-dialect dispatcher

`print_iir(op, indent)` routes by `isinstance(op, dialect.OPS)` to the
owning dialect's `print_op`. Children inside an op recurse through
`print_iir` so a sub-tree mixing dialects renders cleanly.

Mirrors `mir/print.py` (the MIR s-expr printer) in style: Racket-canonical
`#:keyword` form, two-space indent per level, parens-balanced.

Test surface: byte-equal s-expr at the IIR layer. See
`tests/test_iir_print.py`.
'''

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
  from srdatalog.ir.core import Op


# -----------------------------------------------------------------------------
# Helpers (used by every dialect's print.py)
# -----------------------------------------------------------------------------


def _ind(level: int) -> str:
  '''Two-space indent per level, matching mir/print.py.'''
  return '  ' * level


def _str_tuple(strs: tuple[str, ...]) -> str:
  '''"(a b c)" — space-separated, no commas. Matches mir/print.py _var_tuple.'''
  return '(' + ' '.join(strs) + ')'


def _quoted(text: str) -> str:
  '''Free-text fields (Comment.text, RawString.text) — escape and quote.'''
  return '"' + text.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') + '"'


def _bool(b: bool) -> str:
  '''Lowercase, matching mir/print.py's `(step #:recursive true)` form.'''
  return 'true' if b else 'false'


# -----------------------------------------------------------------------------
# Top-level dispatcher
# -----------------------------------------------------------------------------






__all__ = ['print_iir']