Files
hakorune/docs/development/roadmap/phases/phase-25.3-funcscanner/README.md
nyash-codex 3a82633924 refactor(funcscanner): Region+next_i パターン統一 & SSA テスト追加
**FuncScanner .hako 側改善**:
- scan_all_boxes を Region + next_i 形式に統一(continue 多発による SSA/PHI 複雑さ削減)
- インデント修正(タブ→スペース統一)
- デバッグ print 削除

**SSA テスト追加**:
- lang/src/compiler/tests/funcscanner_scan_methods_min.hako
- src/tests/mir_funcscanner_ssa.rs (scan_methods & fib_min SSA デバッグテスト)

**Phase 25.3 ドキュメント**:
- docs/development/roadmap/phases/phase-25.3-funcscanner/ 追加

**関連**: Phase 25.3 FuncScanner 箱化準備作業

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 06:38:43 +09:00

152 lines
9.0 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.

# Phase 25.3 — FuncScanner / StageB defs 安定化
## スコープ / ゴール
- 対象レイヤ
- `.hako` 側:
- `lang/src/compiler/entry/func_scanner.hako` (`FuncScannerBox`)
- `lang/src/compiler/entry/compiler_stageb.hako` (`StageBFuncScannerBox`, `StageBDriverBox`)
- 必要に応じて `lang/src/compiler/tests/funcscanner_fib_min.hako` などのテスト用ハーネス
- Rust 側:
- 既存の LoopForm v2 / LoopSnapshotMergeBox / JSON front は「完成済みの土台」として利用するだけで、原則ここでは触らない。
- ゴール
- Rust VM 検証付きで FuncScanner を安定させる:
- `NYASH_VM_VERIFY_MIR=1``lang/src/compiler/tests/funcscanner_fib_min.hako` を実行したときに、
- `FuncScannerBox.scan_all_boxes/1` で Undefined value が発生しないこと。
- fib 風ソースに対して `defs``TestBox.fib` / `Main.main` が含まれること(箱レベルの振る舞いが安定)。
- StageB 側からも同じ結果が得られる:
- `tools/smokes/v2/profiles/quick/core/phase251/stageb_fib_program_defs_canary_vm.sh` を実行すると、
- `defs``TestBox.fib` が存在し、
- その `body``Loop` ノードが含まれていること。
- Loop/PHI の意味論は **LoopFormBuilder + LoopSnapshotMergeBox** に完全委譲したまま、
- FuncScanner / StageB は「テキストスキャンJSON 組み立て」の箱として綺麗に分離された状態にする。
## すでに前提としている状態
- LoopForm v2 / PHI / snapshot:
- ループ構造・PHI・break/continue スナップショットの意味論は、
- `src/mir/loop_builder.rs`
- `src/mir/phi_core/loopform_builder.rs`
- `src/mir/phi_core/loop_snapshot_merge.rs`
に集約されており、AST ルート / JSON ルートともに同じ実装を使っている。
- canonical `continue_merge` ブロック(ループごとに 1 つが導入済みで、backedge は
- `latch``header`
- `continue_merge``header`
の 2 本に限定されている。
- JSON v0 front:
- `src/runner/json_v0_bridge/lowering/loop_.rs` は LoopForm v2 の **薄いアダプタ**になっている。
- ブロック ID の確保
- `vars` / snapshot の受け渡し
- `LoopFormOps` 実装 (`LoopFormJsonOps`)
だけを担い、PHI 生成は LoopForm v2 に一元化された。
- 25.1e / 25.1q / 25.2:
- 変数スコープCarrier / Pinned / Invariant / BodyLocalInOutと Env_in/Env_out モデルは文書と実装が一致している。
- JSON ループ用のスモーク(`tests/json_program_loop.rs`はすでに緑で、ループbreak/continuebodylocal exit に対して MIR 検証が通っている。
この Phase 25.3 では、「LoopForm / JSON front は触らずに、FuncScanner / StageB ラインをその上に綺麗に載せる」ことが目的になる。
## タスク一覧
### 1. FuncScanner fib 最小ハーネスSSA バグの確認完了)
- 対象:
- `lang/src/compiler/tests/funcscanner_fib_min.hako`
- `FuncScannerBox.scan_all_boxes/1`Rust lowering 時の MIR
- 現状:
- `NYASH_VM_VERIFY_MIR=1` 付きで `funcscanner_fib_min.hako` を実行しても、
Undefined value / `ssa-undef-debug` は発生していないLoopForm v2 / LoopSnapshotMergeBox 修正で解消済み)。
- `cargo test mir_funcscanner_fib_min_ssa_debug` も緑で、FuncScanner 単体の SSA 破綻は再現しない。
- このフェーズで導入した `__mir__` ロガーは、今後の再現時に経路観測用フックとして利用できる状態になっている。
- 位置づけ:
- 「FuncScanner + LoopForm v2 での Undefined Value バグの根治」は完了とみなし、
以降は StageB 側の defs 欠落(`defs=[]`)を主ターゲットとする。
- 追加の SSA ガードme-call 周り):
- Rust 側では `MirBuilder::handle_me_method_call``MeCallPolicyBox` によって箱化し、
- `Box.method/Arity` lowered 関数が存在する場合は、従来どおり `me` を先頭引数とする Global callインスタンス文脈の me-call
- 存在しない場合は、`handle_static_method_call(cls, method, arguments)` にフォールバックし、
static helper`FuncScannerBox._parse_params` / `_strip_comments` など)への呼び出しとして扱うようにした。
- これにより、static box 文脈で「実体のない me を receiver とする Method call」が生成される経路が閉じられ、
FuncScannerBox._scan_methods/4 + `_parse_params` + `_strip_comments` のラインは SSA 的に安全になっている。
### 2.5. MIR ロガー (__mir__) による観測Dev 専用)
- 位置づけ:
- Phase 25.3 では、FuncScanner / StageB のような `.hako` 側ロジックを LoopForm v2 上でデバッグしやすくするため、
専用の MIR ログ構文 `__mir__` を導入する(実行意味論には影響しない dev 専用 Hook
- 構文:
- `__mir__.log("label", v1, v2, ...)`
- lowering 時に `MirInstruction::DebugLog { message: "label", values: [v1, v2, ...] }` へ変換される。
- `__mir__.mark("label")`
- 値無し版の `DebugLog` として `debug_log "label"` だけを差し込む。
- 振る舞い:
- VM 実行時は `NYASH_MIR_DEBUG_LOG=1` のときだけ
- `[MIR-LOG] label: %id=value ...`
の形式でログ出力され、それ以外のときは完全に無視されるEffect::Debug のみ)。
- LoopForm / PHI / snapshot には関与せず、単に MIR に 1 命令追加するだけの観測レイヤ。
- 実装ポイント:
- `src/mir/builder/calls/build.rs` 内の `build_method_call_impl` で、
- receiver が `__mir__``__mir__.log/mark` を検出し、
- `try_build_mir_debug_call``DebugLog` 命令に直接 lowering している。
FuncScanner / StageB のデバッグ時には、`scan_all_boxes` のループ頭や `box` 検出直後に
`__mir__.log("funcscan/head", i, in_str, in_block)` などを埋め込み、VM 実行ログと合わせて
「どの経路で環境スナップショットやステートが崩れているか」を観測する想定だよ。
### 3. StageB FuncScanner との整合性確保(主ターゲット)
- 対象:
- `lang/src/compiler/entry/compiler_stageb.hako`
- `StageBFuncScannerBox.scan_all_boxes`
- `StageBFuncScannerBox._find_matching_brace`
- `StageBDriverBox.main` 内の defs 組み立てロジック
- やること:
- `StageBFuncScannerBox` のロジックを、可能な範囲で `FuncScannerBox` と共有・委譲する方向に寄せる。
- `_find_matching_brace` などはすでに FuncScannerBox に委譲済みなので、
残りのスキャンロジックも「同じアルゴリズム / 同じ境界条件」で動くように整理する。
- `HAKO_STAGEB_FUNCSCAN_TEST=1``StageBFuncScannerBox.test_fib_scan()` を走らせ、
- `brace1/brace2` の close_idx が正しく取れること。
- `defs_len > 0` となり、`TestBox.fib` / `Main.main` がログに出ること。
- そのうえで `StageBDriverBox.main``StageBFuncScannerBox.scan_all_boxes(src)` の結果を
- Program(JSON v0).defs に正しく注入できているかを確認する。
- ここでの主なバグは「SSA ではなく、StageB が fib ソースから defs を組み立てきれていないこと」なので、
ループ構造や LoopForm には手を入れず、StageB 側のテキスト処理と defs 生成パスを中心に見る。
### 4. fib defs canary & ドキュメント更新
- 対象:
- `tools/smokes/v2/profiles/quick/core/phase251/stageb_fib_program_defs_canary_vm.sh`
- `docs/development/roadmap/phases/phase-25.1q/README.md`
- `CURRENT_TASK.md`
- やること:
- canary スクリプトで:
- `Program.kind == "Program"`
- `defs``TestBox.fib` が存在すること。
- `TestBox.fib.body``Loop` ノードが含まれること。
を満たした状態で `rc=0` になるまで確認する。
- Phase 25.1q / 25.2 の README には、
- 「loop/PHI/スナップショットの SSOT は LoopForm v2 + LoopSnapshotMergeBox」
- 「Phase 25.3 で FuncScanner / StageB defs もこの土台の上に載せた」
というつながりを 1〜2 行で追記する。
- `CURRENT_TASK.md` には:
- Phase 25.3 のタスク完了状況FuncScanner fib / StageB fib canary 緑)と、
- その後に繋がる Stage1 UsingResolver / Stage1 CLI selfhost ラインへのブリッジ
を短く整理しておく。
---
この Phase 25.3 は、
- LoopForm v2 / JSON front を「箱として完成済み」とみなし、
- その上で FuncScanner / StageB defs ラインを **構造的に**安定させる
ための仕上げフェーズだよ。
ループや PHI の意味論は触らず、テキストスキャンとスコープ設計を整えることで、selfhosting ライン全体の足場を固めるのが狙い。+