Files
hakorune/docs/guides/macro-box-nyash.md

2.1 KiB

MacroBox in Nyash (Design Draft)

Status: Design draft (Phase 16+). This document specifies the Nyash-side API for user-extensible macros that execute during compilation (pre-MIR). Rust prototype exists; this spec focuses on the Nyash interface and constraints.

Philosophy

  • Box Independence (loose coupling): macro expands against public interfaces only; avoid coupling to private internals.
  • Deterministic, side-effect free: no IO, no randomness, no time/env dependence.
  • Safety and staging: runs in a sandbox before MIR generation; never observes runtime state.

API (Nyash)

box MacroBoxSpec {
  // Required entry. Receives entire AST and returns a transformed AST.
  static function expand(ast) { /* pure transform */ }

  // Optional metadata.
  static function name() { return "MyMacro" }
}

Registration

  • Declared in nyash.toml (planned):
[macros]
paths = [
  "apps/macros/my_macro.nyash",
  "apps/macros/json_lints.nyash"
]
  • Loading policy (dev-only gate): NYASH_MACRO_BOX_NY=1 enables loading Nyash MacroBoxes from configured paths.
  • Isolation: loaded in a dedicated interpreter with IO disabled; only AST utilities and safe helpers exposed.
  • Interim mapping (prototype): name() may map to built-in MacroBoxes for effects (e.g., "UppercasePrintMacro"). Otherwise, identity transform.

Execution Order

  • Built-in (Rust) macro passes
  • User MacroBoxes (Nyash) in registration order
  • Test harness injection
  • Stop on fixed point, or when reaching the pass/cycle guard limits.

Guards

  • Max passes: NYASH_MACRO_MAX_PASSES (default 32)
  • Cycle window: NYASH_MACRO_CYCLE_WINDOW (default 8)

Constraints

  • Pure transform: no external calls (FFI/hostcall) and no global writes.
  • Public-only policy for derives: when generating methods like equals or toString, operate on public fields only.
  • Diagnostics: write via NYASH_MACRO_TRACE=1 (compiler-owned), not via print in user code.

Future Work

  • Packaging: macro crates with versioning; integrity checks.
  • Capability tokens: opt-in capabilities for limited read-only context (e.g., box names list).
  • Attribute-style hooks: @derive, @rewrite, @lint as MacroBox conventions.