53 lines
2.1 KiB
Markdown
53 lines
2.1 KiB
Markdown
|
|
# 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)
|
||
|
|
```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.
|