Files
hakorune/CURRENT_TASK.md

583 lines
44 KiB
Markdown
Raw Normal View History

docs(phase25.4): Phase 25.4 ロードマップ・ドキュメント整備 📋 Phase 25.4 計画確定: NamingBox SSOT化 & CLI設定箱 ✅ 追加ドキュメント: - docs/development/roadmap/phases/phase-25.4-naming-cli-cleanup/ - README.md: Phase 25.4 全体計画 - A. NamingBox SSOT化(完了) - B. Stage-1 CLI 設定箱(次フェーズ) - C. MIR ログ観測リスト(次フェーズ) - docs/development/roadmap/phases/phase-21.7-normalization/README.md - Phase 21.7 との関連性追記 - docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md - Phase 25.1 完了記録更新 - CURRENT_TASK.md: タスク進捗更新 - Phase 25.4-A 完了 - Phase 25.4-B/C 準備完了 - MIR Builder 型混乱バグ調査完了記録 🎯 Phase 25.4 戦略: 0. 共通方針 - 既定挙動は変えない(Fail-Fast + テスト緑キープ) - 新規ロジックは「小さな箱」に閉じ込める - まずドキュメント・構造を揃えてからコード A. NamingBox SSOT化 ✅ 完了 - static/global 名前決定を src/mir/naming.rs に一本化 - Builder/VM で統一ルール使用 B. Stage-1 CLI 設定箱(次フェーズ) - env.get() を Stage1CliConfigBox に集約 - mode/backend/source 等を Config として管理 C. MIR ログ観測リスト(次フェーズ) - __mir__.log の一覧化・分類 - 将来の MirLogBox 化準備 📊 テスト確認コマンド: - cargo test -q mir_static_box_naming --lib - cargo test -q mir_stage1_cli_entry_ssa_smoke --lib - tools/smokes/v2/run.sh --profile quick Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 09:02:30 +09:00
# Current Task — Phase 21.8 / 25 / 25.1 / 25.2 / 25.4 Snapshot2025-11-18 時点)
> このファイルは「今どこまで終わっていて、次に何をやるか」を 1000 行以内でざっくり把握するためのスナップショットだよ。
> 詳細な履歴やログは `git log CURRENT_TASK.md` からいつでも参照できるようにしておくね。
---
## 0. 現在地ざっくり
- フェーズ軸:
- **21.8**: Numeric Core / Core-15 まわりの安定化(既に日常的には安定運用)。
- **25.x**: Stage0/Stage1/StageB / Selfhost ラインのブートストラップと LoopForm v2 / LoopSSA v2 まわりの整備。
- **25.1 系**: StageB / Stage1 / selfhost 向けに、Rust MIR / LoopForm v2 / LoopSSA v2 を段階的に整える長期ライン。
- Rust 側:
- LoopForm v2 + ControlForm + Conservative PHI は、代表テストStage1 UsingResolver / StageB 最小ループ)ではほぼ安定。
- 静的メソッド呼び出し規約と `continue` 絡みの PHI は 25.1m までで根治済み。
- .hako 側:
- StageB コンパイラ本体 / LoopSSA v2 / BreakFinderBox / PhiInjectorBox はまだ部分実装。
- JSON v0 / selfhost ルートは Rust 側の LoopForm v2 規約に追いつかせる必要がある。
- StageB / FuncScanner ライン:
- Phase 25.3 をクローズし、`stageb_fib_program_defs_canary_vm.sh` が緑(`defs``TestBox.fib/Main.main`、fib.body.body[*] に `Loop`)。
- StageB は block パーサ優先 + defs を Block 包みで構造化。次手: Stage1 UsingResolver ループの Region+next_i 揃え / Stage1 CLI program-json selfhost 準備。
---
## 1. 最近完了した重要タスク
feat(phi): Phase 26-E-2 - PhiBuilderBox If PHI生成完全実装 Phase 26-E Phase 2 完了: PhiBuilderBox による If PHI生成SSOT統一化 **実装内容:** 1. PhiBuilderBox 作成 (444行) - If PHI生成: generate_if_phis() 完全実装 - Conservative戦略: void emission 含む完全対応 - 決定的順序: BTreeSet/BTreeMap で非決定性排除 2. PhiBuilderOps trait (7メソッド) - 最小PHI生成インターフェース - new_value, emit_phi, update_var, get_block_predecessors - emit_void, set_current_block, block_exists 3. loop_builder.rs 統合 - PhiBuilderOps trait 実装 (Ops構造体) - If PHI呼び出し箇所統合 (line 1136-1144) - Legacy if_phi::merge_modified_with_control 置換完了 **技術的成果:** - Conservative PHI生成: 全経路カバー + void fallback - 決定的変数順序: BTreeSet で変更変数をソート - 決定的PHI入力順序: pred_bb.0 でソート - テスタビリティ: MockOps でユニットテスト可能 **Phase 3 設計方針 (ChatGPT提案):** - trait 階層化: LoopFormOps: PhiBuilderOps - blanket impl: impl<T: LoopFormOps> PhiBuilderOps for T - PhiBuilderBox: PhiBuilderOps 最小セットのみに依存 - 段階的移行: 既存コード保護しながら統一化 **削減見込み:** - Phase 2: -80行 (If側重複削除) - Phase 4: -287行 (loop_phi.rs Legacy削除) - 合計: -367行 (純削減) **関連ファイル:** - src/mir/phi_core/phi_builder_box.rs (新規, 444行) - src/mir/phi_core/mod.rs (module登録) - src/mir/loop_builder.rs (PhiBuilderOps実装) - CURRENT_TASK.md (Phase 26-E記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 07:05:21 +09:00
### 1-01. Phase 26-E — PhiBuilderBox SSOT統一化進行中 2025-11-22
**目的**
- PHI生成ロジックを単一責務箱PhiBuilderBoxに集約
- If/Loop両対応の統一インターフェース提供
- Conservative戦略 + BTreeSet/BTreeMap で決定性向上
**🎯 Phase 26-E 進捗状況**2025-11-22
- **✅ Phase 1**: PhiBuilderBox 骨格作成444行、ControlForm対応
- **✅ Phase 2**: If PHI生成完全実装Conservative戦略、決定的順序保証
- **🔄 Phase 3**: trait 階層化設計ChatGPT提案、次タスク
- **⏳ Phase 4**: Legacy削除loop_phi.rs 287行、将来タスク
**Phase 2 実装内容2025-11-22完了**
1. **PhiBuilderBox作成** (src/mir/phi_core/phi_builder_box.rs, 444行)
- If PHI生成: `generate_if_phis()` 完全実装
- Conservative戦略: void emission 含む完全対応
- 決定的順序: BTreeSet/BTreeMap で非決定性排除
2. **PhiBuilderOps trait** (7メソッド)
- 最小PHI生成インターフェース
- テスタビリティ向上(モック可能)
3. **loop_builder.rs 統合** (src/mir/loop_builder.rs)
- PhiBuilderOps trait 実装Ops構造体
- If PHI呼び出し箇所統合line 1136-1144
**Phase 3 設計方針ChatGPT提案、2025-11-22**
- **trait 階層化**: `LoopFormOps: PhiBuilderOps` で継承関係を明確化
- **blanket impl**: `impl<T: LoopFormOps> PhiBuilderOps for T` でアダプタ作成
- **PhiBuilderBox**: PhiBuilderOps 最小セットのみに依存
- **段階的移行**: 既存コード保護しながら統一化
**削減見込み**
- Phase 2: -80行If側重複削除
- Phase 4: -287行loop_phi.rs Legacy削除
- **合計**: -367行純削減
**次のステップPhase 3**
1. `pub trait LoopFormOps: PhiBuilderOps` に変更
2. blanket impl でアダプタ実装1箇所
3. PhiBuilderBox を If/Loop 統一インターフェースに
4. 既存テスト100%維持確認
**関連ファイル**
- [phi_builder_box.rs](src/mir/phi_core/phi_builder_box.rs) - 444行
- [loop_builder.rs](src/mir/loop_builder.rs) - PhiBuilderOps実装
- [exit_phi_builder.rs](src/mir/phi_core/exit_phi_builder.rs) - 779行Phase 26-D完成
- [header_phi_builder.rs](src/mir/phi_core/header_phi_builder.rs) - 548行Phase 26-C-2完成
---
### 1-00. Phase 21.7 — Static Box Methodization完了 2025-11-21, 既定ON に移行)
**目的**
- static box 内の呼び出しを NamingBox/Method まわりで一貫して扱えるようにする。
- Global("BoxName.method/arity") を Method{receiver = static singleton} に寄せる(トグル制御)。
**🎯 Phase 21.7++ 計画**2025-11-22 全フェーズ完了!🎊)
- **NamingBox SSOT 統一化チェックリスト**: [phase-21.7-naming-ssot-checklist.md](docs/development/current/main/phase-21.7-naming-ssot-checklist.md)
- StringUtils using 解決バグ修正2025-11-22, commit f4ae1445を踏まえた改善計画
- **✅ Phase 0観測ライン**: Silent Failure 根絶完了commit 63012932
- **✅ Phase 1基盤整備**: StaticMethodId SSOT 基盤確立commit 96c1345e
- **✅ Phase 2VM統一**: VM 名前解決 SSOT 準拠commit 1b413da5
- **✅ Phase 3全体統一**: Builder 側統一、素手 split 根絶commit c8ad1dae
- **✅ Phase 4ドキュメント**: README・トラブルシューティングガイド整備commit 806e4d72
- **累計工数**: 10時間進捗率: 50-67%
**Phase 0-4 実装内容2025-11-22 全完了)**
1. **Phase 0: 観測ライン緊急構築** (commit 63012932)
- TOML parse エラー即座表示pipeline.rs
- VM 関数ルックアップ「Did you mean?」提案global.rs
- using not found 詳細化strip.rs
- **効果**: Silent Failure 根絶、デバッグ時間が時間→分に短縮
2. **Phase 1: StaticMethodId SSOT 基盤** (commit 96c1345e)
- `StaticMethodId` 構造体導入naming.rs:86-248
- parse/format/with_arity ヘルパー実装
- 包括的テスト13ケース全PASS
- **効果**: 関数名パース/フォーマット一元化、型安全化
3. **Phase 2: VM 統一** (commit 1b413da5)
- global.rs を StaticMethodId ベース化
- デバッグログ強化NYASH_DEBUG_FUNCTION_LOOKUP=1
- テスト全通過349 passed, 退行なし)
- **効果**: arity バグ根治、Hotfix 卒業
4. **Phase 3: 全体統一** (commit c8ad1dae)
- unified_emitter.rs の methodization を StaticMethodId 化
- known.rs の split_once 全置き換え2箇所
- **効果**: 素手 split 根絶、Builder 側完全統一、コード50%削減
5. **Phase 4: ドキュメント整備** (commit 806e4d72)
- Phase 21.7 README に完了セクション追加60行
- トラブルシューティングガイド作成200+行、新規)
- チェックリスト進捗サマリー更新
- **効果**: 再発防止、開発者オンボーディング改善
**Phase 0-2 以前の実装内容**
1. **NamingBox decode 関数追加** (Step 1: commit a13f14ce)
- `decode_static_method(func_name: &str) -> Option<(&str, &str, usize)>`
- `is_static_method_name(func_name: &str) -> bool`
- "BoxName.method/arity" 形式をパースして (box_name, method, arity) に分解。
2. **Hotfix 7 修正** (Step 2: commit a13f14ce)
- `unified_emitter.rs` の receiver 追加ロジックを修正。
- StaticCompiler box_kind のメソッドで、static box method (decode可能な名前) の場合は receiver を追加しない。
- instance method のみ receiver を args の先頭に追加するようガード実装。
3. **Methodization 実装** (Step 3: commit b5cd05c2)
- `builder.rs`: `static_box_singletons: HashMap<String, ValueId>` フィールド追加。
- `unified_emitter.rs`: HAKO_MIR_BUILDER_METHODIZE=1 で有効化。
- Callee::Global(name) を decode して static box method 判定。
- シングルトンインスタンス (NewBox) をキャッシュ生成。
- Callee::Method{receiver=singleton} に変換。
**動作確認**
- デフォルト (OFF): `call_global Calculator.add/2` (既存挙動維持)
- トグル (ON): `new Calculator() → call %singleton.add(...)` (methodization)
- RC=0 両モード動作確認済み: `apps/tests/phase217_methodize_test.hako`
**環境変数**
- `HAKO_MIR_BUILDER_METHODIZE=0/1`: methodization 制御。既定ON未設定 or "1")、"0" のときのみ無効化。
- `NYASH_METHODIZE_TRACE=1`: Global→Method 変換ログ出力
**次タスクPhase 21.7++ Phase 3-4**10-15時間見込み
- **Phase 3: 全体統一**
- MIR Builder 側を StaticMethodId 統一builder/calls/unified_emitter.rs 等)
- 素手 split 置き換え(`rg '"\."' --type rust src/mir/builder/`
- 100-200 行削減見込み
- **Phase 4: ドキュメント化**
- SSOT 設計書更新
- 移行ガイド作成
- チームレビュー
- **長期**: NamingBox/UnifiedCallEmitter/VM の 3 点で「名前と arity の SSOT」完全統一。
### 1-0. Phase 25.3 — FuncScanner / StageB defs 安定化(完了)
**目的**
- StageB / FuncScanner ラインで defs が欠落したり Loop が脱落する問題を塞ぎ、selfhost 側の canary を緑に戻す。
**やったこと**
- StageBDriverBox.main:
- main 本文を `{…}` で包んだ block パーサ優先で Program(JSON) に組み立て、defs には `{"type":"Block","body":[…]}` 形式で埋め込むよう整理。
- Program パーサ fallback は `HAKO_STAGEB_PROGRAM_PARSE_FALLBACK=1` の opt-in に封じ込めskip_ws 崩れを回避)。
- StageBFuncScannerBox._scan_methods:
- block パーサ優先に統一し、Program パーサは `HAKO_STAGEB_FUNC_SCAN_PROG_FALLBACK=1` でのみ有効化。
- defs パラメータに必ず `me` を足す従来挙動は維持TestBox/Main いずれも同型で出力)。
- Rust 層の追加変更なしLoopForm v2 / LoopSnapshotMergeBox をそのまま利用)。
**結果**
- `tools/smokes/v2/profiles/quick/core/phase251/stageb_fib_program_defs_canary_vm.sh` が安定して PASS。
- `Program.kind == "Program"`
- `defs``TestBox.fib` / `Main.main` を保持していること。
- `TestBox.fib.body.body[*]``Loop` ノードが含まれること。
を満たした状態で `rc=0` になることを確認。
- FuncScanner / StageB 経由の fib defs ラインは LoopForm v2 + LoopSnapshotMergeBox 上で構造的に安定したとみなし、Phase 25.3 はクローズ。
- 次フェーズの入口が整理できたので、Stage1 UsingResolver ループRegion+next_i 形)と Stage1 CLI program-json/selfhost 導線に着手可能。
### 1-1. Phase 25.1m — Static Method / LoopForm v2 continue + PHI Fix完了
**目的**
- 静的メソッド呼び出し時の「暗黙レシーバ引数ずれ」バグと、LoopForm v2 経路における `continue` + header PHI の欠落を根本から直す。
**Rust 側(静的メソッド / 暗黙レシーバ / JSON v0 Bridge**
- `src/mir/function.rs::MirFunction::new`
- 暗黙 receiver 判定を是正し、**「第 1 パラメータが Box 型の関数だけ」をインスタンスメソッド with receiver** とみなす。
- 非 Box 型(`String`, `Integer` など)で始まるパラメータ列の関数は、暗黙レシーバなしの静的メソッド / Global 関数として扱うように変更。
- その結果:
- `static box TraceTest { method log(label) { ... } }` に対して `TraceTest.log("HELLO")` を呼ぶと、
`label``"HELLO"` が正しく入る(以前は `label = null` になっていた)。
- `src/mir/builder/decls.rs::build_static_main_box`
- `Main.main(args)` を「静的エントリ関数」に lower する経路を **`NYASH_BUILD_STATIC_MAIN_ENTRY=1` のときだけ有効** にし、
通常の VM 実行では wrapper `main()` を正規エントリとして扱うように整理。
- これにより、「`Main.main(args)` 版ではループが 1 度も回らず `return 0` で終わる」バグを解消。
- JSON v0 Bridge 経由の Box メソッドStage1/StageB defs:
- `src/runner/json_v0_bridge/lowering.rs``prog.defs` の降下ロジックを調整し、
- `box_name != "Main"` の関数定義をインスタンスメソッドとして扱って `signature.params` に「暗黙 `me` + 明示パラメータ」を載せる。
- `func_var_map``me``func.params[0]` を事前バインドし、残りのパラメータ名を `params[1..]` に対応づける。
- これにより、`Stage1UsingResolverFull._build_module_map()` のように JSON では `params: []` でも Hako 側で `me._push_module_entry(...)` を使う関数について、
Rust VM 実行時に `me` が未定義ValueId(0))になるケースを構造的に防止。
**LoopForm v2continue + header PHI**
- `src/mir/phi_core/loopform_builder.rs::LoopFormBuilder::seal_phis`
- シグネチャを `seal_phis(ops, latch_id)``seal_phis(ops, latch_id, &continue_snapshots)` に拡張。
- preheader と latch に加え、`LoopBuilder` 側で記録している **`continue_snapshots` からの値も header PHI の入力** として統合。
- pinned / carrier いずれも、header の全 predecessor:
- `(preheader, preheader_copy)`
- `(continue_bb, value_at_continue)`
- `(latch, value_at_latch)`
を入力として持つようになり、balanced scan など「continue を含むループ」の SSA が正しく構成される。
- `src/mir/loop_builder.rs::build_loop_with_loopform`
- `let continue_snaps = self.continue_snapshots.clone();`
- `loopform.seal_phis(self, actual_latch_id, &continue_snaps)?;`
- という形で、LoopBuilder → LoopForm 側に `continue` スナップショットを橋渡し。
**ControlForm / LoopShape invariant**
- `src/mir/control_form.rs::LoopShape::debug_validate`debug ビルドのみ)
- 既存の:
- `preheader -> header` エッジ必須
- `latch -> header` バックエッジ必須
- に加えて、次の invariant を追加:
- `continue_targets` の各ブロックから `header` へのエッジが存在すること。
- `break_targets` の各ブロックから `exit` へのエッジが存在すること。
- これにより、LoopForm / LoopBuilder が `continue` / `break` 経路を誤配線した場合に、構造レベルで早期検知できる。
**テスト / 検証**
- MIR ユニットテスト:
- `src/mir/phi_core/loopform_builder.rs::tests::test_seal_phis_includes_continue_snapshots`
- LoopFormBuilder 単体で「preheader + continue + latch」が PHI 入力に含まれることを固定。
- `src/tests/mir_stageb_loop_break_continue_verifies`
- StageB 風の `loop + break/continue` パターンで MirVerifier 緑。
- `src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifies`
- LoopForm v2/PHI v2 経路(現在は既定実装)で Stage1 UsingResolver フル版が MirVerifier 緑。
- 実行観測:
- 開発用 Hako `loop_continue_fixed.hako`:
- 期待 `RC=3` / 実測 `RC=3`、PHI pred mismatch なし。
- StageB balanced scan:
- `StageBBodyExtractorBox` のバランススキャンループに trace を入れて 228 回イテレーションが回ること、
`ch == "{"` ブランチで `depth` / `i` を更新 → `continue` → 次イテレーションに **確実に戻っている** ことを確認。
feat(phase21.5/22.1): MirBuilder JsonFrag refactor + FileBox ring-1 + registry tests Phase 21.5 (AOT/LLVM Optimization Prep) - FileBox ring-1 (core-ro) provider: priority=-100, always available, no panic path - src/runner/modes/common_util/provider_registry.rs: CoreRoFileProviderFactory - Auto-registers at startup, eliminates fallback panic structurally - StringBox fast path prototypes (length/size optimization) - Performance benchmarks (C/Python/Hako comparison baseline) Phase 22.1 (JsonFrag Unification) - JsonFrag.last_index_of_from() for backward search (VM fallback) - Replace hand-written lastIndexOf in lower_loop_sum_bc_box.hako - SentinelExtractorBox for Break/Continue pattern extraction MirBuilder Refactor (Box → JsonFrag Migration) - 20+ lower_*_box.hako: Box-heavy → JsonFrag text assembly - MirBuilderMinBox: lightweight using set for dev env - Registry-only fast path with [registry:*] tag observation - pattern_util_box.hako: enhanced pattern matching Dev Environment & Testing - Dev toggles: SMOKES_DEV_PREINCLUDE=1 (point-enable), HAKO_MIR_BUILDER_SKIP_LOOPS=1 - phase2160: registry opt-in tests (array/map get/set/push/len) - content verification - phase2034: rc-dependent → token grep (grep -F based validation) - run_quick.sh: fast smoke testing harness - ENV documentation: docs/ENV_VARS.md Test Results ✅ quick phase2034: ALL GREEN (MirBuilder internal patterns) ✅ registry phase2160: ALL GREEN (array/map get/set/push/len) ✅ rc-dependent tests → content token verification complete ✅ PREINCLUDE policy: default OFF, point-enable only where needed Technical Notes - No INCLUDE by default (maintain minimalism) - FAIL_FAST=0 in Bring-up contexts only (explicit dev toggles) - Tag-based route observation ([mirbuilder/min:*], [registry:*]) - MIR structure validation (not just rc parity) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 19:42:42 +09:00
---
### 1-2. Phase 25.1k — LoopSSA v2 (.hako) & StageB harness 追従Rust 側はおおむね完了)
**目的**
- Rust 側の LoopForm v2 / ControlForm / Conservative PHI を SSOT としつつ、StageB / selfhost で使っている `.hako` 側 LoopSSA/BreakFinderBox/PhiInjectorBox をその規約に追従させる準備フェーズ。
feat(phase21.5/22.1): MirBuilder JsonFrag refactor + FileBox ring-1 + registry tests Phase 21.5 (AOT/LLVM Optimization Prep) - FileBox ring-1 (core-ro) provider: priority=-100, always available, no panic path - src/runner/modes/common_util/provider_registry.rs: CoreRoFileProviderFactory - Auto-registers at startup, eliminates fallback panic structurally - StringBox fast path prototypes (length/size optimization) - Performance benchmarks (C/Python/Hako comparison baseline) Phase 22.1 (JsonFrag Unification) - JsonFrag.last_index_of_from() for backward search (VM fallback) - Replace hand-written lastIndexOf in lower_loop_sum_bc_box.hako - SentinelExtractorBox for Break/Continue pattern extraction MirBuilder Refactor (Box → JsonFrag Migration) - 20+ lower_*_box.hako: Box-heavy → JsonFrag text assembly - MirBuilderMinBox: lightweight using set for dev env - Registry-only fast path with [registry:*] tag observation - pattern_util_box.hako: enhanced pattern matching Dev Environment & Testing - Dev toggles: SMOKES_DEV_PREINCLUDE=1 (point-enable), HAKO_MIR_BUILDER_SKIP_LOOPS=1 - phase2160: registry opt-in tests (array/map get/set/push/len) - content verification - phase2034: rc-dependent → token grep (grep -F based validation) - run_quick.sh: fast smoke testing harness - ENV documentation: docs/ENV_VARS.md Test Results ✅ quick phase2034: ALL GREEN (MirBuilder internal patterns) ✅ registry phase2160: ALL GREEN (array/map get/set/push/len) ✅ rc-dependent tests → content token verification complete ✅ PREINCLUDE policy: default OFF, point-enable only where needed Technical Notes - No INCLUDE by default (maintain minimalism) - FAIL_FAST=0 in Bring-up contexts only (explicit dev toggles) - Tag-based route observation ([mirbuilder/min:*], [registry:*]) - MIR structure validation (not just rc parity) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 19:42:42 +09:00
**Rust 側でやったこと(サマリ)**
- Receiver / pinning:
- `CallMaterializerBox::materialize_receiver_in_callee` を事実上 no-op にし、
receiver の pinning / LocalSSA 連携を `receiver::finalize_method_receiver` に一本化。
- `MirBuilder``pin_slot_names: HashMap<ValueId, String>` を持たせ、
`LocalSSA.ensure` が「同じ slot にぶらさがる最新の ValueId」へ自動でリダイレクトできるようにした。
- Compiler Box の分類:
- `CalleeResolverBox::classify_box_kind``BreakFinderBox` / `PhiInjectorBox` / `LoopSSA` を追加し、
Stage1/StageB 用 LoopSSA 箱を `CalleeBoxKind::StaticCompiler` として明示。
feat(phase21.5/22.1): MirBuilder JsonFrag refactor + FileBox ring-1 + registry tests Phase 21.5 (AOT/LLVM Optimization Prep) - FileBox ring-1 (core-ro) provider: priority=-100, always available, no panic path - src/runner/modes/common_util/provider_registry.rs: CoreRoFileProviderFactory - Auto-registers at startup, eliminates fallback panic structurally - StringBox fast path prototypes (length/size optimization) - Performance benchmarks (C/Python/Hako comparison baseline) Phase 22.1 (JsonFrag Unification) - JsonFrag.last_index_of_from() for backward search (VM fallback) - Replace hand-written lastIndexOf in lower_loop_sum_bc_box.hako - SentinelExtractorBox for Break/Continue pattern extraction MirBuilder Refactor (Box → JsonFrag Migration) - 20+ lower_*_box.hako: Box-heavy → JsonFrag text assembly - MirBuilderMinBox: lightweight using set for dev env - Registry-only fast path with [registry:*] tag observation - pattern_util_box.hako: enhanced pattern matching Dev Environment & Testing - Dev toggles: SMOKES_DEV_PREINCLUDE=1 (point-enable), HAKO_MIR_BUILDER_SKIP_LOOPS=1 - phase2160: registry opt-in tests (array/map get/set/push/len) - content verification - phase2034: rc-dependent → token grep (grep -F based validation) - run_quick.sh: fast smoke testing harness - ENV documentation: docs/ENV_VARS.md Test Results ✅ quick phase2034: ALL GREEN (MirBuilder internal patterns) ✅ registry phase2160: ALL GREEN (array/map get/set/push/len) ✅ rc-dependent tests → content token verification complete ✅ PREINCLUDE policy: default OFF, point-enable only where needed Technical Notes - No INCLUDE by default (maintain minimalism) - FAIL_FAST=0 in Bring-up contexts only (explicit dev toggles) - Tag-based route observation ([mirbuilder/min:*], [registry:*]) - MIR structure validation (not just rc parity) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 19:42:42 +09:00
2025-11-19 23:12:01 +09:00
**IfForm / empty else-branch の SSA fixStage1 UsingResolverFull 対応)**
- `src/mir/builder/if_form.rs`:
- `if cond { then }`else なし)のパターンで、
- else-entry 用に pre_if の `variable_map` から PHI ノードを生成したあと、
- その PHI 適用後の `variable_map``else_var_map_end_opt=Some(...)` として merge フェーズに渡すように修正。
- 以前は empty else の場合に `else_var_map_end_opt``None` になっており、
`merge_modified_vars` が pre_if の古い ValueId にフォールバックして、
merge ブロックで未定義の `%0` などを参照するケースがあった(`Stage1UsingResolverFull.main/0` の UndefinedValue
- 修正後は then/else 両ブランチで「PHI 適用後の variable_map」が merge に渡されるため、
empty else でも header/merge の SSA が崩れない。
- 検証:
- `src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifies`
`MirVerifier` 緑になり、`Stage1UsingResolverFull.main/0()` の merge ブロックで PHI 後の値(例: `%24`)を正しく参照していることを MIR dump で確認済み。
**.hako 側の今後25.1k 後半)**
- `LoopSSA.stabilize_merges(json)` を Rust LoopForm v2 の Carrier/Pinned 規約に合わせて実装する(現在はほぼ stub
- StageB Test2`tools/test_stageb_min.sh`)で得られる Program(JSON v0) に対し、
- Rust 側で `NYASH_VM_VERIFY_MIR=1` を立てた実行結果と、
- `.hako` 側 LoopSSA v2 適用後の JSON → Rust 実行結果
を比較し、BreakFinderBox / PhiInjectorBox / LoopSSA の責務を切り分けていく。
---
### 1-3. Phase 25.1e/f/g — LoopForm PHI v2 / ControlForm 統合(サマリ)
- 25.1eLoopForm PHI v2 migration:
- Local SSA`local a = ...`)の ValueId 分離を完了し、LoopForm v2 を「PHI/SSA の正」とする方向へ寄せた。
- Stage1 UsingResolver / 基本的な StageB ループは、LoopForm v2 経路で MirVerifier 緑。
- 25.1fControlForm 層の導入):
- `ControlForm` / `LoopShape` / `IfShape` を導入し、Loop / If を共通ビューとして扱う箱を定義。
- ここでは挙動を変えず、「構造だけを先に固定」する方針で設計を固めた。
- 25.1gConservative PHI ↔ ControlForm ブリッジ):
- `phi_core::loopform_builder::build_exit_phis_for_control` など、ControlForm から Conservative PHI を呼び出す薄いラッパを追加。
- 既存の PHI ロジックはそのままに、将来の置き換えポイントだけを明示している。
---
### 1-4. Phase 25.1A3 — Stage1 CLI bridgestub 実装)
- Rust 側: `src/runner/stage1_bridge.rs``run_refactored` 入口に組み込み、`NYASH_USE_STAGE1_CLI=1` かつ再入ガードなしのときに `lang/src/runner/stage1_cli.hako` を子プロセスで起動する。`STAGE1_EMIT_PROGRAM_JSON` / `STAGE1_EMIT_MIR_JSON` / `STAGE1_BACKEND` / `STAGE1_PROGRAM_JSON` で mode 選択。entry override は `STAGE1_CLI_ENTRY` / `HAKORUNE_STAGE1_ENTRY`
- .hako 側: `Stage1Cli` に最低限の本体を実装。
- `emit_program_json`: Stage1 UsingResolver で prefix を結合し、BuildBox.emit_program_json_v0 で Program(JSON v0) を返す。
- `emit_mir_json`: `MirBuilderBox.emit_from_program_json_v0` をそのまま呼ぶdelegate 未設定なら null
- `run_program_json`: backend==llvm の場合は `env.codegen.emit_object` まで通す。vm/pyvm は当面 MIR(JSON) を stdout に出すのみ(実行は Stage0 橋渡し未配線)。
- CLI: `emit program-json|mir-json` / `run --backend ... <src>` を受理。`NYASH_SCRIPT_ARGS_JSON` を JSON で best-effort 伝播。
- Docs: `docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md` に stub 状態を追記run は暫定挙動)。
- Known gaps: vm/pyvm 実行はまだ Stage0 への橋渡し未着手。llvm も emit object 止まりlink/exec は後続)。
### 1-5. Phase 25.1A4 — Using SSOT 薄設計BuildBox include 除去
- SSOT: `lang/src/using/resolve_ssot_box.hako` に README 相当のコメントと I/Fresolve_modules/resolve_prefixを追加。現状は no-op だが「using をここで扱う」窓口を固定。
- Stage1UsingResolver: `resolve_for_program_json` を追加し、SSOT を呼ぶ導線だけ確保(現状は透過返し)。
- BuildBox: 先頭の `include` を削除し、`using lang.compiler.entry.bundle_resolver as BundleResolver` に置換StageB パーサが include を解せない問題の足場づくり)。
- 実行確認: `NYASH_ALLOW_NYASH=1 HAKO_ALLOW_NYASH=1 NYASH_USE_STAGE1_CLI=1 STAGE1_EMIT_PROGRAM_JSON=1 ... cargo run --bin hakorune -- basic_test.hako` が RC=0 で完走(ただし stdout は `RC: 0` のみ、program-json 出力は未配線)。`cargo run ... emit program-json` は Rust CLI 側の表面が未対応のためエラー(想定挙動)。
---
## 2. まだ残っている問題・課題2025-11-18 時点)
### 2-1. StageB 本体の型エラー(`String > Integer(13)`
- 症状:
- StageB の `Main.main` 実行時に、
`Type error: unsupported compare Gt on String(...) and Integer(13)` が発生。
- LoopForm v2 / PHI / continue 修正とは **独立の StageB 固有のロジック問題**
- 想定される原因:
- StageB 側の body 構築 / JSON 生成で、本来数値比較にすべき箇所で「生の文字列」と整数を比較している。
- もしくは、Parser/Scanner が `len` やインデックスを文字列のまま扱っている部分がある。
- 対応方針(次フェーズ向けメモ):
- `StageBBodyExtractorBox.build_body_src` が吐く `body_src` を最小ケースで抽出し、
その中から問題の比較式(`>`)がどのように生成されているかを特定する。
- StageB の box レベルで:
- 「どのフェーズで型を決めるか」(例: ParserBox / StageB / VM 手前)を決めてから修正する。
- このタスクは 25.1c 続き or 新フェーズ25.1n 相当として、StageB 箱の設計側で扱う。
---
### 2-2. StageB 再入ガード `env.set/2` の扱い
- 現状:
- 一部 StageB コードが `env.set/2` を使った再入ガードに依存しており、
Rust VM 側には `env.set/2` extern が定義されていないため、
`❌ VM error: Invalid instruction: extern function: Unknown: env.set/2` が発生するケースがある。
- 方針メモ:
- 選択肢 A: StageB 再入ガードを Box 内 stateフィールドに寄せて、`env.set/2` 依存をなくす。
- 選択肢 B: StageB ハーネス専用に、最小限の `env.set/2` extern を Rust 側に実装する(本番経路では使わない)。
- 25.1m では構造修正Loop/PHI/receiverを優先し、この extern の話は据え置き。
---
### 2-3. .hako 側 LoopSSA v2Rust LoopForm v2 との乖離)
- 現状:
- `lang/src/compiler/builder/ssa/loopssa.hako``stabilize_merges()` はまだ実質的に stub に近い。
- StageB Test2`compiler_stageb.hako` 経由では、Rust MIR 側で LoopForm v2 / PHI v2 が安定した後も、
`.hako` 側 LoopSSA 経由の JSON から生成した MIR で PHI/SSA 問題が残る可能性がある。
- 目標:
- Rust LoopForm v2 を「制御構造と PHI の SSOT」とみなし、
`.hako` 側 LoopSSA が同じ Carrier/Pinned / preheader/header/exit の規約を JSON レベルで再現する。
- やること(フェーズ 25.1k 後半〜 25.1f/g 連携):
- 特定の関数(例: `BreakFinderBox._find_loops/2`を対象に、Rust 側 / .hako 側のそれぞれで生成されるループ構造を比較。
- LoopSSA v2 の中に:
- Carrier 変数の検出、
- pinned 変数の扱い、
- exit PHI の構築
を Rust LoopForm v2 に合わせて実装。
2025-11-19 23:12:01 +09:00
- 2025-11-19 追記:
- `BreakFinderBox._find_loops/2` については、まず .hako 側を「region box」的に整理した。
- `header_pos` / `header_id` / `exit_pos` / `exit_id` まわりの異常系を `continue` ではなく
`next_i` ローカルへの代入で表現し、1 イテレーションの末尾で `i = next_i` に合流させる形に変更。
- これにより、LoopForm v2 / LoopSSA 側から見ると「単一 region 内での分岐+最後に合流」という構造になり、
carrier/pinned 検出や今後の SSA 解析が行いやすくなった(挙動は従来と同じ)。
### 2-5. static box / me セマンティクス(観測タスクへ移行)
- 現状:
- `static box StringHelpers` のようなユーティリティ箱で、`me.starts_with(src, i, kw)` のように
同一箱内のヘルパー(`starts_with`)を `me.` 経由で呼んでいたため、Stage3 降下時に引数ずれが発生していた。
- 具体的には、`StringHelpers.starts_with_kw/3``StringHelpers.starts_with/3` の降下で
実際の呼び出しが `starts_with("StringHelpers", src, i, kw)` のような 4 引数形になり、
`starts_with(src, i, pat)` 側では `src="StringHelpers"` / `i=<ソース全文>` となって、
`if i + m > n``String > Integer(13)` 比較に化けていた。
- 対応(完了済み・局所修正):
- `lang/src/shared/common/string_helpers.hako``starts_with_kw` を、
`if me.starts_with(src, i, kw) == 0` から `if starts_with(src, i, kw) == 0` に書き換え、
static box ユーティリティに対する `me` 依存を除去した。
- これにより、`starts_with` 内でのガード比較 `i + m > n` はすべて整数同士となり、
StageB fib ケースで発生していた `String("...") > Integer(13)` の TypeError は解消済み。
- 今後Phase 25.1p 以降):
- static box 全般における `me` セマンティクス(本当に「シングルトンインスタンス」として扱う箱と、
純粋な名前空間箱をどう区別するかは、25.1p の DebugLog フェーズで観測しながら設計を詰める。
- 実際に Rust 層(`build_me_expression` / `lower_static_method_as_function` / `FunctionDefBuilder::is_instance_method`)を
統一規約に寄せる作業は、25.1p 以降のサブタスクとして扱う(現時点では局所修正でバグのみ解消)。
---
### 2-4. Builder / Selfhost まわりの残タスク(超ざっくり)
- Builder 内部ルート20.43 系):
- `MirBuilderBox` 経由の internal ルートで、MIR を stdout 経由ではなく一時ファイル / FileBox に書き出し、
ハーネスがそこから読む形に揃える案が残タスク。
- Selfhost CLI / Stage1 CLI:
- StageB / Stage1 CLI を「Rust VM / LLVM / PyVM / selfhost」の 4 経路で安定確認するラインは進行中。
- 25.1m では Rust VM + StageB balanced scan を優先し、CLI 全体は次のフェーズで詰める。
---
## 3. 次にやること(候補タスク)
ここから先は「どのフェーズを進めるか」をそのときの優先度で選ぶ感じだよ。
Rust 側は LoopForm v2 / StageB fib / Stage1 UsingResolver 構造テストまで一通り整ったので、当面は Stage1 CLI / selfhost ラインの小さな箱から進める。
### A. Stage1 CLI / Stage0 ブリッジPhase 25.1 — いまここ)
- A1: Stage1 CLI stub を Stage0 Rust ランナーから呼び出すブリッジDONE
- 実装: `src/runner/stage1_bridge.rs` `src/runner/mod.rs``maybe_run_stage1_cli_stub` を追加。
- `NYASH_USE_STAGE1_CLI=1`(既定 OFFかつ `NYASH_STAGE1_CLI_CHILD!=1` のときにだけ有効。
- entry `.hako``STAGE1_CLI_ENTRY` / `HAKORUNE_STAGE1_ENTRY` で上書き可能(既定: `lang/src/runner/stage1_cli.hako`)。
- 入力ファイル / モード:
- `STAGE1_EMIT_PROGRAM_JSON=1`: `hakorune emit program-json <source.hako>` を子プロセスで実行。
- `STAGE1_EMIT_MIR_JSON=1`: `STAGE1_PROGRAM_JSON` があれば `--from-program-json`、なければ `<source.hako>` から `emit mir-json`
- 上記どちらも無い場合: `hakorune run --backend <backend> <source.hako>`backend は `STAGE1_BACKEND` か CLI の backend 設定)。
- `NYASH_SCRIPT_ARGS_JSON` を拾って `--` 以降の script 引数も Stage1 側に転送。
- 再入防止として子プロセスには `NYASH_STAGE1_CLI_CHILD=1` を付与(子側からは Rust ブリッジを素通り)。
- A2: Stage1 CLI skeleton の責務を doc に固定DONE
- `lang/src/runner/stage1_cli.hako``Stage1Cli.emit_program_json/emit_mir_json/run_program_json/stage1_main` のシグネチャとトグルトポロジーを固定。
- `docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md` に Rust 側ブリッジの振る舞いとトグル名(`NYASH_USE_STAGE1_CLI` / `STAGE1_EMIT_*` / `STAGE1_BACKEND` / `NYASH_STAGE1_CLI_CHILD`)を追記。
- A3: 次ステップ(未着手)
- Stage1 CLI skeleton に StageB/BuildBox/MirBuilder 呼び出しを順に実装し、「Program(JSON)/MIR(JSON) を selfhost 経由で emit できる」状態まで持っていく。
- `tools/selfhost/run_stage1_cli.sh` から呼び出す selfhost パスと、Rust CLl からのブリッジパスの両方で JSON I/O 契約が同じになるように揃える。
### B. Stage1 UsingResolver / LoopForm v2 ラインPhase 25.1e 系フォロー)
- B1: entry UsingResolver の Region+next_i 化とコメント整備(おおむね DONE
- `lang/src/compiler/entry/using_resolver_box.hako` の 3 ループentries / JSON スキャン / modules_listは Region+next_i 形に揃え済み。
- 役割コメント: `resolve_for_source`StageB body_src を受けて prefix を返す)、`_collect_using_entries`JSON スキャンして entries を集める)、`_build_module_map`modules_list を map 化)を明記済み。
- `HAKO_STAGEB_APPLY_USINGS=0` の時は prefix を空 string にしつつ、depth ガードだけは走らせる仕様もコメントで固定。
- B2: UsingResolver 構造テスト(ループ形/PHIの拡充DONE
- `src/tests/mir_stage1_using_resolver_verify.rs` に Region+next_i ループと early-exit JSON スキャンパターンの軽量テストを追加。
- これらは cargo test 経路で常時緑を維持し、v2 quick スモークへの昇格は「実行時間とイズを見ながら後続フェーズで検討」という扱いにするdocs にメモ済み)。
- B3: pipeline_v2 UsingResolver との責務境界DONE
- `lang/src/compiler/pipeline_v2/using_resolver_box.hako` 冒頭に、「entry 側=ファイル I/O + using 収集」「pipeline_v2 側=modules_json 上の alias/path 解決」と役割メモを追加。
- RegexFlow ベースの単一路ループは Region 化不要stateful helperとし、LoopForm v2 の観点からも「観測対象外」とする。
### C. StageB / LoopSSA / Selfhost まわり(中期タスク)
- C1: StageB 再入ガード `env.set/2` の整理(据え置き)
- dev 専用 extern を Rust 側に追加するか、StageB 箱側で state に寄せるかを決める必要があるが、現在はループ/PHI ラインを優先し保留。
- このタスクに着手するときは「prod/CI 経路から完全に切り離した dev ガード」として設計する。
- C2: .hako LoopSSA v2 実装Rust LoopForm v2 への追従)
- Rust LoopForm v2 の Carrier/Pinned/BodyLocalInOut モデルを `.hako` の LoopSSA に輸入し、StageB Test2 / selfhost CLI でも MirVerifier 緑を目指す中〜長期タスク。
- 具体的な対象: `lang/src/compiler/builder/ssa/loopssa.hako` と StageB/BreakFinder 周辺の region 化済みループ。
- C3: Selfhost / CLI 周辺のテスト整理
- 代表的な selfhost / StageB / Stage1 CLI ケースを tests/tools 側でタグ付けquick/integration/selfhost、Phase 25.1 の「どこまでが Rust 側」「どこからが Stage1 側」を見える化する。
---
## 4. 履歴の見方メモ
- 以前の `CURRENT_TASK.md` は ~1900 行の長いログだったけど、読みやすさ重視でこのファイルはスナップショット形式にしたよ。
- 過去の詳細ログが必要になったら:
- `git log -p CURRENT_TASK.md`
- あるいは特定のコミット時点の `CURRENT_TASK.md``git show <commit>:CURRENT_TASK.md`
でいつでも復元できるよ。
---
docs(phase25.4): Phase 25.4 ロードマップ・ドキュメント整備 📋 Phase 25.4 計画確定: NamingBox SSOT化 & CLI設定箱 ✅ 追加ドキュメント: - docs/development/roadmap/phases/phase-25.4-naming-cli-cleanup/ - README.md: Phase 25.4 全体計画 - A. NamingBox SSOT化(完了) - B. Stage-1 CLI 設定箱(次フェーズ) - C. MIR ログ観測リスト(次フェーズ) - docs/development/roadmap/phases/phase-21.7-normalization/README.md - Phase 21.7 との関連性追記 - docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md - Phase 25.1 完了記録更新 - CURRENT_TASK.md: タスク進捗更新 - Phase 25.4-A 完了 - Phase 25.4-B/C 準備完了 - MIR Builder 型混乱バグ調査完了記録 🎯 Phase 25.4 戦略: 0. 共通方針 - 既定挙動は変えない(Fail-Fast + テスト緑キープ) - 新規ロジックは「小さな箱」に閉じ込める - まずドキュメント・構造を揃えてからコード A. NamingBox SSOT化 ✅ 完了 - static/global 名前決定を src/mir/naming.rs に一本化 - Builder/VM で統一ルール使用 B. Stage-1 CLI 設定箱(次フェーズ) - env.get() を Stage1CliConfigBox に集約 - mode/backend/source 等を Config として管理 C. MIR ログ観測リスト(次フェーズ) - __mir__.log の一覧化・分類 - 将来の MirLogBox 化準備 📊 テスト確認コマンド: - cargo test -q mir_static_box_naming --lib - cargo test -q mir_stage1_cli_entry_ssa_smoke --lib - tools/smokes/v2/run.sh --profile quick Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 09:02:30 +09:00
# Phase 25.4 — Naming & Stage1 CLI Cleanupdesign only
- ねらい:
- static box / global 呼び出しの命名規約を NamingBox に集約し、VM 側のレガシーフォールバック経路を撤去する。
- Stage1 CLI の env/トグル解釈を 1 箇所の設定箱にまとめ、stage1_main の責務を薄く保つ。
- `__mir__.log` ベースの MIR ログ観測ポイントをドキュメントで一覧化し、将来の正式 API 化に備える。
- 現状:
- NamingBox`src/mir/naming.rs`は導入済みで、Builder 側の static メソッド名は `encode_static_method` 経由、VM 側の global 呼び出しは `normalize_static_global_name` 経由になっている。
- VM 側の「canonical 名で見つからなければ元名でもう一度探す」フォールバックは削除済みで、`mir_static_box_naming` テスト群が `Main._nop/0` 経路を固定している。
- Stage1 CLI は env-only 仕様argv 依存なし)で Stage0 ブリッジと接続済みだが、env 群の解釈はまだ stage1_main 内に散在している。
- このフェーズでやること(設計レベル):
- NamingBox を「static 名に触るすべてのコードの SSOT」として整理直接 `format!("Box.main")` する箇所を洗い出し)。
- `Stage1CliConfigBox`を設計し、env→Config 変換の責務とフィールドを docs に書き出す(実装は後続でも可)。
- `__mir__.log` のタグと用途を 1 ページの docs にまとめ、dev 用ログと残したい観測ログを分けておく。
---
以上が 2025-11-18 時点の Phase 21.8 / 25 / 25.1 / 25.2 / 25.4 ラインの「いまどこ」「なに済み」「なに残り」だよ。
次にどの箱から攻めるか決めたら、ここに箇条書きで足していこうね。
2025-11-19 23:12:01 +09:00
## 3. これからやるタスクのラフ一覧25.1 / Stage1 系)
ここから先は「まず設計と箱分割を書いてから実装」という方針で進めるタスク群だよ。
### A. Rust 層解析LoopForm v2 / JSON v0 / Stage1 観測)
- A-1: LoopForm v2 / LoopSnapshotMerge の入口確認
- `src/mir/loop_builder.rs` / `src/mir/phi_core/loopform_builder.rs` / `src/mir/phi_core/loop_snapshot_merge.rs` を「Stage1 から見た導線」として読み直し、どのレイヤで Carrier / Pinned / BodyLocalInOut が決まるかを short メモ化する。
- A-2: JSON v0 → MIR ブリッジの導線整理
- `src/runner/json_v0_bridge/lowering/`(特に `loop_.rs`を通して、Program(JSON v0).body / defs.body(Block) が LoopForm v2 までどう運ばれるかを図として docs に落とす。
- A-3: Stage1 UsingResolver の MIR 観測
- 既存テスト `src/tests/mir_stage1_using_resolver_verify.rs` の MIR dump を元に、「どのループが Region+next_i 化候補か」「既に問題なく LoopForm に乗っている場所はどこか」を箇条書きで整理する。
### B. Stage1 UsingResolver 箱化・ループ整理(.hako 側)
- B-1: Stage1UsingResolverBox の責務分割設計
- `lang/src/compiler/entry/using_resolver_box.hako` を、collect_entries / modules_map / file_read などの小さいロジック箱に概念的に分割し、「どの箱が何を責務とするか」を docs に書く(実際のファイル分割は後段)。
- B-2: すべてのループを Region+next_i 形に揃える計画
- entry の UsingResolver 内に残っている「pos++/continue 多発型」ループを洗い出し、Region+next_i 形にどう書き換えるかを phase-25.1 docs に追記する。
- 目的: LoopForm v2 / PHI から見たときに「1 region / 1 backedge / 明確な次位置決定」という形に統一する。
- 状況メモ: entry 側 3 ループentries/JSON scan/modules_listは Region+next_i 化済み。残りなし。
- B-3: pipeline_v2 UsingResolver との役割分担
- `lang/src/compiler/pipeline_v2/using_resolver_box.hako` と entry/Stage1UsingResolverBox のどちらが「テキスト / JSON / modules_map」のどこまでを担当するかを整理し、責務境界をドキュメントに固定する。
- 状況メモ: pipeline_v2 側は modules_json の alias 解決のみRegexFlow.find_from の単一路ループ。Region 化不要として据え置き、境界だけ明記。
- B-4: 構造テストの追加計画
- Region+next_i パターンの軽量 SSA テスト(すでに 1 本追加済み)を基準に、もう 1〜2 本、UsingResolver ソースに近いパターンJSON スキャンearly-exitを追加する方針を決める。
### C. Stage1 CLI / program-json / mir-json SelfHost 準備
- C-1: Stage1 CLI インターフェースの設計メモ
- `.hako → Program(JSON)` / `Program(JSON) → MIR(JSON)` / `MIR(JSON) → 実行` を Stage1 側からどう呼び出すか(関数名・引数レベル)を docs に先に書く。
- C-2: StageB → Stage1 データフロー図
- `compiler_stageb.hako` → Program(JSON v0) → Stage1 UsingResolver → MirBuilder までのパイプラインを Phase25.1 ドキュメントに 1 枚の図としてまとめる。
- C-3: Rust CLI 側ブリッジの最小ガード案
- Stage0/Rust CLI は「Program(JSON/MIR(JSON) を受け取り VM/LLVM に流すだけ」に縮退させる方針と、既定 OFF トグルselfhost 入口)をどう切るかを設計メモとして追加。
### D. 将来フェーズ向けメモvariable_map 決定化ライン)
- D-1: MirBuilder::variable_map / BoxCompilationContext::variable_map BTreeMap 化案
- どの構造を HashMap→BTreeMap 化するか、どのテスト(`mir_funcscanner_skip_ws_vm_debug_flaky` など)で決定性を確認するかを Phase25.x の設計メモとして書いておく。
- D-2: dev 専用 / flaky テストの扱い方針
- どのテストが dev ignore手動実行用で、いつ/何を満たしたら常時有効に戻すかを、このファイルと関連 README に明確に残す。
2025-11-19 23:12:01 +09:00
このセクションは「すぐ実装する TODO ではなく、25.1〜25.x ラインで踏むべき設計タスク一覧」として使う予定だよ。
(静的 me-call 修正の参考メモはここに残しつつ、別セクションは整理済み)
2025-11-19 23:12:01 +09:00
### E. Legacy Loop/PHI 経路の囲い込みと削除準備
- E-1: Legacy loop_phi.rs の役割と削除条件の明文化
- ファイル: `src/mir/phi_core/loop_phi.rs`
- 状態: LoopForm v2 + LoopSnapshotMergeBox への移行後は「legacy scaffold」としてのみ残存。
- やること:
- 現在の利用箇所を 2 種類に分類する:
- 本線経路LoopForm v2 / Stage1 / StageB から参照される部分)
- 互換レイヤ解析専用JSON v0 bridge, 旧 smokes, dev-only ヘルパ)
- 本線はすべて `loopform_builder.rs` + `header_phi_builder.rs` + `loop_snapshot_merge.rs` で賄えることを確認し、`loop_phi.rs` を「legacy 専用(新規利用禁止)」として CURRENT_TASK と docs に固定しておく。
- Phase 31.x の cleanup で実ファイル削除してよい条件(参照 0対応する smokes/テストの移行完了)を `docs/private/roadmap/phases/phase-31.2/legacy-loop-deletion-plan.md` 側と揃えておく。
- E-2: PHI/LoopForm 周辺で HashMap を使ってよい/いけない場所を線引き
- ファイル: `src/mir/builder.rs`, `src/mir/phi_core/*`, `src/mir/loop_builder.rs`
- やること:
- 「PHI 生成とスナップショット決定」に関わる構造では `BTreeMap` / `BTreeSet` / `Vec+sort` のみに限定し、`HashMap` は使わない、というルールを Phase 25.1 docs に明記する。
- それ以外のメタ情報plugin sigs, weak_fields など)は HashMap 維持可とし、「決定性」に影響しないことをコメントで示しておく。
- 代表として `loop_phi.rs` 内の `sanitize_phi_inputs` のように「一度 HashMap で集約してから sort する」パターンは、LoopForm v2 正系統では `PhiInputCollector` + BTree 系で代替されていることを確認し、legacy 側のみに閉じ込める。
- E-3: Legacy 経路の一覧と新規利用禁止ポリシーを docs に反映
- ファイル:
- `docs/development/roadmap/phases/phase-25.1/README.md`(本線側のルール)
- `docs/private/roadmap/phases/phase-31.2/legacy-loop-deletion-plan.md`(削除計画側と整合させる)
- やること:
- Legacy として扱うモジュール(例: `phi_core::loop_phi`, 一部旧 JSON v0 bridge helperを一覧にして、「新しいコードからここを呼ばない」「Phase 31.x で削除予定」と明記する。
- 逆に、今後 PHI/Loop/If で使うべき SSOT 箱LoopForm v2 + HeaderPhiBuilder + BodyLocalPhiBuilder + if_phi + ControlFormを 1 セクションで列挙し、「ここだけを見ると設計が分かる」導線を作る。
## 3. Phase 25.1q — LoopForm Front UnificationDONE / follow-up 別タスクへ)
- 目的: Rust AST ルート (LoopBuilder) と JSON v0 ルート (`json_v0_bridge::lower_loop_stmt`) のループ lowering を “LoopFormBuilder + LoopSnapshotMergeBox” に一本化し、どの経路からでも同じ SSOT を見るだけで良い構造に揃える。
- 完了状態:
- AST ルート:
- `LoopBuilder::build_loop_with_loopform` で canonical `continue_merge_bb` を常時生成し、`continue_target` を header ではなく `continue_merge_bb` に統一済み。
- `LoopFormBuilder::seal_phis` / `LoopSnapshotMergeBox` の continue/exit 入力は「preheader + continue_merge + latch」「header + break snapshots」で完全管理。
- JSON v0 ルート:
- `loop_.rs``LoopFormJsonOps` を実装し、preheader/header/body/latch/continue_merge/exit の block ID を AST ルートと同じ形で生成。
- break/continue/exit の snapshot を `LoopSnapshotMergeBox` でマージし、canonical continue_merge → header backedge を JSON 側でも採用。
- `tests/json_program_loop.rs` で JSON v0 だけを入力にした軽量ループ(通常 / continue / body-local exit`MirVerifier` で確認するスモークを追加。
- Docs/README:
- `docs/development/roadmap/phases/phase-25.1q/README.md` に「AST/JSON ともに LoopForm v2 + LoopSnapshotMergeBox が SSOT」と明記。
- `src/runner/json_v0_bridge/README.md` で “bridge は薄いアダプタであり、新しい PHI 仕様は loopform 側でのみ扱う” とガードを追記。
- `src/mir/phi_core/loop_phi.rs` には “legacy分析用のみ” コメントを追加。将来の cleanup (Phase 31.x) で削除対象とする。
- 残タスクは別フェーズへ:
- Stage1 UsingResolver 周りの SSA バグ(`tests::mir_stage1_using_resolver_verify::mir_stage1_using_resolver_full_collect_entries_verifies` の Undefined Valueは 25.1q の範囲外。LoopForm の SSOT 化は終わっているため、今後は Stage1 側の PHI/Env スナップショット設計タスクとして切り出す。
- JSON v0 → Nyash AST への統合案や loop_phi.rs の実ファイル削除は、Phase 31.x cleanup 計画側で扱う。