Files
hakorune/docs/guides/user-macros.md
Selfhosting Dev 9b9a91c859 feat: GC機能復活&VM整理&json_native調査完了
## 🎉 ChatGPT×Claude協働成果
-  **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活
  - GCメトリクス追跡システム実装(alloc/collect/pause計測)
  - 3種類のGCモード対応(counting/mark_sweep/generational)
  - host_handles.rsでハンドル管理復活

-  **VM整理とエイリアス追加**: 混乱していた名前を整理
  - MirInterpreter = NyashVm = VM のエイリアス統一
  - vm-legacyとインタープリターの違いを明確化
  - 壊れていたvm.rsの互換性修復

-  **スモークテスト整理**: v2構造でプラグイン/コア分離
  - plugins/ディレクトリにプラグインテスト移動
  - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加
  - _ensure_fixture.shでプラグイン事前ビルド確認

## 📊 json_native調査結果
- **現状**: 25%完成(配列/オブジェクトパース未実装)
- **将来性**: 並行処理でyyjson超えの可能性大
  - 100KB以上のJSONで2-10倍速の可能性
  - Nyash ABI実装後はゼロコピー最適化
- **判断**: 現時点では置換不可、将来の大きな足場

## 🔍 技術的発見
- vm-legacy = 完全なVM実装(GC付き)だった
- MirInterpreter = 現在のRust VM(712行、Arc使用)
- 200行簡易JSONは既に削除済み(存在しない)

ChatGPT爆速修復×Claude詳細調査の完璧な協働!

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00

