Files
hakorune/docs/reference/environment-variables.md
nyash-codex caf38dba19 feat(joinir): Phase 190 - LoopExitBinding boxification
Formalize exit PHI → variable_map reconnection with explicit LoopExitBinding
structure. Eliminates hardcoded variable names and prepares for Pattern 4+
multi-carrier support.

Key changes:

1. **New LoopExitBinding struct**:
   - carrier_name: String (e.g., "sum", "count")
   - join_exit_value: ValueId (JoinIR exit value)
   - host_slot: ValueId (variable_map destination)
   Makes it explicit: WHICH variable, FROM where, TO where.

2. **Updated JoinInlineBoundary**:
   - Replaced implicit host_outputs: Vec<ValueId>
   - With explicit exit_bindings: Vec<LoopExitBinding>
   - Old APIs marked #[deprecated] for backward compatibility

3. **Pattern 3 now uses explicit bindings**:
   Before: boundary.host_outputs = vec![sum_var_id]  // implicit
   After:  boundary.exit_bindings = vec![LoopExitBinding {
       carrier_name: "sum".to_string(),
       join_exit_value: ValueId(18),
       host_slot: sum_var_id,
   }]

4. **merge_joinir_mir_blocks() updated**:
   - Consumes exit_bindings instead of bare ValueIds
   - Enhanced debug output shows carrier names
   - Validates carrier name matches variable_map expectations

Benefits:
- Self-documenting code: bindings explain themselves
- Multi-carrier ready: Pattern 4+ just extend the vec![]
- Type-safe: No implicit semantics
- Debuggable: Explicit carrier name in logs

Test status:
- Build:  SUCCESS (0 errors, 47 warnings)
- Pattern 3:  PASS (no regressions)
- Backward compatibility:  Maintained via #[deprecated]

Prepare for Phase 191: Pattern Router Table and Phase 192: JoinLoopTrace

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

Co-Authored-By: ChatGPT <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 19:59:40 +09:00

219 lines
11 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.

