diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md index 15d88f78..d675c8b9 100644 --- a/docs/reference/environment-variables.md +++ b/docs/reference/environment-variables.md @@ -1,157 +1,153 @@ # 環境変数リファレンス -Nyashの動作を制御する環境変数の一覧。 +Nyash の主要な環境変数をカテゴリ別に整理するよ。`適用経路` はどのパスで効くかを示す: + +- Rust AST: Rust パーサ直通 (`--dump-mir` など) +- JSON v0/Stage-1: selfhost/Stage-1/`--ny-parser-pipe` 経由(json_v0_bridge で処理) +- Any: どの経路でも有効 --- -## MIR Builder検証系 +## ダンプ / 診断 -MIRビルダーの動作検証・デバッグ用環境変数。 +| 変数 | デフォルト | 適用経路 | 説明 | +| --- | --- | --- | --- | +| `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 を有効化 | -| 環境変数 | デフォルト | 用途 | 追加Phase | -|---------|----------|-----|-----------| -| `NYASH_ME_CALL_ARITY_STRICT=1` | OFF | me.method呼び出しのarity不一致でエラー返却 | Phase 25.x | -| `NYASH_STATIC_CALL_TRACE=1` | OFF | Static method呼び出しのトレース出力 | Phase 25.x | -| `NYASH_VERIFY_ALLOW_NO_PHI=1` | OFF | PHI検証スキップ(支配・マージ) | - | -| `NYASH_VERIFY_ALLOW_LEGACY=1` | OFF | レガシー命令許可 | - | -| `NYASH_VERIFY_BARRIER_STRICT=1` | OFF | Barrier配置厳密チェック | - | -| `NYASH_VERIFY_EDGE_COPY_STRICT=1` | OFF | Edge copy検証 | - | -| `NYASH_VERIFY_RET_PURITY=1` | OFF | Return block純粋性検証 | - | -| `NYASH_BREAKFINDER_SSA_TRACE=1` | OFF | SSA詳細トレース(BreakFinderBox等) | - | +### ダンプの使い分け +- 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 -# Dev環境で厳密検証(arity不一致でビルドエラー) -NYASH_ME_CALL_ARITY_STRICT=1 cargo test +# 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 -# トレースのみ(warning表示、エラーにはしない) -NYASH_STATIC_CALL_TRACE=1 ./target/release/hakorune program.hako - -# PHI検証を一時的にスキップ -NYASH_VERIFY_ALLOW_NO_PHI=1 ./target/release/hakorune program.hako - -# SSA詳細トレース(BreakFinderBox等のデバッグ) -NYASH_BREAKFINDER_SSA_TRACE=1 cargo test mir_stage1_using_resolver_verify 2>&1 | grep "breakfinder/ssa" +# 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 ``` --- -## Stage-1 CLI制御系 +## Parser / using -Stage-1 CLI(Nyash selfhosting compiler)の制御用環境変数。 - -| 環境変数 | デフォルト | 用途 | 追加Phase | -|---------|----------|-----|-----------| -| `NYASH_USE_STAGE1_CLI=1` | OFF | Stage-1 CLI有効化 | Phase 25.1 | -| `STAGE1_CLI_DEBUG=1` | OFF | Stage-1 CLI詳細ログ | Phase 25.1 | -| `STAGE1_EMIT_PROGRAM_JSON=1` | OFF | Program JSON出力モード | Phase 25.1 | -| `STAGE1_EMIT_MIR_JSON=1` | OFF | MIR JSON出力モード | Phase 25.1 | -| `STAGE1_BACKEND={vm\|llvm\|pyvm}` | `vm` | 実行バックエンド指定 | Phase 25.1 | -| `STAGE1_SOURCE=` | - | ソースファイルパス | Phase 25.1 | -| `STAGE1_SOURCE_TEXT=` | - | ソーステキスト(inline指定) | Phase 25.1 | -| `STAGE1_PROGRAM_JSON=` | - | Program JSONパス | Phase 25.1 | - -### 使用例 - -```bash -# Stage-1 CLI経由で.hakoファイルをコンパイル -NYASH_USE_STAGE1_CLI=1 STAGE1_SOURCE=program.hako \ - ./target/release/hakorune lang/src/runner/stage1_cli.hako - -# Program JSON生成 -STAGE1_EMIT_PROGRAM_JSON=1 STAGE1_SOURCE=program.hako \ - ./target/release/hakorune lang/src/runner/stage1_cli.hako - -# デバッグログ付き -STAGE1_CLI_DEBUG=1 NYASH_USE_STAGE1_CLI=1 \ - ./target/release/hakorune program.hako -``` +| 変数 | デフォルト | 適用経路 | 説明 | +| --- | --- | --- | --- | +| `NYASH_PARSER_STAGE3=1` | OFF | Any | Stage-3 構文を許可 | +| `HAKO_PARSER_STAGE3=1` | OFF | Any | `.hako` 向け Stage-3 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 ソースをダンプ | --- -## Parser制御系 +## Runner / backend 選択 -パーサーの動作制御用環境変数。 - -| 環境変数 | デフォルト | 用途 | 追加Phase | -|---------|----------|-----|-----------| -| `NYASH_PARSER_STAGE3=1` | OFF | Stage-3 parser有効化 | Phase 25.3 | -| `HAKO_PARSER_STAGE3=1` | OFF | Stage-3 parser有効化(.hako側) | Phase 25.3 | -| `NYASH_ENABLE_USING=1` | OFF | using文サポート有効化 | Phase 25.1 | -| `HAKO_ENABLE_USING=1` | OFF | using文サポート有効化(.hako側) | Phase 25.1 | -| `HAKO_STAGEB_APPLY_USINGS=1` | OFF | Stage-B using適用 | Phase 25.1 | - -### 使用例 - -```bash -# using文を使ったプログラムをパース -NYASH_PARSER_STAGE3=1 NYASH_ENABLE_USING=1 \ - ./target/release/hakorune program_with_using.hako -``` +| 変数 | デフォルト | 適用経路 | 説明 | +| --- | --- | --- | --- | +| `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 | 子プロセスへ透過する追加引数 | -| 環境変数 | デフォルト | 用途 | 追加Phase | -|---------|----------|-----|-----------| -| `NYASH_CLI_VERBOSE=1` | OFF | 詳細診断情報出力 | - | -| `NYASH_VM_TRACE=1` | OFF | VM実行トレース出力 | - | -| `NYASH_VM_DUMP_MIR=1` | OFF | VM実行前MIR出力 | - | -| `NYASH_DUMP_JSON_IR=1` | OFF | JSON IR出力 | - | -| `NYASH_STAGE1_MIR_DUMP=1` | OFF | Stage-1 MIR出力 | Phase 25.x | -| `NYASH_STAGE1_SCAN_GE=1` | OFF | Compare Ge命令スキャン | Phase 25.x | -| `NYASH_TO_I64_DEBUG=1` | OFF | to_i64変換デバッグ | Phase 25.x | -| `NYASH_FUNCSCANNER_DEBUG=1` | OFF | FuncScanner詳細ログ | Phase 25.3 | -| `NYASH_JOINIR_EXPERIMENT=1` | OFF | JoinIR実験モード(MIR→JoinIR変換テストを有効化) | Phase 26-H/27 | - -### 使用例 +### Ny compiler 経路の観測テンプレート (Phase 29) ```bash -# VM実行トレース -NYASH_VM_TRACE=1 ./target/release/hakorune program.hako 2>&1 | grep "vm-trace" - -# MIR確認(複数手法) -NYASH_VM_DUMP_MIR=1 ./target/release/hakorune program.hako -./target/release/hakorune --dump-mir program.hako -./target/release/hakorune --emit-mir-json debug.json program.hako - -# Stage-1 CLI + MIRダンプ -NYASH_STAGE1_MIR_DUMP=1 cargo test mir_stage1_cli_emit_program_min - -# JoinIR実験(テスト限定) -NYASH_JOINIR_EXPERIMENT=1 cargo test --release mir_joinir_funcscanner_trim_auto_lowering -- --ignored +# Ny compiler 経路で Program(JSON v0)→MIR→dump を観測 +NYASH_USE_NY_COMPILER=1 \ +NYASH_PARSER_STAGE3=1 HAKO_PARSER_STAGE3=1 \ +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` + +注意: `apps/selfhost/compiler/compiler.hako` が存在しない場合、preferred child process 経路は発火しない。 + --- -## プラグイン・Box制御系 +## GC / Runtime -プラグインとBox factoryの制御用環境変数。 - -| 環境変数 | デフォルト | 用途 | 追加Phase | -|---------|----------|-----|-----------| -| `NYASH_DISABLE_PLUGINS=1` | OFF | プラグイン無効化 | - | -| `NYASH_BOX_FACTORY_POLICY={builtin_first\|plugin_first}` | `builtin_first` | Box factory優先順位 | Phase 15.5 | -| `NYASH_FILEBOX_MODE={auto\|plugin\|builtin}` | `auto` | FileBox実装選択 | Phase 15.5 | - -### 使用例 - -```bash -# プラグイン無効で実行(コアBox経路のみ) -NYASH_DISABLE_PLUGINS=1 ./target/release/hakorune program.hako - -# Plugin優先でBox生成 -NYASH_BOX_FACTORY_POLICY=plugin_first ./target/release/hakorune program.hako -``` +| 変数 | デフォルト | 適用経路 | 説明 | +| --- | --- | --- | --- | +| `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 -- **MIRログ観測**: [docs/development/architecture/mir-logs-observability.md](../development/architecture/mir-logs-observability.md) -- **Phase 25.4計画**: [docs/private/roadmap2/phases/phase-25.4-naming-cli-cleanup/README.md](../development/roadmap/phases/phase-25.4-naming-cli-cleanup/README.md) -- **MIR検証システム**: [src/mir/verification/](../../src/mir/verification/) +| 変数 | デフォルト | 適用経路 | 説明 | +| --- | --- | --- | --- | +| `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 実装選択 | + +--- + +## 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 不一致でエラー | + +--- + +参考: [docs/development/architecture/mir-logs-observability.md](../development/architecture/mir-logs-observability.md) / [src/mir/verification/](../../src/mir/verification/) diff --git a/src/runner/selfhost.rs b/src/runner/selfhost.rs index 89ad7726..cde6b32d 100644 --- a/src/runner/selfhost.rs +++ b/src/runner/selfhost.rs @@ -22,6 +22,16 @@ impl NyashRunner { if let Some(ext) = path.extension().and_then(|s| s.to_str()) { match ext { "ny" | "nyash" => { /* continue */ } + "hako" => { + // Opt-in: allow .hako to flow through Ny compiler when explicitly requested. + if !crate::config::env::use_ny_compiler() { + crate::cli_v!( + "[ny-compiler] skip selfhost pipeline for .hako (ext={}); enable NYASH_USE_NY_COMPILER=1 to force", + ext + ); + return false; + } + } _ => { crate::cli_v!( "[ny-compiler] skip selfhost pipeline for non-Ny source: {} (ext={})", @@ -177,10 +187,15 @@ impl NyashRunner { // This avoids inline embedding pitfalls and supports Stage-3 gating via args. { use crate::runner::modes::common_util::selfhost::{child, json}; + let verbose_level = crate::config::env::dump::cli_verbose_level(); let exe = std::env::current_exe() .unwrap_or_else(|_| std::path::PathBuf::from("target/release/nyash")); let parser_prog = std::path::Path::new("apps/selfhost/compiler/compiler.hako"); if parser_prog.exists() { + // Phase 28.2: observation log (NYASH_CLI_VERBOSE>=2) + if verbose_level >= 2 { + eprintln!("[selfhost/ny] spawning Ny compiler child process: {}", parser_prog.display()); + } // Build extra args forwarded to child program let mut extra_owned: Vec = Vec::new(); if crate::config::env::ny_compiler_min_json() { @@ -233,11 +248,34 @@ impl NyashRunner { ("HAKO_ALLOW_USING_FILE", "0"), ], ) { + // Phase 28.2: observation log - JSON received + if verbose_level >= 2 { + eprintln!("[selfhost/ny] received Program(JSON v0), size={} bytes", line.len()); + } match json::parse_json_v0_line(&line) { Ok(module) => { - if crate::config::env::cli_verbose() { - if crate::config::env::cli_verbose() { - super::json_v0_bridge::maybe_dump_mir(&module); + // Phase 28.2: observation log - before maybe_dump_mir + if verbose_level >= 2 { + let dump_path = crate::config::env::dump::rust_mir_dump_path(); + eprintln!( + "[selfhost/ny] lowering Program(JSON v0) → MIR via json_v0_bridge (funcs={})", + module.functions.len() + ); + eprintln!( + "[selfhost/ny] calling maybe_dump_mir (RUST_MIR_DUMP_PATH={:?}, cli_verbose={})", + dump_path.as_deref().unwrap_or(""), + crate::config::env::cli_verbose() + ); + } + super::json_v0_bridge::maybe_dump_mir(&module); + // Phase 28.2: observation log - after maybe_dump_mir + if verbose_level >= 2 { + if let Some(ref path) = crate::config::env::dump::rust_mir_dump_path() { + if std::path::Path::new(path).exists() { + eprintln!("[selfhost/ny] ✅ MIR dump file created: {}", path); + } else { + eprintln!("[selfhost/ny] ⚠️ MIR dump file NOT created: {}", path); + } } } let emit_only = crate::config::env::ny_compiler_emit_only();