154 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# User Macros (MacroBoxSpec) — Phase 2
Status: PoC complete; PyVM sandbox route wired. This guide explains how to author and run user macros in Nyash.
## Quickstart
- Register user macros (recommended minimal env):
- `NYASH_MACRO_ENABLE=1`
- `NYASH_MACRO_PATHS=apps/macros/examples/echo_macro.nyash`
- Run your program as usual (macro expansion happens once before MIR):
- `./target/release/nyash --backend vm apps/tests/ternary_basic.nyash`
Environment overview (recommended minimal set)
- `NYASH_MACRO_ENABLE=1`既定ON
- `NYASH_MACRO_PATHS=...`カンマ区切りのNyashマクロファイル
- `NYASH_MACRO_STRICT=1`(既定: 厳格)
- `NYASH_MACRO_TRACE=0|1`(開発用トレース)
- Runner route is defaultselfhosting優先。内部子ルートは非推奨`NYASH_MACRO_BOX_CHILD_RUNNER=0` でのみ有効)。
Backward compat (deprecated)
- `NYASH_MACRO_BOX_NY=1` + `NYASH_MACRO_BOX_NY_PATHS=...` → 今後は `NYASH_MACRO_PATHS` を使ってね
## Philosophy
- Hybrid approach: built-in (Rust) for minimal/core derives; user macros in Nyash (PyVM) for flexibility.
- Deterministic, sandboxed execution: default denies IO/NET/ENV.
- Unified interface: AST JSON v0 + MacroCtx. Expansion occurs pre-MIR.
MacroCtx (MVP)
- Rust側に最小の `MacroCtx``MacroCaps` を用意将来のAPI統合のため
- フィールド/メソッドMVP:
- `MacroCtx::from_env()` → 環境からcapabilitiesを組み立て親プロセス
- `ctx.gensym(prefix)` → 衛生識別子生成
- `ctx.report(level, message)` → 開発用レポート(標準エラー)
- `ctx.get_env(key)` → 環境取得(`NYASH_MACRO_CAP_ENV=1` のときのみ)
- 実行契約PoCランナーは `expand(json, ctx)` を優先し、失敗した場合は `expand(json)` にフォールバックします(後方互換)。
## Authoring a Macro
Create a Nyash file that defines `MacroBoxSpec` with a static `expand(json[, ctx])` returning a JSON string (AST JSON v0):
```nyash
static box MacroBoxSpec {
static function expand(json, ctx) {
// json: string (AST JSON v0)
// ctx: string (JSON; {caps:{io,net,env}} MVP). Optional for backward compatibility.
// return: string (AST JSON v0)
return json // identity for MVP
}
}
```
Example (repo): `apps/macros/examples/echo_macro.nyash`.
Editing template (string literal uppercasing)
- Example: `apps/macros/examples/upper_string_macro.nyash`
- Behavior: if a string literal value starts with `UPPER:`, the suffix is uppercased.
- Input: `print("UPPER:hello")` → Output: `print("HELLO")`
## Running your Macro
Register and run via env (simple):
```bash
export NYASH_MACRO_ENABLE=1
export NYASH_MACRO_PATHS=apps/macros/examples/echo_macro.nyash
# Run your program (macro expansion happens before MIR)
./target/release/nyash --backend vm apps/tests/ternary_basic.nyash
```
Selfhost pathNYASH_USE_NY_COMPILER=1での前展開開発用
```bash
NYASH_USE_NY_COMPILER=1 \
NYASH_MACRO_SELFHOST_PRE_EXPAND=1 \
NYASH_VM_USE_PY=1 \
./target/release/nyash --backend vm apps/tests/ternary_basic.nyash
```
Notes: 現状は PyVM ルートのみ対応。`NYASH_VM_USE_PY=1` が必須。
CLI プロファイル(推奨)
- `--profile dev`(既定相当: マクロON/厳格ON
- `--profile lite`マクロOFFの軽量モード
- `--profile ci|strict`マクロON/厳格ON
- 例: `./target/release/nyash --profile dev --backend vm apps/tests/ternary_basic.nyash`
Notes
- Built-in child route (stdin JSON -> stdout JSON) remains available when `NYASH_MACRO_BOX_CHILD_RUNNER=0`.
- Internal child can receive ctx via env: `NYASH_MACRO_CTX_JSON='{"caps":{"io":false,"net":false,"env":true}}'`
- CLI からも指定可能: `--macro-ctx-json '{"caps":{"io":false,"net":false,"env":true}}'`
- Strict mode: `NYASH_MACRO_STRICT=1` (default) fails build on macro child error/timeout; set `0` to fallback to identity.
- Timeout: `NYASH_NY_COMPILER_TIMEOUT_MS` (default `2000`).
Testing
- Smokes (v2): `tools/smokes/v2/run.sh --profile quick --filter "macro"`
- Golden (identity): `tools/test/golden/macro/identity_user_macro_golden.sh`
- Golden (upper string): `tools/test/golden/macro/upper_string_user_macro_golden.sh`
- Golden (array prepend 0): `tools/test/golden/macro/array_prepend_zero_user_macro_golden.sh`
- Golden (map insert tag): `tools/test/golden/macro/map_insert_tag_user_macro_golden.sh`
- Negative (timeout strict fail): covered by v2 smokes (legacy paths removed)
- Negative (invalid JSON strict/nonstrict): covered by v2 smokeslegacy paths removed
Array/Map editing examples
- Array prepend zero: `apps/macros/examples/array_prepend_zero_macro.nyash`
- Transforms every `{"kind":"Array","elements":[...]}` into one with a leading `0` literal element.
- Example input: `print([1, 2])` → Expanded: elements `[0, 1, 2]`.
- Map insert tag: `apps/macros/examples/map_insert_tag_macro.nyash`
- Transforms every `{"kind":"Map","entries":[...]}` by inserting the first entry `{k:"__macro", v: "on"}`.
- Example input: `print({"a": 1})` → Expanded entries: `[{"__macro":"on"}, {"a":1}]`.
## Inspect Expanded AST
```bash
./target/release/nyash --dump-expanded-ast-json apps/tests/ternary_basic.nyash
```
Outputs AST JSON v0 after expansion; use this for golden comparison.
## AST JSON v0 Schema
See `docs/reference/ir/ast-json-v0.md` for the minimal schema used in Phase 2.
## Troubleshooting
- Child timeout: increase `NYASH_NY_COMPILER_TIMEOUT_MS` or simplify macro code; strict mode fails fast.
- Invalid JSON from child: ensure `expand(json)` returns a valid AST JSON v0 string.
- No changes observed: confirm your macro is registered and the runner route is enabled.
- Capability denied: set caps explicitlyデフォルトは全OFF
- `NYASH_MACRO_CAP_IO=1` → IO系BoxFile/Path/Dir許可
- `NYASH_MACRO_CAP_NET=1` → NET系BoxHTTP/Socket許可
- `NYASH_MACRO_CAP_ENV=1``MacroCtx.get_env` 許可(将来拡張)
## Roadmap
- MacroCtx capabilities (io/net/env) expressed via nyash.toml per-macro.
- Diagnostics: JSONL tracing (`NYASH_MACRO_TRACE_JSONL`) and span/source maps.
- Golden tests for expanded JSON; strict mode as default.
## Capabilities (io/net/env)
Purpose: restrict sideeffects and ensure deterministic macro expansion.
- Default: all OFF (io=false, net=false, env=false)
- Behavior:
- io=false → no FileBox/FS access inside macro; AST JSON only
- net=false → no Http/Socket inside macro
- env=false → MacroCtx.getEnv disabled; child inherits scrubbed env
- Planned configuration (nyash.toml): see `docs/reference/macro/capabilities.md`
- PoC mapping: child is always `NYASH_VM_USE_PY=1`, `NYASH_DISABLE_PLUGINS=1`, timeout via `NYASH_NY_COMPILER_TIMEOUT_MS`
## Top-level static MacroBoxSpec (safety)
- 既定では無効(`NYASH_MACRO_TOPLEVEL_ALLOW=0`。Box宣言なしで `static function MacroBoxSpec.expand` を受理したい場合は `--macro-top-level-allow` を指定してください。