# 環境変数リファレンス
Nyash の主要な環境変数をカテゴリ別に整理するよ。`適用経路` はどのパスで効くかを示す:
- Rust AST: Rust パーサ直通 (`--dump-mir` など)
- JSON v0/Stage-1: selfhost/Stage-1/`--ny-parser-pipe` 経由json_v0_bridge で処理)
- Any: どの経路でも有効
---
## ダンプ / 診断
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `RUST_MIR_DUMP_PATH=/tmp/out.mir` | OFF | JSON v0/Stage-1 | MIR printer の出力をファイルに書く (`json_v0_bridge::maybe_dump_mir` 経由) |
| `NYASH_CLI_VERBOSE=1` | OFF | Any | 詳細ログ。`maybe_dump_mir` が stdout に MIR を出す |
| `NYASH_CLI_VERBOSE=2` | OFF | Any | さらに詳細なログNy compiler 経路の診断ログ含む) |
| `NYASH_VM_DUMP_MIR=1` | OFF | Any | VM 実行前の MIR を出力 |
| `NYASH_DUMP_JSON_IR=1` | OFF | Any | JSON IR をダンプ |
| `NYASH_DEBUG_STACK_OVERFLOW=1` | OFF | Any | スタックオーバーフロー時に backtrace を有効化 |
### ダンプの使い分け
- Rust AST 直通: `./target/release/hakorune --dump-mir apps/tests/minimal.hako`env は不要、stdout のみ)
- JSON v0 経路/Stage-1: `RUST_MIR_DUMP_PATH=/tmp/out.mir NYASH_USE_STAGE1_CLI=1 STAGE1_EMIT_MIR_JSON=1 ./target/release/hakorune --dump-mir`stdout + ファイル)
---
## Stage-1 / selfhost CLI
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_USE_STAGE1_CLI=1` | OFF | Stage-1 | Stage-1 stub 経由に切替 |
| `NYASH_STAGE1_MODE=emit-mir` | unset | Stage-1 | `emit-program` / `emit-mir` / `run` を明示 |
| `STAGE1_EMIT_PROGRAM_JSON=1` | OFF | Stage-1 | Program(JSON v0) を吐いて終了(レガシー alias |
| `STAGE1_EMIT_MIR_JSON=1` | OFF | Stage-1 | Program(JSON v0)→MIR(JSON) を Rust 側で降ろす(レガシー alias |
| `HAKO_STAGE1_MODE={emit-program\|emit-mir\|run}` | unset | Stage-1 | .hako / Stage-1 ルート専用のモード指定(`--hako-*` が設定) |
| `HAKO_EMIT_PROGRAM_JSON=1` | OFF | Stage-1 | `.hako` stub に Program(JSON v0) emit を指示 |
| `HAKO_EMIT_MIR_JSON=1` | OFF | Stage-1 | `.hako` stub に MIR(JSON) emit を指示json_v0_bridge 経由) |
| `NYASH_STAGE1_INPUT=path` | unset | Stage-1 | 入力ソースalias: `STAGE1_SOURCE`, `STAGE1_INPUT` |
| `HAKO_STAGE1_INPUT=path` | unset | Stage-1 | `.hako` stub 用の入力ソース(`--hako-*` が設定) |
| `NYASH_STAGE1_PROGRAM_JSON=path` | unset | Stage-1 | Program(JSON v0) のパスalias: `STAGE1_PROGRAM_JSON` |
| `HAKO_STAGE1_PROGRAM_JSON=path` | unset | Stage-1 | `.hako` stub 用 Program(JSON v0) パス |
| `NYASH_STAGE1_BACKEND=vm` | `vm` | Stage-1 | Stage-1 実行の backend ヒントalias: `STAGE1_BACKEND` |
| `NYASH_STAGE1_CLI_CHILD=1` | OFF | Stage-1 | 再帰呼び出しガード |
| `STAGE1_CLI_ENTRY=...` | `lang/src/runner/stage1_cli.hako` | Stage-1 | Stage-1 stub のエントリ差し替え |
| `STAGE1_*` alias | legacy | Stage-1 | `NYASH_STAGE1_*` の旧名。互換のため受理するが順次廃止予定 |
### Stage-1 経路の例
```bash
# Stage-1 で MIR(JSON) を受け取り、Rust 側で dump
RUST_MIR_DUMP_PATH=/tmp/out.mir \
NYASH_USE_STAGE1_CLI=1 STAGE1_EMIT_MIR_JSON=1 \
./target/release/hakorune --dump-mir apps/tests/minimal.hako
# hako- 前置で Stage-1 stub 経由
./target/release/hakorune --hako-emit-program-json /tmp/out.json apps/tests/minimal.hako
./target/release/hakorune --hako-emit-mir-json /tmp/out.mir apps/tests/minimal.hako --dump-mir
```
---
## Parser / using
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_FEATURES=stage3` | `stage3` (implicit) | Any | カンマ区切りの機能フラグ。`stage3` で Stage-3 構文を許可既定ON。 |
| `NYASH_PARSER_STAGE3=1` | legacy | Any | Stage-3 旧エイリアス。将来削除予定。OFF にしたい場合のみ指定。 |
| `HAKO_PARSER_STAGE3=1` | legacy | Any | `.hako` 向け Stage-3 legacy alias。将来削除予定。 |
| `NYASH_ENABLE_USING=1` | ON | Any | using 文を有効化 |
| `HAKO_ENABLE_USING=1` | ON | Any | using 文 alias (.hako) |
| `NYASH_RESOLVE_TRACE=1` | OFF | Any | using/prelude 解決のトレース |
| `NYASH_VM_DUMP_MERGED_HAKO=1` | OFF | Rust AST | using/prelude マージ後の Hako ソースをダンプ |
---
## Runner / backend 選択
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_VM_USE_PY=1` | OFF | Any | PyVM を優先実行 |
| `NYASH_PIPE_USE_PYVM=1` | OFF | JSON v0/Stage-1 | pipe 実行を PyVM に直送 |
| `NYASH_VM_PLUGIN_STRICT=1` | OFF | Any | 必須プラグイン欠如で fail-fast |
| `NYASH_FAIL_FAST=0` | ON | Any | フォールバックを許容(既定は拒否) |
---
## Selfhost compiler / Ny compiler
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_USE_NY_COMPILER=1` | OFF | JSON v0 | Ny selfhost コンパイラを使用 |
| `NYASH_NY_COMPILER_STAGE3=1` | OFF | JSON v0 | Ny コンパイラ子プロセスで Stage-3 surface を許可 |
| `NYASH_NY_COMPILER_TIMEOUT_MS=2000` | `2000` | JSON v0 | selfhost 子プロセスのタイムアウト (ms) |
| `NYASH_NY_COMPILER_EMIT_ONLY=1` | ON | JSON v0 | selfhost コンパイラを emit-only で動かす |
| `NYASH_NY_COMPILER_CHILD_ARGS="-- --min-json"` | unset | JSON v0 | 子プロセスへ透過する追加引数 |
### Ny compiler 経路の観測テンプレート (Phase 29)
```bash
# Ny compiler 経路で Program(JSON v0)→MIR→dump を観測
NYASH_USE_NY_COMPILER=1 \
NYASH_FEATURES=stage3 \
RUST_MIR_DUMP_PATH=/tmp/ny_selfhost_minimal.mir \
NYASH_CLI_VERBOSE=2 \
./target/release/hakorune --dump-mir apps/tests/minimal_ssa_skip_ws.hako \
2>/tmp/ny_selfhost_minimal.log
```
確認項目:
- `/tmp/ny_selfhost_minimal.log` に以下の診断ログが出ているか:
- `[selfhost/ny] spawning Ny compiler child process: ...`
- `[selfhost/ny] received Program(JSON v0), size=... bytes`
- `[selfhost/ny] lowering Program(JSON v0) → MIR via json_v0_bridge`
- `[selfhost/ny] calling maybe_dump_mir (RUST_MIR_DUMP_PATH=..., cli_verbose=...)`
- `[selfhost/ny] ✅ MIR dump file created` または `⚠️ MIR dump file NOT created`
注意: Ny selfhost compiler のエントリは現在 `lang/src/compiler/entry/compiler.hako` に統一されているよ。このファイルが存在しない場合、preferred child process 経路は発火しない。
---
## GC / Runtime
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_GC_MODE={auto|rc+cycle|minorgen|stw|rc|off}` | `rc+cycle` | Any | GC モード選択 |
| `NYASH_GC_TRACE=1` | OFF | Any | GC トレース出力 (0-3) |
| `NYASH_GC_METRICS=1` | OFF | Any | GC メトリクス (text) |
| `NYASH_GC_METRICS_JSON=1` | OFF | Any | GC メトリクス (JSON) |
| `NYASH_VM_TRACE=1` | OFF | Any | VM 実行トレース |
---
## プラグイン / Box
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_DISABLE_PLUGINS=1` | OFF | Any | プラグイン無効化 |
| `NYASH_BOX_FACTORY_POLICY={builtin_first|plugin_first}` | `builtin_first` | Any | Box factory の優先順位 |
| `NYASH_FILEBOX_MODE={auto|plugin|builtin}` | `auto` | Any | FileBox 実装選択 |
---
## JoinIR トグル (Phase 72 整理版)
JoinIR は制御構造を関数呼び出し + 継続に正規化する IR 層。フラグは config/env のポリシーで集約するよ。
**ポリシー入口**
- `joinir_core_enabled()``NYASH_JOINIR_CORE` が優先。未設定時は `NYASH_JOINIR_EXPERIMENT` や IfSelect/VM bridge/LLVM 実験の明示設定で自動 ON。
- `joinir_dev_enabled()``NYASH_JOINIR_DEV=1` または JoinIR debug level > 0 で ON開発者向け束ねスイッチ
### Core本線化対象
| 変数 | デフォルト | 説明 |
| --- | --- | --- |
| `NYASH_JOINIR_CORE` | unset | Core トグルの明示 ON/OFF未設定時は下記を見て自動判定 |
| `NYASH_JOINIR_EXPERIMENT` | OFF | JoinIR 実験メイントグルCore 判定に含まれる) |
| `HAKO_JOINIR_IF_SELECT` | OFF | IfSelect/IfMerge JoinIR 経路。エイリアス `NYASH_JOINIR_IF_SELECT` は Deprecated。 |
| `HAKO_JOINIR_IF_IN_LOOP_ENABLE` | OFF | if-in-loop JoinIR 本線切替Core 候補)。 |
| `NYASH_JOINIR_VM_BRIDGE` | OFF | VM bridge Route B。Core 判定に含まれる。 |
| `NYASH_JOINIR_LLVM_EXPERIMENT` | OFF | LLVM 経路 JoinIR 実験ハーネス専用。Core 判定に含まれる。 |
| ~~`NYASH_HAKO_CHECK_JOINIR`~~ | 削除済み | **Phase 124 で削除**: hako_check は JoinIR 専用化。環境変数不要。 |
### DevOnly開発/計測専用)
| 変数 | デフォルト | 説明 |
| --- | --- | --- |
| `NYASH_JOINIR_DEV` | OFF | DevOnly まとめて ON。 |
| `NYASH_JOINIR_LOWER_FROM_MIR` | OFF | MIR ベース lowering 切替。 |
| `NYASH_JOINIR_LOWER_GENERIC` | OFF | 関数名フィルタなし generic lowering。 |
| `NYASH_JOINIR_VM_BRIDGE_DEBUG` | OFF | VM bridge 追加ログ。 |
| `NYASH_JOINIR_MAINLINE_DEBUG` | OFF | Mainline 追加ログ。 |
| `HAKO_JOINIR_IF_IN_LOOP_DRYRUN` | OFF | if-in-loop dry-run。 |
| `HAKO_JOINIR_IF_TOPLEVEL` / `_DRYRUN` | OFF | ループ外 if JoinIR 経路 / dry-run。 |
| `HAKO_JOINIR_STAGE1` | OFF | Stage1 JoinIR 経路。 |
| `HAKO_JOINIR_PRINT_TOKENS_MAIN` | OFF | print_tokens main A/B。 |
| `HAKO_JOINIR_ARRAY_FILTER_MAIN` | OFF | array.filter main A/B。 |
| `NYASH_JOINIR_DEBUG` / `HAKO_JOINIR_DEBUG` | OFF | JoinIR デバッグログ。 |
### Deprecated / 廃止候補
| 変数 | 状態 | 説明 |
| --- | --- | --- |
| `HAKO_JOINIR_NESTED_IF` | Deprecated候補 | Route B nested if。 |
| `HAKO_JOINIR_READ_QUOTED` / `_IFMERGE` | Deprecated候補 | read_quoted JoinIR 実験。 |
### 使用例
```bash
# Core JoinIR + Stage-3推奨
env NYASH_FEATURES=stage3 NYASH_JOINIR_CORE=1 ./target/release/hakorune program.hako
# VM bridge Route B開発用
env NYASH_FEATURES=stage3 NYASH_JOINIR_EXPERIMENT=1 NYASH_JOINIR_VM_BRIDGE=1 ./target/release/hakorune program.hako
# LLVM ハーネス JoinIR 実験
env NYASH_FEATURES=stage3 NYASH_LLVM_USE_HARNESS=1 \
NYASH_JOINIR_EXPERIMENT=1 NYASH_JOINIR_LLVM_EXPERIMENT=1 \
./target/release/hakorune --backend llvm apps/tests/minimal_ssa_skip_ws.hako
```
詳細: [ENV_INVENTORY.md](../private/roadmap2/phases/phase-29-longterm-joinir-full/ENV_INVENTORY.md) / [Phase 72 フラグ整理](../private/roadmap2/phases/phase-72-joinir-dev-flags/README.md)
---
## MIR 検証系(代表)
| 変数 | デフォルト | 適用経路 | 説明 |
| --- | --- | --- | --- |
| `NYASH_VERIFY_ALLOW_NO_PHI=1` | OFF | Any | PHI 検証をスキップ |
| `NYASH_VERIFY_EDGE_COPY_STRICT=1` | OFF | Any | Edge copy 検証を厳格化 |
| `NYASH_VERIFY_RET_PURITY=1` | OFF | Any | return ブロックの純粋性検証 |
| `NYASH_ME_CALL_ARITY_STRICT=1` | OFF | Any | me.method の arity 不一致でエラー |
| `NYASH_MIR_DISABLE_OPT=1` | OFF | Any | MIR Optimizer 全体を無効化(開発/診断用、`src/mir/optimizer.rs` |
| `NYASH_TRACE_VARMAP=1` | OFF | Any | `MirBuilder.variable_map` の状態をトレース出力(`[varmap/<tag>] {name=ValueId(..),..}`。JoinIR loop 統合のデバッグ用。 |
---
参考: [docs/development/architecture/mir-logs-observability.md](../development/architecture/mir-logs-observability.md) / [src/mir/verification/](../../src/mir/verification/)