# Current Task このファイルは「いま何に集中しているか」と「次にやり得る候補」だけを書く軽量ビューだよ。 詳細ログや過去フェーズの記録は `docs/development/current/main/` 以下の各 `phase-*.md` と `joinir-architecture-overview.md` を真実のソースとして扱うことにするね。 --- ## 🎯 今フォーカスしているテーマ(2025-12-09 時点のスナップショット) ### 1. JoinIR ループ基盤の状態 - LoopBuilder は完全削除済みで、ループは JoinIR Pattern1–4(while / break / if‑PHI / continue)+ P5(Trim系) で統一。 - JoinValueSpace / LoopHeaderPhi / ExitLine / JoinInlineBoundary / JoinIRVerifier まで含めた 「Loop → JoinIR → MIR → return」のパイプラインは、代表パターンと JsonParser ミニケースで安定している。 - **Phase 213–217 完了**: P3(if‑PHI) は if‑sum 最小パターン(`phase212_if_sum_min.hako`)まで AST ベースで一般化済みで、 Phase 215 で ExprResult の出口契約を Pattern2 と同じ形に揃えて RC=2 まで通すようになった。 Phase 216 で selfhost 側の production test も検証完了。 **Phase 217 でマルチキャリア if‑sum(sum+count)も追加実装0行で動作確認** - Phase 195/214/215 の箱組合せで完璧動作。 - **Phase 218 調査完了**: JsonParser-style if‑sum 適用を試行し、パターン認識のギャップを特定。 - Phantom `count` carrier が誤検出され、`is_if_sum_pattern()` が false を返す根本原因を解明。 - AST ベース lowerer は実装済みだが、carrier 検出ロジックの問題で起動されていないことを確認。 - **Phase 219 完了**: Phantom carrier bug 修正 - 名前ベース推定削除、代入ベース検出に統一。 - `analyze_loop_updates_from_ast()` で assignment-based detection 実装 - RHS structure classification + name heuristic で CounterLike/AccumulationLike 判定 - phase212 で AST lowerer 正常起動確認(`is_simple_if_sum_pattern() = true`) - phase218/217 は Phase 214+ (condition variable support) でブロック中 - **Phase 220 完了** ✅: P3 if-sum ConditionEnv 統合 + ExprResult routing 統一化 - **Phase 220-C**: condition variable remap fix(condition_bindings 事前登録) - **Phase 219-fix**: ConditionPatternBox で複雑条件フィルタリング(`i % 2 == 1` → legacy mode) - **Phase 220-D**: loop 条件変数サポート(`loop(i < len)` → ConditionEnv 経由で解決) - **Phase 221**: ExprResult routing 実装(expr_result → carrier PHI dst) - **Phase 221-R**: ExprResultResolver Box 箱化(Phase 33 パターン準拠、-37 行削減) - **成果**: phase212_if_sum_min.hako → RC=2 達成、P3/P2 の expr-result 経路完全統一 - **次フェーズ**: P3/P2 expr-result 経路が揃ったので、JsonParser/selfhost への実戦適用フェーズへ移行 - **Phase 221 実戦投入完了** ✅: JsonParser 数値ループの棚卸し・制約整理 - **実戦 OK**: 5/9 テスト PASS(NumberAccumulation, if-sum, captured vars) - **制約発見**: 3種の既知制約を整理(LoopBodyLocal in condition, MethodCall whitelist, if condition pattern) - **次の候補**: LoopBodyLocal 条件対応(Pattern 5+ 拡張)、if condition 左辺変数対応 - **Phase 222 完了** ✅: If Condition 正規化(左リテラル/変数同士対応) - **ConditionPatternBox 拡張**: normalize_comparison() で `0 < i` → `i > 0` 正規化 - **if-sum 統合**: extract_loop_condition() を正規化ベースに変更 - **テスト**: phase222_if_cond_left_literal_min.hako → RC=2 達成 - **制約解決**: Phase 221 の "if condition pattern" 制約を解消 - **Phase 223 完了** ✅: LoopBodyLocal Condition Promotion(条件昇格システム) - **Phase 223-1 完了** ✅: 包括的棚卸(Category A: 6 patterns, Category B: 1, Category C: 2) - **Phase 223-2 完了** ✅: API レベル設計(LoopBodyCondPromoter Box, P0: Pattern4/_skip_whitespace 向け) - 既存箱との役割整理(LoopConditionScopeBox, LoopBodyCarrierPromoter, TrimLoopLowerer) - Promotion API 定義(ConditionPromotionRequest/Result) - Pattern4 統合方針(promotion-first, Fail-Fast fallback) - **Phase 223-3 完了** ✅: 実装完了(LoopBodyCondPromoter 抽出, Pattern4 統合, E2E テスト) - `LoopBodyCondPromoter` Box 実装(`loop_body_cond_promoter.rs`) - `extract_continue_condition()`: body 内 if 文から continue 条件を抽出 - Pattern4 への統合: LoopBodyLocal 昇格成功時に lowering 続行(以前は Fail-Fast) - E2E テスト: `apps/tests/phase223_p4_skip_whitespace_min.hako`(昇格成功 → Pattern4 lowering 続行確認) - 5 unit tests PASS、ビルド成功、ドキュメント更新完了 - **残課題**: JoinIR Trim lowering(Phase 172+)で完全な RC 正確性を実現する必要あり - **Phase 223.5 完了** ✅: LoopBodyCondPromoter の Pattern2 統合 - **Pattern2 統合**: header/break 条件両方を分析し昇格を試みる - **A-4 テスト追加**: `apps/tests/phase2235_p2_digit_pos_min.hako`(cascading LoopBodyLocal パターン → Fail-Fast 確認) - **error_messages.rs 拡張**: `format_error_pattern2_promotion_failed()` 等追加 - **成果**: Pattern2/4 両方から LoopBodyCondPromoter を使う統一構造が完成 - **Phase 224 完了** ✅: A-4 DigitPos Promoter(Core Implementation + ConditionAlias Bridge) - **DigitPosPromoter 実装**: cascading indexOf パターン(substring → indexOf → comparison)の昇格ロジック完成 - **Two-tier 戦略**: A-3 Trim → A-4 DigitPos フォールバック型オーケストレーション - **Unit Tests**: 6/6 PASS(comparison operators, cascading dependency, edge cases) - **Promotion 検証**: Pattern2/Pattern4 パイプラインで digit_pos → is_digit_pos 昇格成功確認 - **Phase 224-D**: ConditionAlias を CarrierInfo/ConditionEnv に導入し、`digit_pos` → `is_digit_pos` の条件解決ブリッジを追加(LoopBodyLocal 名で書かれた break 条件でも carrier が参照されるようになった) - **残課題**: substring/indexOf を含む body-local init の MethodCall lowering は Phase 193/224-B/C/225 のラインで段階的に対応中(完全対応は後続 Phase) - **詳細**: [PHASE_224_SUMMARY.md](docs/development/current/main/PHASE_224_SUMMARY.md) - **Phase 224-D 完了** ✅: ConditionAlias 導入(昇格変数の条件参照解決) - **ConditionAlias 型追加**: `CarrierInfo` に `condition_aliases: Vec` フィールド追加 - **Promoter 側記録**: DigitPosPromoter / TrimPatternInfo が昇格時に alias を記録(`digit_pos` → `is_digit_pos`) - **Pattern2 統合**: 昇格・merge 後に join_id 割り当て、ConditionEnv に alias を追加(`digit_pos` → ValueId(104)) - **CarrierInfo 構造修正**: DigitPosPromoter が carriers list に追加する形に変更(loop_var_name 置換ではなく) - **検証**: `phase2235_p2_digit_pos_min.hako` で alias 解決成功、エラーが次段階(substring init)に進展 - **残課題**: substring method in body-local init(Phase 193 limitation) → Phase 225 で解決 - **Phase 225 完了** ✅: LoopBodyLocalInit MethodCall メタ駆動化(ハードコード完全削除) - **問題**: Phase 193 の `emit_method_call_init` にハードコードされた whitelist (`SUPPORTED_INIT_METHODS`) と Box 名 match 文 - **解決**: MethodCallLowerer への委譲により単一責任原則達成 - `SUPPORTED_INIT_METHODS` 定数削除(indexOf, get, toString の硬直した whitelist) - Box 名 match 文削除(`indexOf → StringBox` 等のハードコード) - CoreMethodId メタデータで `allowed_in_init()` 管理(substring, indexOf 等を動的許可) - **成果**: - **substring メソッド追加**: Phase 225 で substring が body-local init で使用可能に(デジタル解析等で必須) - **コード削減**: -82 行(158 削除 - 76 追加) - **メタ駆動**: すべてのメソッド判定が CoreMethodId 経由(拡張性向上) - **テスト**: - 877/884 テスト PASS(7 失敗は pre-existing P3 accumulator issues) - MethodCallLowerer 単体テスト 8/8 PASS - LoopBodyLocalInit 単体テスト 3/3 PASS - **既知制約**: Cascading LoopBodyLocal 依存(`ch` → `digit_pos` → condition)は Phase 193 からの既存制約(ConditionEnv のみ解決、LoopBodyLocalEnv 非対応) - **詳細**: [phase225-bodylocal-init-methodcall-design.md](docs/development/current/main/phase225-bodylocal-init-methodcall-design.md) - **Phase 226 完了** ✅: Cascading LoopBodyLocal 対応(`digit_pos = digits.indexOf(ch)` 解決) - **問題**: Phase 225 で `digit_pos` init が `ch` を参照するとき、ConditionEnv のみ検索し `Variable 'ch' not bound in ConditionEnv` エラー - **根本原因**: 引数解決時に LoopBodyLocalEnv を参照していなかった(body-local → condition の優先順位なし) - **解決**: 1. `LoopBodyLocalInitLowerer::lower_init_expr()` に `env` パラメータ追加(cascading 対応) 2. `LoopBodyLocalInitLowerer::emit_method_call_init()` に `body_local_env` パラメータ追加 3. `MethodCallLowerer::lower_for_init()` に `body_local_env` パラメータ追加 4. `MethodCallLowerer::lower_arg_with_cascading()` 新規ヘルパー関数実装(body_local → condition の優先順位解決) - **成果**: - **Cascading 解決成功**: `[method_call_lowerer] Arg 'ch' found in LoopBodyLocalEnv → ValueId(1013)` - **`ch not bound` エラー解消**: `digit_pos = digits.indexOf(ch)` 正常に lowering - **コード追加**: +100 行(2ファイル、loop_body_local_init.rs / method_call_lowerer.rs) - **既存テスト**: 877/884 PASS(Phase 226 非関連 7失敗、pre-existing) - **残課題**: `ValueId(14) undefined` エラー(promotion ロジック関連、Phase 226 範囲外) - **詳細**: Cascading dependency chain: `ch = s.substring(p, p+1)` → `digit_pos = digits.indexOf(ch)` → `if digit_pos < 0 { break }` ### 2. JsonParser / Trim / selfhost への適用状況 - Trim 系: - `_trim` / `_skip_whitespace` の P5 パイプライン(LoopBodyLocal 昇格 → bool carrier → TrimLoopLowerer)は JoinIR→MIR まで end‑to‑end で安定動作。 - JsonParser: - 11 ループ中、基本形(P1/P2/P5 相当)の 7 本は JoinIR インフラ上で理論的にカバー可能と確認済み。 - すでに JoinIR で実戦投入できているのは `_skip_whitespace` / `_trim*` / `_match_literal` / `_atoi_min` / `_parse_number_min`。 - 残りの複雑ループ(`_parse_array` / `_parse_object` / `_unescape_string` / 本体 `_parse_string` など)は 「LoopBodyLocal + 複数 MethodCall + 複数フラグ」という組み合わせで、今後の拡張対象として整理済み。 - selfhost (.hako): - selfhost stage‑3 depth‑1(Rust→.hako)までは JoinIR 経路で代表ケースが緑。 - depth‑2(.hako 側で JSON/MIR を読み、JoinIR/MIR/VM/LLVM に流すライン)は、JsonParser 側のループカバレッジ拡張が前提。 ### 3. 直近で意識しておきたい設計の芯 - **Loop パターン空間**は有限で整理済み: - P1: Simple While - P2: Break - P3: If‑PHI(単一/複数キャリア) - P4: Continue(then/else‑continue 正規化込み) - P5: LoopBodyLocal 昇格(Trim/JsonParser 用の部分適用) - 「増やすべき」は新しい Pattern ではなく、既存 Pattern の前処理箱: - BoolExprLowerer / ConditionEnv / LoopConditionScopeBox / LoopBodyCarrierPromoter / TrimLoopHelper / ComplexAddendNormalizer / LoopBodyLocalEnv / UpdateEnv などで 条件式とキャリア更新を吸収し、Pattern1–4 は「ループ骨格」に専念させる方針。 - Fail‑Fast 原則: - JoinIR 以外のループ lowering パスは存在しない(LoopBuilder は削除済み)。 - 「わからないパターン」は必ず `[joinir/freeze]` 系の明示エラーにして、サイレントフォールバックはしない。 --- ## ✅ 最近まとまった大きな塊(超要約) ここ半年くらいで終わっている主な塊だけをざっくり書くね。 細かいタスク・バグ票・議論は `phase-XXX*.md` に全部残っているので、必要になったときだけそちらを読む想定。 - **LoopBuilder 削除ライン(Phase 180 前後)** - LoopBuilder を dev‑only → hard freeze → 物理削除まで完了。 - Loop lowering の SSOT を JoinIR に一本化。 - **LoopPattern / Router ライン(Phase 170–179)** - LoopFeatures / LoopPatternKind / PatternRouter / PatternPipelineContext を整備。 - Pattern1–4 の検出・ルーティングを「構造ベース+AST features」で統一(関数名ベタ書き依存を除去)。 - **Exit / Boundary / ValueId ライン(Phase 172–205)** - ExitMeta / ExitLineReconnector / JoinInlineBoundary(+Builder) / LoopHeaderPhiBuilder を箱化。 - JoinValueSpace(Param/Local 領域)+ PHI 契約 Verifier で ValueId 衝突と PHI 破損を根治。 - **P5(Trim/JsonParser) ライン(Phase 171–176, 173–175, 190–193)** - LoopBodyLocal 昇格パイプライン(Trim, `_skip_whitespace`, `_parse_string` 簡易版)を構築。 - StringAppend / NumberAccumulation / Complex addend 正規化など、更新式まわりの箱を揃えた。 - **P3 (If‑PHI) 汎用化ライン(Phase 195–196, 212–215)** - multi‑carrier P3 の JoinIR 生成を整理。 - Select 展開 / JoinIR→MIR ブリッジ側のバグ(PHI inputs, back‑edge, 二重 remap)を修正。 - if‑sum 最小パターンを AST ベースで一般化し、ExprResult Exit 契約まで Pattern2 と揃えた。 このあたりが「JoinIR ループ基盤の芯」で、以降の Phase は JsonParser/selfhost の各ループへの適用フェーズ、という位置づけだよ。 --- ## 🧭 これからの候補(まだ「やる」とは決めていないメモ) ここは「やることリスト」ではなく「今後やるとしたらこの辺」というメモにする。 実際に着手するタイミングで、別途 Phase/タスクを切る想定だよ。 1. JsonParser 残りループへの JoinIR 展開 - `_parse_array` / `_parse_object` / `_unescape_string` / 本体 `_parse_string` など。 - 既存の P2/P3/P4+P5 パイプラインをどこまで延ばせるかを検証するフェーズ。 2. selfhost depth‑2 ラインの再開 - `.hako` 側で Program/MIR JSON を読んで JoinIR/MIR/VM/LLVM に流すライン。 - JsonParser 側のカバレッジが上がったあとに、小さいループから順に移植する。 3. JoinIR Verify / 最適化まわり - すでに PHI/ValueId 契約は debug ビルドで検証しているので、 必要なら SSA‐DFA や軽い最適化(Loop invariant / Strength reduction)を検討。 --- ## 📎 このファイルの運用ルール(自分向けメモ) - 過去フェーズの詳細な ToDo/Done リストは **CURRENT_TASK には書かない**。 代わりに `phase-XXX*.md` と `joinir-architecture-overview.md` を SSOT として維持する。 - CURRENT_TASK は「あくまで最新のフォーカスと次の候補だけ」に絞る。 目安として **このファイル自体は 2〜3画面程度(〜300行以内)** に収める。 - 新しい大フェーズを始めたら: 1. まず docs 配下に `phase-XXX-*.md` を書く。 2. CURRENT_TASK には「そのフェーズの一行要約」と「今のフォーカスかどうか」だけを書く。