freeze: macro platform complete; default ON with profiles; env consolidation; docs + smokes\n\n- Profiles: --profile {lite|dev|ci|strict} (dev-like default for macros)\n- Macro paths: prefer NYASH_MACRO_PATHS (legacy envs deprecated with warnings)\n- Selfhost pre-expand: auto mode, PyVM-only, add smokes (array/map)\n- Docs: user-macros updated; new macro-profiles guide; AGENTS freeze note; CURRENT_TASK freeze\n- Compat: non-breaking; legacy envs print deprecation notices\n
This commit is contained in:
101
docs/guides/macro-system.md
Normal file
101
docs/guides/macro-system.md
Normal file
@ -0,0 +1,101 @@
|
||||
# Macro System (Phase 16) — Quickstart
|
||||
|
||||
Status: MVP available behind environment gates (default OFF). This page describes how to enable and use the initial features (derive, test runner, expansion dump) and the developer‑facing Pattern/Quote API preview.
|
||||
|
||||
## Enabling/disabling macros
|
||||
|
||||
- Default: ON
|
||||
- Disable: `NYASH_MACRO_DISABLE=1` or `NYASH_MACRO_ENABLE=0|false|off`
|
||||
- Debug trace: `NYASH_MACRO_TRACE=1`
|
||||
- CLI shortcut for debug: `--expand` (prints pre/post AST, and sets trace)
|
||||
|
||||
## Derive (MVP)
|
||||
|
||||
- Provided derives: `Equals`, `ToString`
|
||||
- Control via env:
|
||||
- `NYASH_MACRO_DERIVE=Equals,ToString` (default when unset)
|
||||
- `NYASH_MACRO_DERIVE_ALL=1` (force all derives)
|
||||
- Behavior:
|
||||
- Injects `equals(__ny_other)` and `toString()` into Box declarations when not already present.
|
||||
- Public-only: derives operate on public fields only (Philosophy: Box independence / loose coupling).
|
||||
- No changes to MIR instruction set; expansion happens on AST, then compiled as usual.
|
||||
|
||||
Example
|
||||
```
|
||||
NYASH_MACRO_ENABLE=1 ./target/release/nyash --backend vm apps/APP/main.nyash
|
||||
```
|
||||
|
||||
## Test runner (MVP)
|
||||
|
||||
- CLI: `--run-tests` → enable macro engine and inject a test harness main
|
||||
- Discovery targets:
|
||||
- Top‑level functions with names `test_*`
|
||||
- Box static/instance methods `test_*`
|
||||
- Filtering: `--test-filter SUBSTR` or `NYASH_TEST_FILTER=SUBSTR`
|
||||
- Entry policy when a main exists:
|
||||
- `--test-entry wrap` → rename original `main` to `__ny_orig_main`, run tests then call original
|
||||
- `--test-entry override` → replace entry with test harness only
|
||||
- Force apply even if a main exists: `NYASH_TEST_FORCE=1`
|
||||
- Return policy in wrap mode:
|
||||
- `--test-return {tests|original}` or `NYASH_TEST_RETURN`
|
||||
- `tests` (default): harness returns number of failed tests
|
||||
- `original`: return the original main result (tests still run)
|
||||
- Parameterized tests (MVP): `NYASH_TEST_ARGS_DEFAULTS=1` injects integer `0` defaults for each parameter (static/instance)
|
||||
- Exit code: number of failed tests (0 = green)
|
||||
|
||||
Examples
|
||||
```
|
||||
# run all tests in a file
|
||||
./target/release/nyash --run-tests apps/tests/my_tests.nyash
|
||||
|
||||
# filter + wrap entry + default arg injection
|
||||
NYASH_MACRO_ENABLE=1 NYASH_TEST_ARGS_DEFAULTS=1 \
|
||||
./target/release/nyash --run-tests --test-filter http --test-entry wrap apps/tests/my_tests.nyash
|
||||
```
|
||||
|
||||
## Expansion dump
|
||||
|
||||
```
|
||||
./target/release/nyash --expand --dump-ast apps/tests/ternary_basic.nyash
|
||||
```
|
||||
Shows pre/post expansion AST (debug only).
|
||||
|
||||
## Developer API (preview)
|
||||
|
||||
- Pattern/Quote primitives are available to bootstrap macro authorship.
|
||||
- TemplatePattern:
|
||||
- Bind placeholders using `$name` inside a template AST.
|
||||
- OrPattern: alternation of templates.
|
||||
- Variadic `$...name` supported at any position inside call/array argument lists; binds the variable-length segment to a pseudo list (`ASTNode::Program`).
|
||||
- Unquote:
|
||||
- Replace `$name` with the bound AST.
|
||||
- Splice `$...name` into call/array argument lists.
|
||||
- Array/Map nodes participate in pattern/unquote (map keys must match literally; values can bind via `$name`).
|
||||
|
||||
### JSON test args (advanced)
|
||||
|
||||
For `--run-tests`, you can supply per-test arguments and instance construction details via `NYASH_TEST_ARGS_JSON`.
|
||||
|
||||
Shapes:
|
||||
- Simple list (as before): `{ "test_name": [1, "s", true], "Box.method": [ 0, 1 ] }`
|
||||
- Detailed object:
|
||||
- `{ "Box.method": { "args": [ ... ], "instance": { "ctor": "new|birth", "args": [ ... ], "type_args": ["T", "U"] } } }`
|
||||
- Typed values inside args:
|
||||
- `{ "i": 1 }`, `{ "f": 1.2 }`, `{ "s": "x" }`, `{ "b": true }`, `null`
|
||||
- Arrays/Maps as value: `{ "array": [1, 2, 3] }`, `{ "map": { "k": 1, "k2": {"s":"v"} } }`
|
||||
- Call/method/var literals: `{ "call": "fn", "args": [...] }`, `{ "method": "m", "object": {"var":"obj"}, "args": [...] }`, `{ "var": "name" }`
|
||||
|
||||
Diagnostics:
|
||||
- When JSON cannot be mapped or arity mismatches, warnings are printed with `[macro][test][args]` and the specific test may be skipped unless `NYASH_TEST_ARGS_DEFAULTS=1` is set.
|
||||
|
||||
Notes
|
||||
- Textual `quote(code)` is supported as a convenience via the existing parser, but `$name` placeholders should be built in AST templates directly.
|
||||
- This API will evolve; treat as experimental until the stable `macro_box` interface is finalized.
|
||||
|
||||
## Expansion Safety (Depth/Cycle)
|
||||
|
||||
- The macro engine applies a bounded number of expansion passes and stops on fixpoint.
|
||||
- Environment tuning:
|
||||
- `NYASH_MACRO_MAX_PASSES` (default 32)
|
||||
- `NYASH_MACRO_CYCLE_WINDOW` (default 8) — detect cycles across recent states
|
||||
- `NYASH_MACRO_TRACE=1` — pass-by-pass logging
|
||||
Reference in New Issue
Block a user