Files
hakorune/CURRENT_TASK.md

300 lines
22 KiB
Markdown
Raw Normal View History

# Current Task — Phase 21.8 / 25 / 25.1 / 25.2 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 規約に追いつかせる必要がある。
---
## 1. 最近完了した重要タスク
### 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 ロジックはそのままに、将来の置き換えポイントだけを明示している。
---
## 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. 次にやること(候補タスク)
ここから先は「どのフェーズを進めるか」をそのときの優先度で選ぶ感じだよ。
2025-11-19 23:12:01 +09:00
1. **StageB / BreakFinder / FuncScanner ラインの SSA 根治Phase 25.1m 続き)**
- JSON v0 bridge の Loop lowering で、`backedge_to_cond``Jump` だけでなく `Branch(cond→header/exit)` も認識するように修正(`loop_.rs`)。
→ BreakFinderBox._find_loops/2 のような break を含むループでも header PHI が正しく張られるようにした。
- BreakFinderBox は解析用の static box として扱い、`me._find_loops` / `me._jumps_to``BreakFinderBox._find_loops` / `_jumps_to` に正規化。
`me` 未定義による Undefined ValueId を避ける。
- StageB → Stage1 パーサ経路は、`ParserBox.parse_program2` のトップレベルループではなく、`parse_block2``Main.main` の本文をブロックとしてパースし、
Program(JSON v0) を自前で組み立てる構造に変更StageB 固まり問題を回避)。
2. **StageB 再入ガード `env.set/2` の整理**
- 再入ガードを Box 内 state で持つ方向か、Rust 側に dev 専用 extern を追加するかを決める。
- どちらにしても「本番経路prod ランナー)には影響しない」ようフラグでガードする。
3. **.hako LoopSSA v2 実装LoopForm v2 への追従)**
- Rust LoopForm v2 の規約Carrier/Pinned / preheader/header/latch/exit`.hako` の LoopSSA に輸入。
- StageB Test2 / selfhost CLI の JSON→MIR 経路で MirVerifier 緑を目標にする。
4. **Selfhost / CLI 周辺のテスト整理**
- 代表的な selfhost / StageB / Stage1 CLI ケースに対して、
「Phase 25.1m でどこまで緑になったか」「どこから先が 25.1k 以降の仕事か」を tests / tools 側で見える化する。
---
## 4. 履歴の見方メモ
- 以前の `CURRENT_TASK.md` は ~1900 行の長いログだったけど、読みやすさ重視でこのファイルはスナップショット形式にしたよ。
- 過去の詳細ログが必要になったら:
- `git log -p CURRENT_TASK.md`
- あるいは特定のコミット時点の `CURRENT_TASK.md``git show <commit>:CURRENT_TASK.md`
でいつでも復元できるよ。
---
以上が 2025-11-18 時点の Phase 21.8 / 25 / 25.1 / 25.2 ラインの「いまどこ」「なに済み」「なに残り」だよ。
次にどの箱から攻めるか決めたら、ここに箇条書きで足していこうね。
2025-11-19 23:12:01 +09:00
## 2-? StageB FuncScanner (in progress)
- StageBFuncScannerBox を compiler_stageb.hako 内に追加し、StageBDriverBox.main からは FuncScannerBox ではなくこちらを呼ぶように変更。
- VM 側の Undefined value (BreakFinderBox._find_loops/2, FuncScannerBox.scan_all_boxes/1) は解消済みで、StageB 自体は rc=0 まで到達する。
- ただし現時点では StageBFuncScannerBox.scan_all_boxes(src) が fib サンプルに対しても defs=[] を返しており、Program(JSON) に TestBox.fib が載っていない状態。
- 一度 StageBDriverBox から直接 FuncScannerBox.scan_all_boxes を呼ぶ構成も試したが、この経路では FuncScannerBox.scan_all_boxes/1 で再び Undefined value が発生したため、現状は StageBFuncScannerBox 経由に戻しているStageB rc は 0、defs は空)。
- StageBFuncScannerBox._find_matching_brace は FuncScannerBox._find_matching_brace と同じ balanced scan アルゴリズムに揃えつつ、`[funcscan/debug] _find_matching_brace enter open_idx=... n=...` ログで挙動を観測できるようにしてあるclose_idx=-1 になる原因調査用)。
- Rust Stage3 パーサ側の `using` パースを拡張し、`using "lang.compiler.parser.box" as ParserBox` 形式を受理するようにしたうえで、FuncScannerBox 自身もこの形に正規化した。
- これにより `lang/src/compiler/entry/func_scanner.hako` 単体に対して `--dump-mir` が通るようになり、FuncScannerBox.scan_all_boxes/1 の MIR を直接観測できる。
- 次の担当者は StageBFuncScannerBox.scan_all_boxes/1 と FuncScannerBox.scan_all_boxes/1 の MIR を比較しつつ、StageB body 抽出→FuncScanner→defs 注入の導線と LoopBuilder 側の exit PHI を突き合わせてほしい。
## 3. Static Box フィールド仕様ドキュメント(完了)
- docs/reference/language/LANGUAGE_REFERENCE_2025.md: 3.4 Static Boxパターンに「static box 内のフィールドはすべて static フィールドとして扱われる」旨を明記した。
- 言語仕様としては、static box の中では `PI: FloatBox` のような宣言で十分であり、追加の `static` キーワードは不要であることをドキュメント上で固定。
- 次タスク候補Claude Code 向け): static box / box のフィールド挙動に関するサンプルとテストVM/JSON v0 両方)の整理、および static box 上の `me` セマンティクス25.1p DebugLog フェーズと連動)の仕様化。
## 3. Phase 25.1q — LoopForm Front Unification (planning)
- 目的: Rust AST ルート (LoopBuilder) と JSON v0 ルート (json_v0_bridge::lower_loop_stmt) のループ lowering フロントを整理し、PHI/LoopForm の SSOT を phi_core + LoopFormBuilder に明示的に寄せる。
- 現状:
- Rust AST → MIR は LoopBuilder + LoopFormBuilder で統一済み。
- JSON v0 → MIR は loop_.rs から同じ phi_core を呼んでいるが、ファイルが分かれており、LLM/人間が誤って JSON 側だけを触るケースがあった。
- 25.1q でやること(設計メモレベル):
- docs に「LoopForm/PHI の意味論は phi_core が SSOT」と明記。
- loop_.rs を「JSON から LoopForm に渡す薄いアダプタ」に限定し、余計なデバッグや独自分岐を増やさない方針を固定。
- 将来的に JSON v0 → AST → MirBuilder に寄せる統合案を設計メモとして整理(実装は 25.2 以降)。