2025-12-08 04:00:44 +09:00
|
|
|
|
# JoinIR Architecture Overview (2025‑12‑08)
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
このドキュメントは、JoinIR ライン全体(Loop/If lowering, ExitLine, Boundary, 条件式 lowering)の
|
|
|
|
|
|
「箱」と「契約」を横串でまとめた設計図だよ。selfhost / JsonParser / hako_check など、
|
|
|
|
|
|
どの呼び出し元から見てもここを見れば「JoinIR 層の責務と流れ」が分かるようにしておく。
|
|
|
|
|
|
|
|
|
|
|
|
変更があったら、Phase ドキュメントではなく **このファイルを随時更新する** 方針。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 不変条件(Invariants)
|
|
|
|
|
|
|
|
|
|
|
|
JoinIR ラインで守るべきルールを先に書いておくよ:
|
|
|
|
|
|
|
|
|
|
|
|
1. **JoinIR 内部は JoinIR ValueId だけ**
|
|
|
|
|
|
- JoinIR lowering が発行する `JoinInst` の `ValueId` は、すべて `alloc_value()` で割り当てるローカル ID。
|
|
|
|
|
|
- Rust/MIR 側の ValueId(`builder.variable_map` に入っている ID)は、JoinIR には直接持ち込まない。
|
|
|
|
|
|
|
|
|
|
|
|
2. **host ↔ join の橋渡しは JoinInlineBoundary 系だけ**
|
|
|
|
|
|
- host から JoinIR への入力(ループ変数 / 条件専用変数)は
|
|
|
|
|
|
- `JoinInlineBoundary.join_inputs + host_inputs`
|
|
|
|
|
|
- `JoinInlineBoundary.condition_bindings`(ConditionBinding)
|
|
|
|
|
|
だけで接続する。
|
|
|
|
|
|
- 出力(キャリアの出口)は `JoinInlineBoundary.exit_bindings` に一本化する。
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
3. **LoopHeader PHI を SSA の単一源泉にする**
|
|
|
|
|
|
- ループ変数とキャリアは **LoopHeaderPhiBuilder/LoopHeaderPhiInfo** でヘッダ PHI を作り、これを「現在値」の SSOT にする。
|
|
|
|
|
|
- exit 用の PHI も組むが、変数再接続や expr_result 収集はヘッダ PHI を経由して行う(SSA‑undef 防止)。
|
|
|
|
|
|
|
|
|
|
|
|
4. **式としての戻り値とキャリア更新を分離する**
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 「ループが式として値を返す」ケース(例: `let r = loop_min_while(...)`)の出口は **exit_phi_builder** が扱う。
|
|
|
|
|
|
- 「ループが状態更新だけする」ケース(例: `trim` の `start/end`)の出口は **ExitLine(ExitMeta / ExitBinding / ExitLineReconnector)** だけが扱う。
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
5. **ループ制御 vs 条件式の分離**
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- ループの「形」(Pattern1–4, LoopFeatures)は control-flow 専用の箱が担当。
|
|
|
|
|
|
- 条件式(`i < len && (ch == " " || ch == "\t")` 等)は **BoolExprLowerer / condition_to_joinir** が担当し、
|
|
|
|
|
|
ループパターンは boolean ValueId だけを受け取る。
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
6. **Fail‑Fast**
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- JoinIR が対応していないループパターン / if パターンは、必ず `[joinir/freeze]` 等で明示的にエラーにする。
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- LoopBuilder 等へのサイレントフォールバックは禁止。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-08 18:36:13 +09:00
|
|
|
|
7. **Param の役割(ParamRole)を分ける**
|
|
|
|
|
|
- JoinIR 側で扱うパラメータは概念的に 3 種類に分かれる:
|
|
|
|
|
|
- 条件専用(Condition param): 継続条件や break 条件だけに使う値
|
|
|
|
|
|
- キャリア(Carrier param): ループ状態(pos/result など)として更新される値
|
|
|
|
|
|
- 式結果(Expr param): ループが式として返す値
|
|
|
|
|
|
- ExitLine / Header PHI / InstructionRewriter は **Carrier param だけ** を対象にし、Condition/Expr param は上書きしない。
|
|
|
|
|
|
- 現状は ConditionBinding/ExitMeta/JoinFragmentMeta で役割を区別しており、将来 ParamRole enum として明示する予定。
|
|
|
|
|
|
|
|
|
|
|
|
8. **LoopHeader PHI dst は予約領域(上書き禁止)**
|
2025-12-09 16:19:08 +09:00
|
|
|
|
- LoopHeaderPhiBuilder が生成したヘッダ PHI の dst ValueId は「現在のループ値」の SSOT として扱い、
|
2025-12-08 18:36:13 +09:00
|
|
|
|
BoundaryInjector や InstructionRewriter が `Copy` などで二度書きすることを禁止する。
|
|
|
|
|
|
- merge ラインでは「ヘッダ PHI dst に対する新しい定義が出てきたら debug モードで panic する」ことで契約違反を早期検出する。
|
|
|
|
|
|
|
2025-12-09 16:19:08 +09:00
|
|
|
|
9. **ParamRole の不変条件(Phase 200-A 追加)**
|
|
|
|
|
|
- **Condition 役のパラメータは「PHI dst にしてはいけない」**
|
|
|
|
|
|
- 理由: 条件専用変数はループ内で更新されない(例: `digits` in `_atoi()`)
|
|
|
|
|
|
- LoopHeaderPhiBuilder は Condition 役の変数に対して header PHI を生成しない
|
|
|
|
|
|
- **Condition 役のパラメータは「ExitLine の対象にも入れない」**
|
|
|
|
|
|
- 理由: 条件専用変数はループ外で使われない(ループ内でのみ参照)
|
|
|
|
|
|
- ExitLineReconnector は Condition 役の変数を exit_bindings から除外
|
|
|
|
|
|
- **ParamRole の分類**:
|
|
|
|
|
|
- `LoopParam`: ループ制御変数(例: `i` in `loop(i < len)`)→ header PHI + exit_bindings
|
2025-12-10 00:01:53 +09:00
|
|
|
|
- `Condition`: 条件専用変数(例: `digits` in `digits.indexOf(ch)`)→ condition_bindings のみ
|
|
|
|
|
|
- `Carrier`: 状態更新変数(例: `sum`, `count`)→ header PHI + exit_bindings
|
|
|
|
|
|
- `ExprResult`: ループ戻り値 → exit_phi_builder で処理
|
|
|
|
|
|
|
|
|
|
|
|
10. **JoinIR Core は常時 ON**
|
|
|
|
|
|
- LoopBuilder は物理削除済み。JoinIR を OFF にする経路やフォールバックは存在しない。
|
|
|
|
|
|
- `NYASH_JOINIR_CORE` は deprecated(0 を指定しても警告して無視)。JoinIR の OFF トグルは提供しない。
|
2025-12-09 16:19:08 +09:00
|
|
|
|
|
2025-12-10 08:58:37 +09:00
|
|
|
|
11. **Phase 220: P3 if-sum の ConditionEnv 統合完了**
|
|
|
|
|
|
- **LoopBuilder へのフォールバック経路は Phase 187 で完全削除済み**。
|
|
|
|
|
|
- **P3 if-sum には ConditionPatternBox + ConditionEnv が必須**:
|
|
|
|
|
|
- 単純条件(`var CmpOp literal`)のみ if-sum mode へルーティング(Phase 219-fix)。
|
|
|
|
|
|
- 複雑条件(`i % 2 == 1` 等)は legacy P3 経路へフォールバック。
|
|
|
|
|
|
- **Phase 220-D で loop 条件の変数サポート完了**:
|
|
|
|
|
|
- `loop(i < len)` のような変数条件を ConditionEnv で解決。
|
|
|
|
|
|
- `extract_loop_condition()` を ValueOrLiteral 対応に拡張。
|
|
|
|
|
|
- **Phase 220 で if-sum の expr-result exit contract が P2 と揃った**:
|
|
|
|
|
|
- ExprResultResolver Box で expr_result routing を統一化(Phase 221-R)。
|
|
|
|
|
|
- phase212_if_sum_min.hako → RC=2 達成。
|
|
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-09 19:39:01 +09:00
|
|
|
|
## 1.9 ValueId Space Management (Phase 201)
|
|
|
|
|
|
|
|
|
|
|
|
JoinIR の ValueId 割り当ては **JoinValueSpace** で一元管理され、3つの領域に分離されているよ:
|
|
|
|
|
|
|
|
|
|
|
|
### 1.9.1 ValueId 空間のダイアグラム
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
JoinValueSpace Memory Layout:
|
|
|
|
|
|
|
|
|
|
|
|
0 100 1000 u32::MAX
|
|
|
|
|
|
├──────────┼──────────┼──────────────────────────┤
|
|
|
|
|
|
│ PHI │ Param │ Local │
|
|
|
|
|
|
│ Reserved│ Region │ Region │
|
|
|
|
|
|
└──────────┴──────────┴──────────────────────────┘
|
|
|
|
|
|
|
|
|
|
|
|
PHI Reserved (0-99):
|
|
|
|
|
|
- LoopHeader PHI dst 用の予約領域
|
|
|
|
|
|
- reserve_phi(id) で特定 ID をマーク
|
|
|
|
|
|
|
|
|
|
|
|
Param Region (100-999):
|
|
|
|
|
|
- alloc_param() で割り当て
|
|
|
|
|
|
- 使用箇所: ConditionEnv, CarrierInfo.join_id, CapturedEnv
|
|
|
|
|
|
|
|
|
|
|
|
Local Region (1000+):
|
|
|
|
|
|
- alloc_local() で割り当て
|
|
|
|
|
|
- 使用箇所: Pattern lowerers (Const, BinOp, etc.)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.9.2 JoinValueSpace の役割
|
|
|
|
|
|
|
|
|
|
|
|
- **単一の真実源 (SSOT)**: すべての JoinIR ValueId 割り当てを一箇所で管理
|
|
|
|
|
|
- **領域分離**: Param ID、Local ID、PHI dst が決して重複しない
|
|
|
|
|
|
- **契約検証**: デバッグモードで違反を早期検出
|
|
|
|
|
|
- **後方互換性**: 既存 API は継続動作
|
|
|
|
|
|
|
|
|
|
|
|
### 1.9.3 各コンポーネントと ValueId 領域の対応表
|
|
|
|
|
|
|
|
|
|
|
|
| コンポーネント | 使用領域 | 割り当て方法 | 用途 |
|
|
|
|
|
|
|--------------|---------|------------|------|
|
|
|
|
|
|
| ConditionEnv | Param (100-999) | `alloc_param()` | ループ条件変数の JoinIR ValueId |
|
|
|
|
|
|
| CarrierInfo.join_id | Param (100-999) | `alloc_param()` | キャリア変数の JoinIR ValueId |
|
|
|
|
|
|
| CapturedEnv | Param (100-999) | `alloc_param()` | 関数スコープ変数の JoinIR ValueId |
|
|
|
|
|
|
| Pattern 1 lowerer | Local (1000+) | `alloc_local()` | 中間値(Const, Compare, etc.) |
|
|
|
|
|
|
| Pattern 2 lowerer | Local (1000+) | `alloc_local()` | 中間値(Const, BinOp, etc.) |
|
|
|
|
|
|
| Pattern 3 lowerer | Local (1000+) | `alloc_local()` | 中間値(PHI, Select, etc.) |
|
|
|
|
|
|
| Pattern 4 lowerer | Local (1000+) | `alloc_local()` | 中間値(Select, BinOp, etc.) |
|
|
|
|
|
|
| LoopHeaderPhiBuilder | PHI Reserved (0-99) | `reserve_phi()` | PHI dst ID 保護(上書き防止) |
|
|
|
|
|
|
|
|
|
|
|
|
### 1.9.4 設計原則
|
|
|
|
|
|
|
|
|
|
|
|
1. **領域の固定境界**
|
|
|
|
|
|
- 明確な境界(100, 1000)で領域を分離
|
|
|
|
|
|
- デバッグが容易(ValueId を見ればどの領域か一目瞭然)
|
|
|
|
|
|
- アロケータ間の調整不要
|
|
|
|
|
|
|
|
|
|
|
|
2. **reserve_phi() vs alloc_phi()**
|
|
|
|
|
|
- PHI dst ID は MirBuilder(host 側)から来るため、JoinValueSpace は割り当てない
|
|
|
|
|
|
- `reserve_phi()` はマーカーのみ(「この ID を上書きするな」という契約)
|
|
|
|
|
|
|
|
|
|
|
|
3. **value_id_ranges.rs との関係**
|
|
|
|
|
|
- `value_id_ranges.rs`: **モジュールレベルの分離**(min_loop, skip_ws 等の各モジュールに大きな固定範囲を割り当て)
|
|
|
|
|
|
- `JoinValueSpace`: **lowering 内部の分離**(param vs local vs PHI)
|
|
|
|
|
|
- 両者は相補的な役割
|
|
|
|
|
|
|
2025-12-10 00:01:53 +09:00
|
|
|
|
### 1.9.5 Phase 205: 領域契約の検証強化
|
|
|
|
|
|
|
|
|
|
|
|
**追加された Box-First 機能**:
|
|
|
|
|
|
|
|
|
|
|
|
1. **衝突検出(debug-only)**
|
|
|
|
|
|
- 全ての割り当てられた ValueId を追跡(`allocated_ids: HashSet<u32>`)
|
|
|
|
|
|
- 重複割り当てを即座に検出し panic(Fail-Fast 原則)
|
|
|
|
|
|
- `check_collision()` で実装
|
|
|
|
|
|
|
|
|
|
|
|
2. **領域検証(debug-only)**
|
|
|
|
|
|
- `verify_region(id, expected_region)` で ValueId が期待される領域にいるか検証
|
|
|
|
|
|
- 違反時は明確なエラーメッセージと修正ヒントを提供
|
|
|
|
|
|
- 例: "ValueId(500) is in Param region, expected Local. Hint: Use alloc_local() for JoinIR values"
|
|
|
|
|
|
|
|
|
|
|
|
3. **RegionVerifier Box**
|
|
|
|
|
|
- 場所: `src/mir/builder/control_flow/joinir/merge/mod.rs::verify_valueid_regions()`
|
|
|
|
|
|
- 責務: merge 時に boundary と loop_info の ValueId 領域契約を検証
|
|
|
|
|
|
- 検証項目:
|
|
|
|
|
|
- 全ての `boundary.join_inputs` が Param 領域(100-999)にいる
|
|
|
|
|
|
- 全ての `condition_bindings[].join_value` が Param 領域にいる
|
|
|
|
|
|
- 全ての `carrier_phis[].phi_dst` が有効範囲(<= LOCAL_MAX)内
|
|
|
|
|
|
|
|
|
|
|
|
4. **明示的な領域定数**
|
|
|
|
|
|
```rust
|
|
|
|
|
|
pub const PHI_RESERVED_MIN: u32 = 0;
|
|
|
|
|
|
pub const PHI_RESERVED_MAX: u32 = 99;
|
|
|
|
|
|
pub const PARAM_MIN: u32 = 100;
|
|
|
|
|
|
pub const PARAM_MAX: u32 = 999;
|
|
|
|
|
|
pub const LOCAL_MIN: u32 = 1000;
|
|
|
|
|
|
pub const LOCAL_MAX: u32 = 100000;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Fail-Fast 原則の実装**:
|
|
|
|
|
|
- 領域違反は即座に panic(デバッグモード)
|
|
|
|
|
|
- フォールバックやサイレント修正は一切行わない
|
|
|
|
|
|
- エラーメッセージに具体的な修正方法を含める
|
|
|
|
|
|
|
|
|
|
|
|
詳細は `src/mir/join_ir/lowering/join_value_space.rs` と `phase205-valueid-regions-design.md` を参照。
|
2025-12-09 19:39:01 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
## 2. 主な箱と責務
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 Loop 構造・検出ライン
|
|
|
|
|
|
|
|
|
|
|
|
- **LoopFeatures / LoopPatternKind / router**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/loop_pattern_detection.rs`
|
|
|
|
|
|
- `src/mir/builder/control_flow/joinir/patterns/router.rs`
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- `src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- AST から break/continue/if‑else PHI などの特徴を抽出(ast_feature_extractor)。
|
|
|
|
|
|
- `classify(&LoopFeatures)` で Pattern1–4 に分類し、テーブル駆動の `LOOP_PATTERNS` でルーティング。
|
|
|
|
|
|
- ルータ順序は P4(continue) → P3(if‑phi) → P1(simple) → P2(break) で固定(優先度フィールドはデバッグ用)。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
- **Pattern Lowerers (Pattern1–4)**
|
|
|
|
|
|
- ファイル例:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- `pattern1_minimal.rs`(Simple while)
|
|
|
|
|
|
- `pattern2_with_break.rs`(break 付き / Trim 昇格パスを含む)
|
|
|
|
|
|
- `pattern3_with_if_phi.rs`(if‑phi キャリア)
|
|
|
|
|
|
- `pattern4_with_continue.rs`(continue を Select で表現)
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
|
|
|
|
|
- LoopScopeShape / AST / LoopFeatures を入力として JoinIR の `JoinModule` を構築。
|
|
|
|
|
|
- `JoinFragmentMeta{ expr_result, exit_meta }` を返し、出口情報を ExitLine に渡す。
|
|
|
|
|
|
- host/MIR の ValueId は一切扱わない(JoinIR ローカルの ValueId のみ)。
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **Scope / Env Builders**
|
|
|
|
|
|
- `loop_scope_shape_builder.rs`: ループ本体ローカルの収集、LoopScopeShape 統一生成。
|
|
|
|
|
|
- `condition_env_builder.rs`: 条件専用変数の環境と ConditionBinding を一括構築。
|
|
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- **CommonPatternInitializer** (Phase 33-22)
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/patterns/common_init.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- 全 Pattern 共通の初期化ロジック統一化(ループ変数抽出 + CarrierInfo 構築)。
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 全パターンで boundary.loop_var_name を確実に設定し、SSA‑undef を防ぐ。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-08 19:51:04 +09:00
|
|
|
|
- **PatternPipelineContext** (Phase 179-B)
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- 全 Pattern の前処理結果を格納する「解析済みコンテキスト箱」。
|
|
|
|
|
|
- CommonPatternInitializer + LoopScopeShapeBuilder の結果を統一的に保持。
|
|
|
|
|
|
- Pattern 1-4 の共通データ(loop_var_name, loop_var_id, carrier_info, loop_scope)を提供。
|
|
|
|
|
|
- Pattern 2/4 専用データ(condition_env, carrier_updates, trim_helper)は Option<T> で保持。
|
|
|
|
|
|
- **Analyzer-only dependencies**: 解析ロジックのみ依存、JoinIR emission ロジックは含まない。
|
2025-12-08 21:09:00 +09:00
|
|
|
|
|
|
|
|
|
|
- **TrimLoopLowerer (P5 Dedicated Module)** (Phase 180)
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/patterns/trim_loop_lowering.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- Trim/CharComparison (Pattern 5) 専用の lowering ロジックを一箇所に集約。
|
|
|
|
|
|
- Pattern2/4 から呼ばれ、LoopBodyLocal 変数を carrier に昇格し、Trim パターンの break 条件を置き換える。
|
|
|
|
|
|
- TrimPatternValidator/TrimPatternLowerer を内部で利用し、carrier 初期化コード生成・条件式置換を実行。
|
|
|
|
|
|
- 入力:
|
|
|
|
|
|
- MirBuilder, LoopScopeShape, loop_cond, break_cond, body, loop_var_name, carrier_info, alloc_join_value
|
|
|
|
|
|
- 出力:
|
|
|
|
|
|
- `Some(TrimLoweringResult)`: Trim パターン検出・lowering 成功時(置換後条件、更新 carrier_info、condition_bindings)
|
|
|
|
|
|
- `None`: Trim パターンでない場合(通常ループ処理に戻る)
|
|
|
|
|
|
- `Err`: Trim パターン検出したが lowering 失敗時
|
|
|
|
|
|
- 使用元:
|
|
|
|
|
|
- Pattern2 (pattern2_with_break.rs): Trim/P5 ロジックを完全委譲(~160 行削減)
|
|
|
|
|
|
- Pattern4 (pattern4_with_continue.rs): 将来の Phase 172+ で Trim lowering 実装時に利用予定
|
2025-12-08 19:51:04 +09:00
|
|
|
|
- デザイン原則:
|
|
|
|
|
|
- Pure analysis container(前処理結果のみ保持、emission なし)
|
|
|
|
|
|
- Pattern-specific variants(Option<T> でパターン固有データ管理)
|
|
|
|
|
|
- Single source of truth(全パターンが同じ前処理経路を使用)
|
|
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- **JoinIRConversionPipeline** (Phase 33-22)
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/patterns/conversion_pipeline.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- JoinIR → MIR 変換フロー統一化(JoinModule → MirModule → merge_joinir_mir_blocks)。
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- JoinIR/MIR の関数数・ブロック数をログ出力し、全パターンが同じ入口でマージする。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
### 2.2 条件式ライン(式の箱)
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **BoolExprLowerer / condition_to_joinir**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/join_ir/lowering/bool_expr_lowerer.rs`
|
|
|
|
|
|
- `src/mir/join_ir/lowering/condition_to_joinir.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 通常の if/while 条件を MIR Compare/BinOp/UnaryOp へ lowering。
|
|
|
|
|
|
- ループ lowerer 用の「AST 条件 → JoinIR Compute 命令列」を ConditionEnv とセットで構築。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **ConditionEnv/ConditionBinding + ConditionEnvBuilder**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/join_ir/lowering/condition_env.rs`
|
|
|
|
|
|
- `src/mir/builder/control_flow/joinir/patterns/condition_env_builder.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 変数名→JoinIR ValueId の環境を組み立て、host↔join の橋渡しを ConditionBinding に明示する。
|
|
|
|
|
|
- Pattern 2 では break 条件の全変数をスキャンし、JoinInlineBoundary.condition_bindings に渡す。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-07 23:09:25 +09:00
|
|
|
|
- **LoopConditionScopeBox(Phase 170-D 実装済み)**
|
|
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/loop_condition_scope.rs`
|
2025-12-07 21:29:19 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 条件式の各変数を LoopParam / OuterLocal / LoopBodyLocal に分類。
|
|
|
|
|
|
- 関数パラメータ誤分類バグは `condition_var_analyzer.rs` の修正で解消済み(OuterLocal として扱う)。
|
2025-12-07 23:09:25 +09:00
|
|
|
|
|
2025-12-10 09:29:32 +09:00
|
|
|
|
- **ConditionPatternBox(Phase 219-fix / Phase 222 拡張完了)**
|
2025-12-10 08:58:37 +09:00
|
|
|
|
- ファイル: `src/mir/join_ir/lowering/condition_pattern.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- if 条件の複雑度を判定(SimpleComparison vs Complex)。
|
2025-12-10 09:29:32 +09:00
|
|
|
|
- **Phase 222**: 条件を正規化(var on left の canonical form)。
|
|
|
|
|
|
- `normalize_comparison()` で左右反転をサポート:
|
|
|
|
|
|
- `0 < i` → `i > 0` (literal < var → var > literal)
|
|
|
|
|
|
- `i > j` (var CmpOp var) - そのまま受理
|
2025-12-10 08:58:37 +09:00
|
|
|
|
- 複雑条件(`i % 2 == 1`、MethodCall 等)は false を返し、legacy P3 経路へルーティング。
|
|
|
|
|
|
- 使用箇所:
|
|
|
|
|
|
- PatternPipelineContext.is_if_sum_pattern() で条件複雑度をチェック。
|
2025-12-10 09:29:32 +09:00
|
|
|
|
- P3 if-sum mode は単純比較のみ受理、複雑条件は PoC lowerer へフォールバック。
|
2025-12-10 08:58:37 +09:00
|
|
|
|
|
2025-12-10 17:59:24 +09:00
|
|
|
|
- **MethodCallLowerer(Phase 224-B 実装完了)**
|
|
|
|
|
|
- ファイル: `src/mir/join_ir/lowering/method_call_lowerer.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- AST MethodCall ノードを JoinIR BoxCall に lowering(メタデータ駆動)。
|
|
|
|
|
|
- CoreMethodId の `is_pure()`, `allowed_in_condition()`, `allowed_in_init()` でホワイトリスト判定。
|
|
|
|
|
|
- Phase 224-B P0: 引数なしメソッドのみ対応(`s.length()`, `arr.length()` 等)。
|
|
|
|
|
|
- 設計原則:
|
|
|
|
|
|
- **メソッド名ハードコード禁止**: CoreMethodId メタデータのみ参照。
|
|
|
|
|
|
- **Fail-Fast**: ホワイトリストにないメソッドは即座にエラー。
|
|
|
|
|
|
- **Box-First**: 単一責任("このMethodCallをJoinIRにできるか?")だけを担当。
|
|
|
|
|
|
- 使用箇所:
|
|
|
|
|
|
- `condition_lowerer.rs` の `lower_value_expression()` から呼び出し。
|
|
|
|
|
|
- Pattern 2/3/4 のループ条件式で `s.length()` 等をサポート可能。
|
|
|
|
|
|
- 次ステップ: Phase 224-C で引数付きメソッド(`substring(i, i+1)`, `indexOf(ch)`)対応予定。
|
|
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **LoopBodyCarrierPromoter(Phase 171-C-2 実装済み)**
|
2025-12-07 23:09:25 +09:00
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/loop_body_carrier_promoter.rs`
|
|
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- LoopBodyLocal を Trim パターンとして bool キャリアへ昇格(substring + equality 連鎖を検出)。
|
|
|
|
|
|
- 昇格成功 → CarrierInfo に統合し Pattern 2/4 へ橋渡し。昇格失敗は Fail‑Fast。
|
|
|
|
|
|
- Pattern 2 は安全な Trim なら実際に前処理(substring 生成 + 空白比較の初期化)を emit してから JoinIR lowering。
|
|
|
|
|
|
- Pattern 4 は Trim 昇格が起きた場合はガード付きでエラーにし、未実装を明示(Fail‑Fast)。
|
2025-12-08 13:08:44 +09:00
|
|
|
|
- 汎用性:
|
|
|
|
|
|
- Phase 173 で `_skip_whitespace`(JsonParser)が Trim パターンで動作確認済み。
|
|
|
|
|
|
- Phase 174 で `_parse_string` 最小化版(終端クォート検出)でも動作確認済み。
|
|
|
|
|
|
- → 空白文字以外の文字比較ループにも対応可能(TrimLoopHelper の汎用性実証)。
|
2025-12-08 04:00:44 +09:00
|
|
|
|
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- **LoopBodyCondPromoter(Phase 223-3 + 223.5 + 224 実装完了)**
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/loop_body_cond_promoter.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- ループ条件(header/break/continue)に出てくる LoopBodyLocal を carrier に昇格する統一 API。
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- Pattern 2/Pattern 4 両対応の薄いコーディネーター箱(detection は専門 Promoter に委譲)。
|
|
|
|
|
|
- **Phase 224: Two-tier strategy** - A-3 Trim → A-4 DigitPos フォールバック型オーケストレーション。
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- Phase 223-3 実装内容:
|
|
|
|
|
|
- `extract_continue_condition()`: body 内の if 文から continue 条件を抽出。
|
|
|
|
|
|
- `try_promote_for_condition()`: LoopBodyCarrierPromoter を使った昇格処理。
|
|
|
|
|
|
- Pattern4 への統合完了: LoopBodyLocal 条件の昇格成功時に lowering を続行(以前は Fail-Fast)。
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- Phase 223.5 実装内容:
|
|
|
|
|
|
- Pattern2 への統合完了: header/break 条件を分析し昇格を試みる。
|
|
|
|
|
|
- A-4(digit_pos)テスト追加: cascading LoopBodyLocal パターンで Fail-Fast 動作を確認。
|
|
|
|
|
|
- error_messages.rs に Pattern2 用エラー関数追加: `format_error_pattern2_promotion_failed()` など。
|
|
|
|
|
|
- Phase 224 実装内容(Core Implementation Complete ⚠️):
|
|
|
|
|
|
- **Two-tier promotion**: Step1 で A-3 Trim 試行 → 失敗なら Step2 で A-4 DigitPos 試行 → 両方失敗で Fail-Fast。
|
|
|
|
|
|
- **DigitPosPromoter 統合**: cascading indexOf パターン(substring → indexOf → comparison)の昇格をサポート。
|
|
|
|
|
|
- **Unit test 完全成功**: 6/6 PASS(promoter 自体は完璧動作)。
|
2025-12-10 18:45:04 +09:00
|
|
|
|
- **Phase 224-D**: ConditionAlias/CarrierInfo との連携により、昇格済み LoopBodyLocal 名(`digit_pos` 等)を ConditionEnv から見えるようにブリッジ。
|
|
|
|
|
|
- **残りの制約**: body-local init の MethodCall(`substring` 等)の lowering は Phase 193/224-B/C のスコープ外で、今後の Phase で対応。
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- 設計原則:
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- **Thin coordinator**: 専門 Promoter(LoopBodyCarrierPromoter / DigitPosPromoter)に昇格ロジックを委譲。
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- **Pattern-agnostic**: Pattern2 (break) / Pattern4 (continue) の統一入口として機能。
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- **Fail-Fast with clear routing**: A-3 → A-4 順で試行し、両方失敗なら明示的エラー。
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- 入出力:
|
|
|
|
|
|
- 入力: `ConditionPromotionRequest`(loop_param_name, cond_scope, break_cond/continue_cond, loop_body)
|
|
|
|
|
|
- 出力: `ConditionPromotionResult::Promoted { carrier_info, promoted_var, carrier_name }` または `CannotPromote { reason, vars }`
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- 使用元(Phase 223.5 実装完了、Phase 224 拡張済み):
|
2025-12-10 15:00:20 +09:00
|
|
|
|
- Pattern4: promotion-first(昇格試行 → 成功なら CarrierInfo merge → 失敗なら Fail-Fast)
|
2025-12-10 16:21:01 +09:00
|
|
|
|
- Pattern2: promotion-first(同上、break条件を分析対象とする)
|
|
|
|
|
|
|
|
|
|
|
|
- **DigitPosPromoter(Phase 224 実装完了 ⚠️ Core Complete)**
|
|
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/loop_body_digitpos_promoter.rs`(467 lines)
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- **A-4 pattern**: Cascading LoopBodyLocal with indexOf(substring → indexOf → comparison)の昇格。
|
|
|
|
|
|
- **Pattern detection**: `local ch = s.substring(...); local digit_pos = digits.indexOf(ch); if digit_pos < 0 { break }`
|
|
|
|
|
|
- **Comparison operators**: `<`, `>`, `<=`, `>=`, `!=` をサポート(equality `==` は A-3 Trim 領域)。
|
|
|
|
|
|
- **Dependency validation**: indexOf() が別の LoopBodyLocal に依存していることを検証(cascading pattern)。
|
|
|
|
|
|
- Phase 224 実装内容:
|
|
|
|
|
|
- `try_promote()`: A-4 パターン検出 & bool carrier 昇格(`digit_pos` → `is_digit_pos`)。
|
|
|
|
|
|
- **Unit tests**: 6/6 PASS(basic pattern, non-indexOf rejection, no dependency rejection, comparison operators, equality rejection)。
|
|
|
|
|
|
- **Integration**: LoopBodyCondPromoter から A-3 Trim フォールバック後に呼ばれる。
|
|
|
|
|
|
- 設計原則:
|
|
|
|
|
|
- **One Box, One Question**: A-4 DigitPos パターン専用(A-3 Trim は LoopBodyCarrierPromoter に残す)。
|
|
|
|
|
|
- **Separation of Concerns**: Trim(equality-based)と DigitPos(comparison-based)を分離。
|
|
|
|
|
|
- **Bool carrier consistency**: A-3 Trim と同じく bool carrier に昇格(`is_digit_pos`)。
|
|
|
|
|
|
- 入出力:
|
|
|
|
|
|
- 入力: `DigitPosPromotionRequest`(cond_scope, break_cond/continue_cond, loop_body)
|
|
|
|
|
|
- 出力: `DigitPosPromotionResult::Promoted { carrier_info, promoted_var, carrier_name }` または `CannotPromote { reason, vars }`
|
|
|
|
|
|
- 現状の制約(Phase 224-continuation で対応予定):
|
|
|
|
|
|
- **Promotion は成功**: LoopBodyCondPromoter → DigitPosPromoter → Promoted ✅
|
|
|
|
|
|
- **Lowerer integration gap**: lower_loop_with_break_minimal が昇格済み変数を認識せず、break condition AST に元の変数名が残っているため独立チェックでエラー。
|
|
|
|
|
|
- **Solution**: Option B(promoted variable tracking)で昇格済み変数リストを lowerer に渡す(1-2h 実装予定)。
|
|
|
|
|
|
- 参考:
|
|
|
|
|
|
- 設計ドキュメント: `docs/development/current/main/phase224-digitpos-promoter-design.md`
|
|
|
|
|
|
- 完全サマリ: `docs/development/current/main/PHASE_224_SUMMARY.md`
|
|
|
|
|
|
- テストケース: `apps/tests/phase2235_p2_digit_pos_min.hako`
|
2025-12-10 15:00:20 +09:00
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **ContinueBranchNormalizer / LoopUpdateAnalyzer**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/join_ir/lowering/continue_branch_normalizer.rs`
|
|
|
|
|
|
- `src/mir/join_ir/lowering/loop_update_analyzer.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- else-continue を then-continue へ正規化し、Select ベースの continue を簡潔にする。
|
|
|
|
|
|
- ループ本体で実際に更新されるキャリアだけを抽出(Pattern 4 で不要キャリアを排除)。
|
2025-12-07 21:29:19 +09:00
|
|
|
|
|
2025-12-09 03:59:53 +09:00
|
|
|
|
- **LoopBodyLocalEnv / UpdateEnv / CarrierUpdateEmitter(Phase 184, 191統合完了)**
|
feat(joinir): Phase 184 - Body-local MIR Lowering Infrastructure
Phase 184 implements the foundation for body-local variable support in
update expressions, completing the three-box architecture:
LoopBodyLocalEnv (storage), UpdateEnv (composition), and
CarrierUpdateEmitter (emission).
## Implementation Summary
### Task 184-1: Design Document
- Created phase184-body-local-mir-lowering.md
- Two-Environment System design (ConditionEnv + LoopBodyLocalEnv)
- Box-First design principles documented
### Task 184-2: LoopBodyLocalEnv Implementation
- New file: src/mir/join_ir/lowering/loop_body_local_env.rs (216 lines)
- Storage box for body-local variable name → ValueId mappings
- BTreeMap for deterministic ordering (PHI consistency)
- 7 unit tests: empty env, single/multiple locals, get/contains, iteration
### Task 184-3: UpdateEnv Implementation
- New file: src/mir/join_ir/lowering/update_env.rs (237 lines)
- Composition box for unified variable resolution
- Priority order: ConditionEnv (condition vars) → LoopBodyLocalEnv (body-local)
- 8 unit tests: priority, fallback, not found, combined lookup
### Task 184-4: CarrierUpdateEmitter Integration
- Modified: src/mir/join_ir/lowering/carrier_update_emitter.rs
- Added emit_carrier_update_with_env() (UpdateEnv version)
- Kept emit_carrier_update() for backward compatibility
- 4 new unit tests: body-local variable, priority, not found, const update
- Total 10 tests PASS (6 existing + 4 new)
### Task 184-5: Representative Test Cases
- apps/tests/phase184_body_local_update.hako (Pattern1 baseline)
- apps/tests/phase184_body_local_with_break.hako (Pattern2, Phase 185 target)
### Task 184-6: Documentation Updates
- Updated: docs/development/current/main/joinir-architecture-overview.md
- Updated: CURRENT_TASK.md (Phase 184 completion record)
## Test Results
All 25 unit tests PASS:
- LoopBodyLocalEnv: 7 tests
- UpdateEnv: 8 tests
- CarrierUpdateEmitter: 10 tests (6 existing + 4 new)
Build: ✅ Success (0 errors)
## Design Constraints
Following 箱理論 (Box Theory) principles:
- Single Responsibility: Each box has one clear purpose
- Deterministic: BTreeMap ensures consistent ordering
- Conservative: Pattern5 (Trim) integration deferred to Phase 185
- Fail-Fast: Explicit errors for unsupported patterns
## Scope Limitation
Phase 184 provides the **infrastructure only**:
- ✅ Storage box (LoopBodyLocalEnv)
- ✅ Composition box (UpdateEnv)
- ✅ Emission support (CarrierUpdateEmitter)
- ❌ Pattern2/4 integration (requires body-local collection, Phase 185)
## Next Steps
Phase 185: Pattern2/4 Integration
- Integrate LoopBodyLocalEnv into Pattern2/4 lowerers
- Add body-local variable collection from loop body AST
- Enable full E2E body-local variable support in update expressions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 23:59:19 +09:00
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/join_ir/lowering/loop_body_local_env.rs`
|
|
|
|
|
|
- `src/mir/join_ir/lowering/update_env.rs`
|
|
|
|
|
|
- `src/mir/join_ir/lowering/carrier_update_emitter.rs`
|
2025-12-09 03:59:53 +09:00
|
|
|
|
- `src/mir/join_ir/lowering/loop_with_break_minimal.rs`(Phase 191統合)
|
feat(joinir): Phase 184 - Body-local MIR Lowering Infrastructure
Phase 184 implements the foundation for body-local variable support in
update expressions, completing the three-box architecture:
LoopBodyLocalEnv (storage), UpdateEnv (composition), and
CarrierUpdateEmitter (emission).
## Implementation Summary
### Task 184-1: Design Document
- Created phase184-body-local-mir-lowering.md
- Two-Environment System design (ConditionEnv + LoopBodyLocalEnv)
- Box-First design principles documented
### Task 184-2: LoopBodyLocalEnv Implementation
- New file: src/mir/join_ir/lowering/loop_body_local_env.rs (216 lines)
- Storage box for body-local variable name → ValueId mappings
- BTreeMap for deterministic ordering (PHI consistency)
- 7 unit tests: empty env, single/multiple locals, get/contains, iteration
### Task 184-3: UpdateEnv Implementation
- New file: src/mir/join_ir/lowering/update_env.rs (237 lines)
- Composition box for unified variable resolution
- Priority order: ConditionEnv (condition vars) → LoopBodyLocalEnv (body-local)
- 8 unit tests: priority, fallback, not found, combined lookup
### Task 184-4: CarrierUpdateEmitter Integration
- Modified: src/mir/join_ir/lowering/carrier_update_emitter.rs
- Added emit_carrier_update_with_env() (UpdateEnv version)
- Kept emit_carrier_update() for backward compatibility
- 4 new unit tests: body-local variable, priority, not found, const update
- Total 10 tests PASS (6 existing + 4 new)
### Task 184-5: Representative Test Cases
- apps/tests/phase184_body_local_update.hako (Pattern1 baseline)
- apps/tests/phase184_body_local_with_break.hako (Pattern2, Phase 185 target)
### Task 184-6: Documentation Updates
- Updated: docs/development/current/main/joinir-architecture-overview.md
- Updated: CURRENT_TASK.md (Phase 184 completion record)
## Test Results
All 25 unit tests PASS:
- LoopBodyLocalEnv: 7 tests
- UpdateEnv: 8 tests
- CarrierUpdateEmitter: 10 tests (6 existing + 4 new)
Build: ✅ Success (0 errors)
## Design Constraints
Following 箱理論 (Box Theory) principles:
- Single Responsibility: Each box has one clear purpose
- Deterministic: BTreeMap ensures consistent ordering
- Conservative: Pattern5 (Trim) integration deferred to Phase 185
- Fail-Fast: Explicit errors for unsupported patterns
## Scope Limitation
Phase 184 provides the **infrastructure only**:
- ✅ Storage box (LoopBodyLocalEnv)
- ✅ Composition box (UpdateEnv)
- ✅ Emission support (CarrierUpdateEmitter)
- ❌ Pattern2/4 integration (requires body-local collection, Phase 185)
## Next Steps
Phase 185: Pattern2/4 Integration
- Integrate LoopBodyLocalEnv into Pattern2/4 lowerers
- Add body-local variable collection from loop body AST
- Enable full E2E body-local variable support in update expressions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 23:59:19 +09:00
|
|
|
|
- 責務:
|
|
|
|
|
|
- **LoopBodyLocalEnv**: ループ本体で宣言された body-local 変数の名前→ValueId マッピングを管理(箱化設計)。
|
|
|
|
|
|
- **UpdateEnv**: 条件変数(ConditionEnv)と body-local 変数(LoopBodyLocalEnv)を統合した変数解決層。
|
|
|
|
|
|
- Priority order: 1. Condition variables(高優先度) → 2. Body-local variables(フォールバック)
|
|
|
|
|
|
- **CarrierUpdateEmitter**: UpdateExpr を JoinIR 命令に変換する際、UpdateEnv を使用して body-local 変数をサポート。
|
|
|
|
|
|
- `emit_carrier_update_with_env()`: UpdateEnv 版(Phase 184 新規)
|
|
|
|
|
|
- `emit_carrier_update()`: ConditionEnv 版(後方互換)
|
2025-12-09 03:59:53 +09:00
|
|
|
|
- **LoopBodyLocalInitLowerer**: Phase 191 で Pattern2 に統合完了。
|
|
|
|
|
|
- 対応済み init 式: 整数リテラル、変数参照、二項演算(`local digit = i + 1`)
|
|
|
|
|
|
- UpdateEnv の優先順位により ConditionEnv → LoopBodyLocalEnv の順で変数解決
|
feat(joinir): Phase 184 - Body-local MIR Lowering Infrastructure
Phase 184 implements the foundation for body-local variable support in
update expressions, completing the three-box architecture:
LoopBodyLocalEnv (storage), UpdateEnv (composition), and
CarrierUpdateEmitter (emission).
## Implementation Summary
### Task 184-1: Design Document
- Created phase184-body-local-mir-lowering.md
- Two-Environment System design (ConditionEnv + LoopBodyLocalEnv)
- Box-First design principles documented
### Task 184-2: LoopBodyLocalEnv Implementation
- New file: src/mir/join_ir/lowering/loop_body_local_env.rs (216 lines)
- Storage box for body-local variable name → ValueId mappings
- BTreeMap for deterministic ordering (PHI consistency)
- 7 unit tests: empty env, single/multiple locals, get/contains, iteration
### Task 184-3: UpdateEnv Implementation
- New file: src/mir/join_ir/lowering/update_env.rs (237 lines)
- Composition box for unified variable resolution
- Priority order: ConditionEnv (condition vars) → LoopBodyLocalEnv (body-local)
- 8 unit tests: priority, fallback, not found, combined lookup
### Task 184-4: CarrierUpdateEmitter Integration
- Modified: src/mir/join_ir/lowering/carrier_update_emitter.rs
- Added emit_carrier_update_with_env() (UpdateEnv version)
- Kept emit_carrier_update() for backward compatibility
- 4 new unit tests: body-local variable, priority, not found, const update
- Total 10 tests PASS (6 existing + 4 new)
### Task 184-5: Representative Test Cases
- apps/tests/phase184_body_local_update.hako (Pattern1 baseline)
- apps/tests/phase184_body_local_with_break.hako (Pattern2, Phase 185 target)
### Task 184-6: Documentation Updates
- Updated: docs/development/current/main/joinir-architecture-overview.md
- Updated: CURRENT_TASK.md (Phase 184 completion record)
## Test Results
All 25 unit tests PASS:
- LoopBodyLocalEnv: 7 tests
- UpdateEnv: 8 tests
- CarrierUpdateEmitter: 10 tests (6 existing + 4 new)
Build: ✅ Success (0 errors)
## Design Constraints
Following 箱理論 (Box Theory) principles:
- Single Responsibility: Each box has one clear purpose
- Deterministic: BTreeMap ensures consistent ordering
- Conservative: Pattern5 (Trim) integration deferred to Phase 185
- Fail-Fast: Explicit errors for unsupported patterns
## Scope Limitation
Phase 184 provides the **infrastructure only**:
- ✅ Storage box (LoopBodyLocalEnv)
- ✅ Composition box (UpdateEnv)
- ✅ Emission support (CarrierUpdateEmitter)
- ❌ Pattern2/4 integration (requires body-local collection, Phase 185)
## Next Steps
Phase 185: Pattern2/4 Integration
- Integrate LoopBodyLocalEnv into Pattern2/4 lowerers
- Add body-local variable collection from loop body AST
- Enable full E2E body-local variable support in update expressions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 23:59:19 +09:00
|
|
|
|
- 設計原則:
|
|
|
|
|
|
- **箱理論**: 各 Box が単一責任を持ち、境界明確。
|
|
|
|
|
|
- **決定性**: BTreeMap 使用で一貫した順序保証(PHI 生成の決定性)。
|
2025-12-09 04:28:10 +09:00
|
|
|
|
- **Phase 192完了**: Complex addend(`v = v*10 + f(x)`)は ComplexAddendNormalizer で temp に分解してから NumberAccumulation に載せる。
|
|
|
|
|
|
- `complex_addend_normalizer.rs`: Pure AST transformer(前処理箱)
|
|
|
|
|
|
- Pattern2 統合完了、emission ライン再利用(変更なし)
|
|
|
|
|
|
- 制約: MethodCall を含む init 式は Phase 193 で対応予定
|
feat(joinir): Phase 184 - Body-local MIR Lowering Infrastructure
Phase 184 implements the foundation for body-local variable support in
update expressions, completing the three-box architecture:
LoopBodyLocalEnv (storage), UpdateEnv (composition), and
CarrierUpdateEmitter (emission).
## Implementation Summary
### Task 184-1: Design Document
- Created phase184-body-local-mir-lowering.md
- Two-Environment System design (ConditionEnv + LoopBodyLocalEnv)
- Box-First design principles documented
### Task 184-2: LoopBodyLocalEnv Implementation
- New file: src/mir/join_ir/lowering/loop_body_local_env.rs (216 lines)
- Storage box for body-local variable name → ValueId mappings
- BTreeMap for deterministic ordering (PHI consistency)
- 7 unit tests: empty env, single/multiple locals, get/contains, iteration
### Task 184-3: UpdateEnv Implementation
- New file: src/mir/join_ir/lowering/update_env.rs (237 lines)
- Composition box for unified variable resolution
- Priority order: ConditionEnv (condition vars) → LoopBodyLocalEnv (body-local)
- 8 unit tests: priority, fallback, not found, combined lookup
### Task 184-4: CarrierUpdateEmitter Integration
- Modified: src/mir/join_ir/lowering/carrier_update_emitter.rs
- Added emit_carrier_update_with_env() (UpdateEnv version)
- Kept emit_carrier_update() for backward compatibility
- 4 new unit tests: body-local variable, priority, not found, const update
- Total 10 tests PASS (6 existing + 4 new)
### Task 184-5: Representative Test Cases
- apps/tests/phase184_body_local_update.hako (Pattern1 baseline)
- apps/tests/phase184_body_local_with_break.hako (Pattern2, Phase 185 target)
### Task 184-6: Documentation Updates
- Updated: docs/development/current/main/joinir-architecture-overview.md
- Updated: CURRENT_TASK.md (Phase 184 completion record)
## Test Results
All 25 unit tests PASS:
- LoopBodyLocalEnv: 7 tests
- UpdateEnv: 8 tests
- CarrierUpdateEmitter: 10 tests (6 existing + 4 new)
Build: ✅ Success (0 errors)
## Design Constraints
Following 箱理論 (Box Theory) principles:
- Single Responsibility: Each box has one clear purpose
- Deterministic: BTreeMap ensures consistent ordering
- Conservative: Pattern5 (Trim) integration deferred to Phase 185
- Fail-Fast: Explicit errors for unsupported patterns
## Scope Limitation
Phase 184 provides the **infrastructure only**:
- ✅ Storage box (LoopBodyLocalEnv)
- ✅ Composition box (UpdateEnv)
- ✅ Emission support (CarrierUpdateEmitter)
- ❌ Pattern2/4 integration (requires body-local collection, Phase 185)
## Next Steps
Phase 185: Pattern2/4 Integration
- Integrate LoopBodyLocalEnv into Pattern2/4 lowerers
- Add body-local variable collection from loop body AST
- Enable full E2E body-local variable support in update expressions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 23:59:19 +09:00
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
### 2.3 キャリア / Exit / Boundary ライン
|
|
|
|
|
|
|
2025-12-09 18:32:03 +09:00
|
|
|
|
- **Phase 200-B: FunctionScopeCaptureAnalyzer (完了)**
|
|
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/function_scope_capture.rs`
|
|
|
|
|
|
- 責務: 関数スコープの「実質定数」を検出
|
|
|
|
|
|
- 判定条件:
|
|
|
|
|
|
1. 関数トップレベルで 1 回だけ定義
|
|
|
|
|
|
2. ループ内で再代入なし
|
|
|
|
|
|
3. 安全な初期式(文字列/整数リテラル)のみ
|
|
|
|
|
|
- 結果: CapturedEnv に name, host_id, is_immutable を格納
|
|
|
|
|
|
- **ConditionEnvBuilder v2**:
|
|
|
|
|
|
- 責務: CapturedEnv から ParamRole::Condition として ConditionEnv に追加
|
|
|
|
|
|
- 経路: analyze_captured_vars → build_with_captures → ConditionEnv.captured
|
|
|
|
|
|
- 不変条件: Condition role は Header PHI / ExitLine の対象にならない
|
|
|
|
|
|
- **Pattern 2 統合**: Phase 200-C で完了 ✅
|
|
|
|
|
|
- MirBuilder.fn_body_ast フィールド追加
|
|
|
|
|
|
- LoopPatternContext.fn_body 経由で Pattern 2 lowerer に渡す
|
|
|
|
|
|
- analyze_captured_vars_v2() で構造的ループ検索(ポインタ比較 → AST 構造比較)
|
|
|
|
|
|
|
|
|
|
|
|
- **Phase 200-C: digits.indexOf E2E 連携 (完了)**
|
|
|
|
|
|
- 目的: 200-A/B インフラを実際に Pattern 2 経路に統合
|
|
|
|
|
|
- 実装:
|
|
|
|
|
|
- fn_body を MirBuilder → LoopPatternContext → Pattern 2 に渡す
|
|
|
|
|
|
- analyze_captured_vars_v2() で構造的マッチング(AST Debug 文字列比較)
|
|
|
|
|
|
- digits / s 等の関数ローカル定数が CapturedEnv に正しく捕捉される
|
|
|
|
|
|
- 検証結果:
|
|
|
|
|
|
- capture 検出: ✅ PASS
|
|
|
|
|
|
- E2E 実行: ❌ BLOCKED(テストケースが Pattern 5+ 必要)
|
|
|
|
|
|
- テストケース制約:
|
|
|
|
|
|
- phase200_digits_atoi_min.hako: body-local `pos` を条件 `if pos < 0` で使用
|
|
|
|
|
|
- → Pattern 5 (body-local promotion) が必要
|
|
|
|
|
|
|
|
|
|
|
|
- **Phase 200-D: digits capture "実戦 1 本" 検証 (完了)**
|
|
|
|
|
|
- 目的: capture 経路の E2E 検証(body-local なしのシンプルケース)
|
|
|
|
|
|
- 検証結果:
|
|
|
|
|
|
- capture 検出: ✅ PASS(base, limit, n 等が正しく CapturedEnv に)
|
|
|
|
|
|
- ConditionEnv 統合: ✅ PASS(captured vars が ConditionEnv.captured に追加)
|
|
|
|
|
|
- 実行: ⚠️ 別の制約でブロック(substring 未対応、キャリア更新型問題)
|
|
|
|
|
|
- 成果:
|
|
|
|
|
|
- capture 経路(analyze_captured_vars_v2 → ConditionEnv → Pattern 2)が正常動作
|
|
|
|
|
|
- 関数スコープ定数が正しく検出・統合される
|
|
|
|
|
|
- テストファイル: phase200d_capture_minimal.hako, phase200d_capture_in_condition.hako
|
|
|
|
|
|
|
2025-12-09 01:09:54 +09:00
|
|
|
|
- **CarrierInfo / LoopUpdateAnalyzer / CarrierUpdateEmitter**
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/join_ir/lowering/carrier_info.rs`
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- `src/mir/join_ir/lowering/loop_update_analyzer.rs`
|
2025-12-09 01:09:54 +09:00
|
|
|
|
- `src/mir/join_ir/lowering/carrier_update_emitter.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- ループで更新される変数(carrier)を検出し、UpdateExpr を保持。
|
|
|
|
|
|
- Pattern 4 では実際に更新されるキャリアだけを残す。
|
2025-12-09 01:09:54 +09:00
|
|
|
|
- **Phase 188 完了** ✅: String 更新(StringAppendChar/StringAppendLiteral)を UpdateRhs ベースのホワイトリストで受理し、JoinIR BinOp を emit。
|
|
|
|
|
|
- 許可: `UpdateRhs::Const`, `UpdateRhs::Variable`, `UpdateRhs::StringLiteral`
|
|
|
|
|
|
- 拒否: `UpdateRhs::Other`(method call / nested BinOp 等の複雑パターンのみ)
|
|
|
|
|
|
- Pattern2/4 の can_lower() で選別、carrier_update_emitter.rs で JoinIR 生成
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
- **ExitMeta / JoinFragmentMeta**
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- ファイル: `carrier_info.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- JoinIR lowerer が出口の JoinIR ValueId を記録(expr_result とキャリアを明確に分離)。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **LoopHeader PHI Builder**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/builder/control_flow/joinir/merge/loop_header_phi_info.rs`
|
|
|
|
|
|
- `loop_header_phi_builder.rs`
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- ループ変数とキャリアの PHI をヘッダブロックに生成し、entry/latch の 2 入力で SSA を確立。
|
|
|
|
|
|
- instruction_rewriter が latch 側を埋めた後に finalize して挿入する。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
- **JoinInlineBoundary**
|
|
|
|
|
|
- ファイル: `src/mir/join_ir/lowering/inline_boundary.rs`
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 主フィールド:
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- `join_inputs / host_inputs`:ループパラメータの橋渡し
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- `condition_bindings`:条件専用変数の橋渡し(JoinIR ValueId を明示)
|
|
|
|
|
|
- `exit_bindings`:キャリア出口の橋渡し(carrier 名を明示)
|
|
|
|
|
|
- `expr_result` / `loop_var_name`:expr result / ヘッダ PHI 生成用のメタ情報
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- 「host ↔ JoinIR」の境界情報の SSOT。各パターン lowerer がここに全て詰めてから merge する。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
- **BoundaryInjector**
|
|
|
|
|
|
- ファイル: `src/mir/builder/joinir_inline_boundary_injector.rs`
|
|
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- `join_inputs` と `condition_bindings` を entry block に Copy で注入し、JoinIR ローカル ID と host ID を接続。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
- **ExitLine (ExitMetaCollector / ExitLineReconnector / ExitLineOrchestrator)**
|
|
|
|
|
|
- ファイル:
|
|
|
|
|
|
- `src/mir/builder/control_flow/joinir/merge/exit_line/mod.rs`
|
|
|
|
|
|
- `exit_line/meta_collector.rs`
|
|
|
|
|
|
- `exit_line/reconnector.rs`
|
|
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- ExitMeta から exit_bindings を構築(Collector)。
|
|
|
|
|
|
- 変数再接続はヘッダ PHI の dst を使って `builder.variable_map` を更新(Reconnector)。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- expr 用の PHI には一切触れない(carrier 専用ライン)。
|
|
|
|
|
|
|
2025-12-10 08:58:37 +09:00
|
|
|
|
- **ExprResultResolver(Phase 221-R 実装済み)**
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/merge/expr_result_resolver.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- expr_result ValueId を exit_bindings/carrier_phis と照合し、適切な出口値を解決。
|
|
|
|
|
|
- expr_result が carrier の場合: carrier PHI dst を返す(変数再接続と統一)。
|
|
|
|
|
|
- expr_result が非 carrier の場合: remapped ValueId を返す(expr-only の値)。
|
|
|
|
|
|
- 特徴:
|
|
|
|
|
|
- Phase 33 モジュール化パターン準拠(ExitMetaCollector/ExitLineReconnector と同様)。
|
|
|
|
|
|
- 4つのシナリオを unit test でカバー(carrier/non-carrier/None/error)。
|
|
|
|
|
|
- merge/mod.rs から 64 行を抽出、-37 行のネット削減。
|
|
|
|
|
|
|
2025-12-08 06:14:03 +09:00
|
|
|
|
- **JoinInlineBoundaryBuilder(Phase 200-2 / Phase 201 完了)**
|
2025-12-08 04:35:13 +09:00
|
|
|
|
- ファイル: `src/mir/join_ir/lowering/inline_boundary_builder.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- JoinInlineBoundary の構築を Builder パターンで統一化。
|
|
|
|
|
|
- フィールド直書きの散乱を防ぎ、inputs/outputs/condition_bindings/exit_bindings/loop_var_name/expr_result の設定を fluent API で実施。
|
2025-12-08 06:14:03 +09:00
|
|
|
|
- **Phase 201 で Pattern1/2/3/4 全てに適用完了**(境界情報組み立てを 1 箇所に集約)。
|
2025-12-08 04:35:13 +09:00
|
|
|
|
|
|
|
|
|
|
- **JoinIRVerifier(Phase 200-3 追加)**
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/merge/mod.rs`(debug_assertions 専用関数)
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- LoopHeader PHI / ExitLine 契約をデバッグビルドで検証する門番。
|
|
|
|
|
|
- `verify_loop_header_phis()`: loop_var_name がある場合にヘッダ PHI が存在するか確認。
|
|
|
|
|
|
- `verify_exit_line()`: exit_bindings が exit block に対応しているか確認。
|
|
|
|
|
|
- `verify_joinir_contracts()`: merge_joinir_mir_blocks() の最後で全契約を一括チェック。
|
|
|
|
|
|
- release ビルドでは完全に除去される(`#[cfg(debug_assertions)]`)。
|
|
|
|
|
|
|
2025-12-09 16:19:08 +09:00
|
|
|
|
- **FunctionScopeCaptureAnalyzer / CapturedEnv(Phase 200-A 追加)**
|
|
|
|
|
|
- ファイル: `src/mir/loop_pattern_detection/function_scope_capture.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- 関数スコープで宣言され、ループ内で不変な変数("実質定数")を検出。
|
|
|
|
|
|
- 例: `local digits = "0123456789"` in `JsonParser._atoi()`
|
|
|
|
|
|
- CapturedVar: `{ name, host_id, is_immutable }`
|
|
|
|
|
|
- CapturedEnv: 検出された変数のコレクション
|
|
|
|
|
|
- **Phase 200-A**: 型と空実装のみ(skeleton)。
|
|
|
|
|
|
- **Phase 200-B**: 実際の検出ロジックを実装予定(AST スキャン + 再代入チェック)。
|
|
|
|
|
|
|
|
|
|
|
|
- **ParamRole enum(Phase 200-A 追加)**
|
|
|
|
|
|
- ファイル: `src/mir/join_ir/lowering/inline_boundary_builder.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- JoinInlineBoundary のパラメータ役割を明示的に区別。
|
|
|
|
|
|
- LoopParam / Condition / Carrier / ExprResult の 4 種類。
|
|
|
|
|
|
- **不変条件**:
|
|
|
|
|
|
- **Condition 役**: PHI dst にしてはいけない(ループ内で更新されない)。
|
|
|
|
|
|
- **Condition 役**: ExitLine の対象にも入れない(ループ外で使われない)。
|
|
|
|
|
|
- 理由: 条件専用変数(例: `digits`)はループ内でのみ参照され、不変。
|
|
|
|
|
|
- **Phase 200-A**: enum 定義のみ。
|
|
|
|
|
|
- **Phase 200-B**: ルーティングロジック実装予定(CapturedEnv 統合時)。
|
|
|
|
|
|
|
|
|
|
|
|
- **ConditionEnvBuilder::build_with_captures(Phase 200-A 追加)**
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/patterns/condition_env_builder.rs`
|
|
|
|
|
|
- 責務:
|
|
|
|
|
|
- 将来 CapturedEnv を受け取り、ConditionEnv に統合する v2 入口。
|
|
|
|
|
|
- **Phase 200-A**: 既存実装に委譲する skeleton。
|
|
|
|
|
|
- **Phase 200-B**: CapturedEnv の変数を condition_bindings に追加する実装予定。
|
|
|
|
|
|
|
2025-12-07 21:02:20 +09:00
|
|
|
|
### 2.4 expr result ライン(式としての戻り値)
|
|
|
|
|
|
|
|
|
|
|
|
- **exit_phi_builder**
|
|
|
|
|
|
- ファイル: `src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs`
|
|
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- JoinIR fragment が `expr_result` を持つときに exit ブロックへ PHI を生成。
|
|
|
|
|
|
- carrier_inputs も受け取り exit ブロックに PHI を作るが、再接続の SSOT は LoopHeader PHI(ExitLine はヘッダ PHI を使用)。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- **InstructionRewriter**
|
2025-12-07 21:02:20 +09:00
|
|
|
|
- ファイル: `instruction_rewriter.rs`
|
|
|
|
|
|
- 責務:
|
2025-12-08 04:00:44 +09:00
|
|
|
|
- continuation 関数(k_exit)をスキップし、Return → exit ブロック Jump に変換。
|
|
|
|
|
|
- `JoinFragmentMeta.expr_result` と exit_bindings をヘッダ PHI 経由で収集し、`exit_phi_inputs` / `carrier_inputs` を復活させた(SSA‑undef 修正済み)。
|
|
|
|
|
|
- tail call を Branch/Jump に書き換えつつ、LoopHeaderPhiInfo に latch 入力を記録する。
|
2025-12-09 14:56:05 +09:00
|
|
|
|
- **Select 展開の不変条件(Phase 196)**:
|
|
|
|
|
|
- PHI の入力 ValueId は必ず `remapper.remap_instruction()` で remap 済みの MIR ValueId を使用。
|
|
|
|
|
|
- InstructionRewriter では ValueId の二重 remap を行わない(block ID のみ remap)。
|
|
|
|
|
|
- 詳細: [phase196-select-bug-analysis.md](./phase196-select-bug-analysis.md)
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. JoinIR → MIR 統合の全体フロー
|
|
|
|
|
|
|
|
|
|
|
|
1. Pattern router が AST/LoopFeatures から Pattern1–4 を選択し、各 lowerer が
|
|
|
|
|
|
`(JoinModule, JoinFragmentMeta)` を生成。
|
|
|
|
|
|
2. `JoinInlineBoundary` が:
|
|
|
|
|
|
- ループ入力(join_inputs/host_inputs)
|
|
|
|
|
|
- 条件変数(condition_bindings)
|
|
|
|
|
|
- キャリア出口(exit_bindings)
|
|
|
|
|
|
を保持。
|
2025-12-08 04:00:44 +09:00
|
|
|
|
3. `merge_joinir_mir_blocks` が(マルチ関数対応):
|
|
|
|
|
|
- 全関数の BlockID を再割り当て(block_allocator)し、ValueId はパラメータを除外して収集。
|
|
|
|
|
|
- Boundary の condition/exit Bindings の JoinIR ValueId も remap 対象に追加。
|
|
|
|
|
|
- LoopHeader PHI を生成(loop_header_phi_builder)し、latch 側は instruction_rewriter が埋める。
|
|
|
|
|
|
- instruction_rewriter で関数をマージしつつ Call→Jump に変換、k_exit 関数はスキップ。
|
|
|
|
|
|
- BoundaryInjector で entry block に Copy を注入(join_inputs + condition_bindings)。
|
|
|
|
|
|
- Header PHI を finalize → exit_phi_builder で expr_result/carrier の exit PHI を構築。
|
|
|
|
|
|
- ExitLineOrchestrator がヘッダ PHI dst を使って variable_map を更新。
|
|
|
|
|
|
- host の現在ブロックから JoinIR entry へ jump を張り、exit ブロックに切り替える。
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
この全体フローの詳細は `src/mir/builder/control_flow/joinir/merge/mod.rs` と
|
|
|
|
|
|
`phase-189-multi-function-mir-merge/README.md` を参照。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-08 21:41:19 +09:00
|
|
|
|
## 4. JsonParser / Trim / P5 ループの現在地(Phase 170–181)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 JsonParser ループ空間と P1–P5
|
|
|
|
|
|
|
|
|
|
|
|
Phase 181 で JsonParserBox 内の 11 ループを棚卸しした結果、
|
|
|
|
|
|
構造的には **すべて JoinIR Pattern1–4 (+ P5) で扱える** ことが分かったよ。
|
|
|
|
|
|
|
|
|
|
|
|
- 既に JoinIR 経路で動作しているもの:
|
|
|
|
|
|
- `_skip_whitespace`(P2 + P5 Trim)
|
|
|
|
|
|
- `_trim` leading/trailing(P2 + P5 Trim)
|
|
|
|
|
|
- **Phase 182 で P1/P2 パターン検証完了** ✅:
|
|
|
|
|
|
- Pattern1 (Simple): `_match_literal` 系ループで動作確認済み(apps/tests/phase182_p1_match_literal.hako)
|
|
|
|
|
|
- Pattern2 (Break): 整数演算ループで動作確認済み(apps/tests/phase182_p2_break_integer.hako)
|
|
|
|
|
|
- **ブロッカー発見**: 実際の JsonParser ループには 2 つの制約が必要:
|
|
|
|
|
|
1. LoopBodyLocal 変数の扱い(`ch`, `digit_pos`, `pos` など)
|
|
|
|
|
|
- 現状は Trim pattern 専用の carrier 昇格を試みてエラーになる
|
|
|
|
|
|
- P1/P2 では純粋なローカル変数(昇格不要)として扱うべき
|
|
|
|
|
|
2. 文字列連結フィルタ(Phase 178)
|
|
|
|
|
|
- `num_str = num_str + ch` のような string concat を保守的に reject
|
|
|
|
|
|
- JsonParser では必須の操作なので段階的に有効化が必要
|
2025-12-08 23:43:26 +09:00
|
|
|
|
- **設計原則**:
|
|
|
|
|
|
- string は「特別扱いのパターン」ではなく、あくまで MirType の 1 種類として扱う。
|
|
|
|
|
|
- Pattern2/4 側で型名や変数名(`"result"`, `"num_str"` など)に依存した分岐は入れない。
|
|
|
|
|
|
- LoopUpdateAnalyzer の `UpdateKind` / `UpdateRhs` で「安全な更新パターン」を列挙し、
|
|
|
|
|
|
そのうち string にも適用可能なものだけを **ホワイトリストで許可**する。
|
|
|
|
|
|
- 実際の lowering は CarrierUpdateLowerer / 式 Lowerer 側で行い、JoinIR のループ形(P1–P4)は増やさない。
|
2025-12-09 01:54:53 +09:00
|
|
|
|
3. 数値の桁展開(Phase 190 設計完了)
|
|
|
|
|
|
- `v = v * 10 + digit` のような NumberAccumulation パターンを UpdateKind で whitelist 制御。
|
|
|
|
|
|
- 型制約: Integer のみ許可(String は StringAppendChar 使用)。
|
|
|
|
|
|
- 検出: AST 構造解析(名前依存禁止)、Complex パターンは Fail-Fast で reject。
|
2025-12-08 23:14:10 +09:00
|
|
|
|
- **Phase 183 で LoopBodyLocal 役割分離完了** ✅:
|
|
|
|
|
|
- **設計**: LoopBodyLocal を 2 カテゴリに分類:
|
|
|
|
|
|
- **Condition LoopBodyLocal**: ループ条件(header/break/continue)で使用 → Trim 昇格対象
|
|
|
|
|
|
- **Body-only LoopBodyLocal**: ループ本体のみで使用 → 昇格不要、pure local 扱い
|
|
|
|
|
|
- **実装**: TrimLoopLowerer に `is_var_used_in_condition()` ヘルパー追加
|
|
|
|
|
|
- 条件で使われていない LoopBodyLocal は Trim 昇格スキップ
|
|
|
|
|
|
- 5 つの unit test で変数検出ロジックを検証
|
|
|
|
|
|
- **テスト**: `apps/tests/phase183_body_only_loopbodylocal.hako` で動作確認
|
|
|
|
|
|
- `[TrimLoopLowerer] No LoopBodyLocal detected` トレース出力で body-only 判定成功
|
2025-12-09 00:59:38 +09:00
|
|
|
|
- **次の課題(→Phase 184 で対応)**: body-local 変数の MIR lowering 対応(`local temp` in loop body)
|
2025-12-08 23:14:10 +09:00
|
|
|
|
- Phase 183 では "Trim promotion しない" 判定まで完了
|
2025-12-09 00:59:38 +09:00
|
|
|
|
- 実際の MIR 生成インフラは Phase 184 で実装済み(Pattern2/4 への統合は次フェーズ)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 Body-local 変数の MIR lowering 基盤(Phase 184)
|
|
|
|
|
|
|
|
|
|
|
|
Phase 184 では、「条件には出てこない LoopBodyLocal 変数」を安全に JoinIR→MIR に落とすためのインフラ箱だけを追加したよ。
|
|
|
|
|
|
|
|
|
|
|
|
- **LoopBodyLocalEnv**
|
|
|
|
|
|
- 責務: ループ本体内で `local` 定義された変数の「JoinIR 側 ValueId のみ」を管理する。
|
|
|
|
|
|
- 入力: ループ本体 AST / JoinIR ビルダー。
|
|
|
|
|
|
- 出力: `name -> join_value_id` のマップ。
|
|
|
|
|
|
- 特徴: host 側との対応は持たない。ConditionEnv とは完全に分離された「本体専用ローカル環境」。
|
|
|
|
|
|
|
|
|
|
|
|
- **UpdateEnv**
|
|
|
|
|
|
- 責務: UpdateExpr lowering 時の変数解決順序をカプセル化する。
|
|
|
|
|
|
- 仕様: `ConditionEnv`(条件・キャリア)と `LoopBodyLocalEnv`(本体ローカル)を中で束ねて、
|
|
|
|
|
|
`resolve(name)` で「条件→ローカル」の順に ValueId を返す。
|
|
|
|
|
|
- 利用箇所: CarrierUpdateEmitter / CarrierUpdateLowerer が、変数名ベースで UpdateExpr を JoinIR に落とす時に利用。
|
|
|
|
|
|
|
|
|
|
|
|
- **CarrierUpdateEmitter 拡張**
|
|
|
|
|
|
- 責務: `LoopUpdateSummary`(UpdateKind)に応じて、int 系キャリア更新を JoinIR 命令に変換する。
|
|
|
|
|
|
- 変更点: 直接 `variable_map` を読むのではなく、`UpdateEnv` 経由で名前解決するように変更。
|
|
|
|
|
|
- 効果: 本体専用の LoopBodyLocal 変数(`temp` 等)を、Pattern2/4 から安全に扱える土台が整った。
|
|
|
|
|
|
|
|
|
|
|
|
このフェーズではあくまで「ストレージ・名前解決・emit の箱」までで止めてあり、
|
|
|
|
|
|
Pattern2/4 への統合(実際に Body-local 更新を使うループを JoinIR 経路に載せる)は次フェーズ(Phase 185 以降)の仕事として分離している。
|
2025-12-08 21:41:19 +09:00
|
|
|
|
- 構造的に P1–P4 で対応可能(代表例):
|
|
|
|
|
|
- `_parse_number` / `_atoi`(P2 Break)- Phase 182 でブロッカー特定済み
|
|
|
|
|
|
- `_match_literal`(P1 Simple while)- Phase 182 で動作確認済み ✅
|
|
|
|
|
|
- `_parse_string` / `_parse_array` / `_parse_object`
|
|
|
|
|
|
(P2 + P4 + P5 の組み合わせで表現可能なことを設計上確認済み)
|
|
|
|
|
|
- 低優先度だが理論上は P1–P4 からの拡張で吸収可能:
|
|
|
|
|
|
- `_unescape_string` など、複雑な continue / 条件付き更新を含むループ
|
|
|
|
|
|
|
|
|
|
|
|
方針:
|
|
|
|
|
|
|
2025-12-10 00:01:53 +09:00
|
|
|
|
- **ループの「形」は P1–P4 から増やさない**。
|
2025-12-08 21:41:19 +09:00
|
|
|
|
複雑さ(LoopBodyLocal 条件、OR chain、continue 多用など)は BoolExprLowerer /
|
|
|
|
|
|
ContinueBranchNormalizer / TrimLoopLowerer (P5) といった補助箱側で吸収する。
|
2025-12-10 00:01:53 +09:00
|
|
|
|
- JsonParser 側の P5 適用(Trim / `_skip_whitespace` / `_parse_string` 最小版)は実証済み。
|
2025-12-08 21:41:19 +09:00
|
|
|
|
残りのループは Phase 17x–18x で、P1–P4+P5 の組み合わせとして段階的に実装していく。
|
|
|
|
|
|
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
### 4.3 JsonParser 実戦カバレッジ(Phase 221 時点)
|
2025-12-10 00:01:53 +09:00
|
|
|
|
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
Phase 210–221 で「数値ループ+if-sum」を実戦投入し、JoinIR インフラが **本番級に動作する** ことを確認したよ:
|
2025-12-10 00:01:53 +09:00
|
|
|
|
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
- **実戦確認済みループ**(9/13 loops ≒ 69%):
|
2025-12-10 00:01:53 +09:00
|
|
|
|
- ✅ `_skip_whitespace` (P2 + P5 Trim, Phase 173)
|
|
|
|
|
|
- ✅ `_trim` leading/trailing (P2 + P5 Trim, Phase 171/172)
|
|
|
|
|
|
- ✅ `_match_literal` 最小版 (P1 Simple, Phase 210)
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
- ✅ `_atoi` 最小版 (P2 Break, NumberAccumulation, Phase 190)
|
|
|
|
|
|
- ✅ `_parse_number` 最小版 (P2 Break, NumberAccumulation, Phase 190)
|
|
|
|
|
|
- ✅ if-sum 最小版 (P3 IfPHI, variable condition, Phase 212/220)
|
|
|
|
|
|
- ✅ captured vars 最小版 (P2 Break, function-local const, Phase 200-D)
|
|
|
|
|
|
- ✅ digits accumulate 最小版 (P2 Simple accumulation, Phase 200-D)
|
|
|
|
|
|
|
|
|
|
|
|
- **Phase 210–221 の成果**:
|
|
|
|
|
|
- 8 本すべて JoinIR → MIR → Runtime 完全成功(RC 正常)
|
|
|
|
|
|
- Pattern1/2/3 自動ルーティング正常動作
|
|
|
|
|
|
- NumberAccumulation (Mul+Add), if-sum (if条件付き更新), captured vars すべて正常
|
|
|
|
|
|
- ConditionEnv/ConditionPatternBox/ExprResultResolver 統合完了
|
|
|
|
|
|
- **制約発見ゼロ(基本パス)** - Phase 190/200/220 の統合が完璧に機能
|
|
|
|
|
|
|
|
|
|
|
|
- **Phase 221 制約発見** (2025-12-09):
|
|
|
|
|
|
- ⚠️ **LoopBodyLocal in condition**: break/continue 条件で loop-body-local 変数を使用(Pattern 5+ 必要)
|
|
|
|
|
|
- ⚠️ **MethodCall whitelist**: body-local init で `substring` 未対応(Phase 193: indexOf/get/toString のみ)
|
2025-12-10 09:29:32 +09:00
|
|
|
|
- ~~⚠️ **if condition pattern**: if-sum mode は `var CmpOp literal` のみ(`i > 0` は OK、`0 < i` や `i > j` は NG)~~ → **Phase 222 で解決済み✅**
|
|
|
|
|
|
|
|
|
|
|
|
- **Phase 222 解決済み制約** (2025-12-10):
|
|
|
|
|
|
- ✅ **if condition pattern**: ConditionPatternBox 正規化で左リテラル・変数同士の比較をサポート
|
|
|
|
|
|
- `0 < i`, `len > i` → `i > 0`, `i < len` に正規化
|
|
|
|
|
|
- `i > j` (var CmpOp var) - 直接サポート
|
|
|
|
|
|
- テスト: phase222_if_cond_left_literal_min.hako → RC=2 達成
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
|
|
|
|
|
|
- **残りループ** (Phase 222+ で段階的対応予定):
|
2025-12-10 00:01:53 +09:00
|
|
|
|
- `_parse_array`, `_parse_object` (MethodCall 複数)
|
|
|
|
|
|
- `_unescape_string` (複雑なキャリア処理)
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
- `_atoi`/`_parse_number` 本体(LoopBodyLocal in condition 対応後)
|
2025-12-10 00:01:53 +09:00
|
|
|
|
|
docs: Phase 221 JsonParser numerical loops deployment
Phase 221: JsonParser 数値ループの実戦投入と制約整理完了
## Task 1: 代表テスト再確認 (E2E)
✅ 3/3 tests PASS:
- phase190_atoi_impl.hako: 12 (P2 NumberAccumulation)
- phase190_parse_number_impl.hako: 123 (P2 NumberAccumulation)
- phase212_if_sum_min.hako: RC=2 (P3 if-sum with variable condition)
## Task 2: JsonParser ミニケース追加
✅ 2/2 additional tests PASS:
- phase200d_capture_minimal.hako: 30 (P2 with captured vars)
- phase200d_digits_accumulate.hako: 0,1,2 (P2 simple accumulation)
## Task 3: 制約の洗い出し記録
### ✅ 実戦 OK (5/9 tests):
- NumberAccumulation (P2) ✅
- if-sum pattern (P3) ✅
- Captured variables (P2) ✅
- Simple accumulation (P2) ✅
### ⚠️ 制約でブロック (4/9 tests):
1. **LoopBodyLocal in condition** (Pattern 5+ required):
- phase200_digits_atoi_min.hako: `pos` in break condition
- phase200_digits_parse_number_min.hako: `digit_pos` in break condition
2. **MethodCall whitelist** (Phase 193 constraint):
- phase200d_digits_simple.hako: `substring` not whitelisted
- Supported: indexOf, get, toString only
3. **if condition pattern** (Phase 219-fix constraint):
- phase218_json_if_sum_min.hako: Variable in if LHS (`i > 0`)
- if-sum mode accepts only `var CmpOp literal`
## Task 4: 設計ドキュメント固定
Updated docs/development/current/main/joinir-architecture-overview.md:
- Section 4.3: JsonParser 実戦カバレッジ (Phase 210 → Phase 221)
- Coverage: 7/13 (54%) → 9/13 (69%)
- Added: 3 constraint categories with concrete examples
- Conclusion: NumberAccumulation + captured const + if-sum 基盤完成 ✨
Updated CURRENT_TASK.md:
- Added Phase 221 summary (実戦 OK, 制約発見, 次の候補)
## 成果サマリー
- **JoinIR 数値ループ基盤**: 実戦投入可能な成熟度に到達
- **5/9 テスト PASS**: NumberAccumulation, if-sum, captured vars 全て動作
- **3 種の既知制約**: LoopBodyLocal in condition, MethodCall whitelist, if condition pattern
- **次の候補**: Pattern 5+ 拡張, if condition 左辺変数対応
2025-12-10 09:03:46 +09:00
|
|
|
|
**結論**:
|
|
|
|
|
|
- JoinIR 数値ループ基盤(NumberAccumulation + captured const + if-sum)は **実戦投入可能な成熟度** に到達 ✨
|
|
|
|
|
|
- **Phase 221 で 3 種の既知制約を整理** - 次フェーズで Pattern 5+ 拡張 / MethodCall whitelist 拡張が候補
|
2025-12-10 00:01:53 +09:00
|
|
|
|
|
2025-12-08 21:41:19 +09:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. selfhost / .hako JoinIR Frontend との関係
|
2025-12-07 21:02:20 +09:00
|
|
|
|
|
|
|
|
|
|
JoinIR は Rust 側だけでなく、将来的に .hako selfhost コンパイラ側でも生成・解析される予定だよ:
|
|
|
|
|
|
|
|
|
|
|
|
- .hako 側の JsonParser/分析箱は、Program JSON / MIR JSON v1 を読んで JoinIR/MIR を解析する。
|
|
|
|
|
|
- Rust 側 JoinIR ラインの設計変更(特に ValueId/ExitLine/Boundary 周り)は、
|
|
|
|
|
|
**必ずこのファイルを更新してから** .hako 側にも段階的に反映する方針。
|
|
|
|
|
|
|
|
|
|
|
|
「JoinIR の仕様」「箱の責務」「境界の契約」は、このファイルを SSOT として運用していく。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 関連ドキュメント
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/development/current/main/10-Now.md`
|
|
|
|
|
|
- 全体の「いまどこ」を短くまとめたダッシュボード。
|
|
|
|
|
|
- `docs/private/roadmap2/phases/phase-180-joinir-unification-before-selfhost/README.md`
|
|
|
|
|
|
- JoinIR 統一フェーズ全体のロードマップと進捗。
|
|
|
|
|
|
- 各 Phase 詳細:
|
|
|
|
|
|
- 185–188: Strict mode / LoopBuilder 削除 / Pattern1–4 基盤
|
|
|
|
|
|
- 189–193: Multi-function merge / Select bridge / ExitLine 箱化
|
|
|
|
|
|
- 171–172 / 33‑10/13: ConditionEnv, ConditionBinding, JoinFragmentMeta, ExitLineRefactor 等
|
2025-12-08 03:06:20 +09:00
|
|
|
|
- `docs/development/current/main/loop_pattern_space.md`
|
|
|
|
|
|
- JoinIR ループパターン空間の整理メモ。
|
|
|
|
|
|
どの軸(継続条件 / break / continue / PHI / 条件変数スコープ / 更新パターン)でパターンを分けるか、
|
|
|
|
|
|
そして P1–P4 / Trim(P5) の位置づけと、今後追加候補のパターン一覧がまとまっている。
|
2025-12-08 15:17:53 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Roadmap(JoinIR の今後のゴール)
|
|
|
|
|
|
|
|
|
|
|
|
ここから先の JoinIR の「目指す形」を、箱レベルでざっくり書いておくよ。フェーズ詳細は各 phase ドキュメントに分散させて、このセクションは常に最新の方向性だけを保つ。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 直近(Phase 176-177 まわり)
|
|
|
|
|
|
|
|
|
|
|
|
- **P5(Trim/JsonParser 系)ループの複数キャリア対応** ✅ Phase 176 完了 (2025-12-08)
|
|
|
|
|
|
- 完了内容:
|
|
|
|
|
|
- Pattern2 lowerer を全キャリア対応に拡張(ヘッダ PHI / ループ更新 / ExitLine)。
|
|
|
|
|
|
- CarrierUpdateLowerer ヘルパで UpdateExpr → JoinIR 変換を統一。
|
|
|
|
|
|
- 2キャリア(pos + result)E2E テスト完全成功。
|
|
|
|
|
|
- 技術的成果:
|
|
|
|
|
|
- CarrierInfo / ExitMeta / ExitLine / LoopHeaderPhiBuilder の multi-carrier 対応を Pattern2 lowerer で完全活用。
|
|
|
|
|
|
- Trim pattern の「キャリア = ループ変数」という誤解を解消(loop_var は特殊キャリア)。
|
|
|
|
|
|
- 次のステップ (Phase 177):
|
|
|
|
|
|
- JsonParser `_parse_string` 本体を P2+P5 で通す(pos + result の 2 キャリアで実ループ動作確認)。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 中期(selfhost depth‑2 / JsonParser 本体)
|
|
|
|
|
|
|
|
|
|
|
|
- **JsonParserBox / Trim 系ループの本線化**
|
|
|
|
|
|
- 目標:
|
|
|
|
|
|
- `_trim` / `_skip_whitespace` / `_parse_string` / `_parse_array` などの主要ループが、すべて JoinIR Pattern1–4 + P5 で通ること。
|
|
|
|
|
|
- LoopConditionScopeBox + LoopBodyCarrierPromoter + TrimLoopHelper の上で安全に正規化できるループを広げていく。
|
|
|
|
|
|
- 方針:
|
|
|
|
|
|
- 「ループの形」は P1–P4 から増やさず、複雑さは BoolExprLowerer / ContinueBranchNormalizer / P5 系の補助箱で吸収する。
|
|
|
|
|
|
- LoopPatternSpace の P6/P7/P12 候補(break+continue 同時 / 複数キャリア条件更新 / early return)は、実アプリで必要になった順に小さく足す。
|
|
|
|
|
|
|
|
|
|
|
|
- **selfhost depth‑2(.hako JoinIR/MIR Frontend)**
|
|
|
|
|
|
- 目標:
|
|
|
|
|
|
- `.hako → JsonParserBox → Program/MIR JSON → MirAnalyzerBox/JoinIrAnalyzerBox → VM/LLVM` の深度 2 ループを、日常的に回せるようにする。
|
|
|
|
|
|
- Rust 側の JoinIR は「JSON を受け取って実行・検証するランナー層」、.hako 側が「JoinIR/MIR を構築・解析する言語側 SSOT」という役割分担に近づける。
|
|
|
|
|
|
- 前提:
|
|
|
|
|
|
- 本ドキュメント(joinir-architecture-overview.md)を .hako 側の JoinIR 実装の参照設計として維持し、仕様変更は必ずここを更新してから .hako にも反映する。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 当面やらないこと(Non‑Goals)
|
|
|
|
|
|
|
|
|
|
|
|
- ループパターンを闇雲に増やすこと
|
|
|
|
|
|
- P1–P4(構造)+ P5(body‑local 条件を昇格する補助パス)を「骨格」とみなし、
|
|
|
|
|
|
新しいパターンが必要になったときは LoopPatternSpace に追記してから、小さな箱で補う方針。
|
|
|
|
|
|
- LoopBuilder の復活や、JoinIR 以外の別ラインによるループ lowering
|
|
|
|
|
|
- LoopBuilder 系は Phase 186–187 で完全に削除済み。
|
|
|
|
|
|
ループに関する新しい要件はすべて JoinIR 側のパターン/箱の拡張で扱う。
|
|
|
|
|
|
- JoinIR の中に言語固有のハードコード(特定 Box 名や変数名)を戻すこと
|
|
|
|
|
|
- Trim/JsonParser 系は、構造(パターン)と補助箱(Promoter/Helper)で扱い、
|
|
|
|
|
|
「sum」「ch」など名前ベースの判定は LoopUpdateSummary / TrimLoopHelper の内部に閉じ込める。
|
|
|
|
|
|
|
|
|
|
|
|
この Roadmap は、JoinIR 層の変更や selfhost 深度を進めるたびに更新していくよ。
|
2025-12-09 03:18:05 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. JoinIR 第1章:基盤完成サマリ(2025-12-09 時点)
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 現在の対応状況
|
|
|
|
|
|
|
|
|
|
|
|
**Pattern サポート**:
|
|
|
|
|
|
| Pattern | 説明 | 状態 |
|
|
|
|
|
|
|---------|------|------|
|
|
|
|
|
|
| P1 Simple | `loop(cond) { body }` | ✅ 完成 |
|
|
|
|
|
|
| P2 Break | `loop(cond) { if(...) break }` | ✅ 完成 |
|
|
|
|
|
|
| P3 If-PHI | `loop { if(...) a else b; use(φ) }` | ✅ 完成 |
|
|
|
|
|
|
| P4 Continue | `loop { if(...) continue }` | ✅ 完成 |
|
|
|
|
|
|
| P5 Trim | LoopBodyLocal → bool carrier 昇格 | ✅ 基本完成 |
|
|
|
|
|
|
|
|
|
|
|
|
**UpdateKind サポート**:
|
|
|
|
|
|
| UpdateKind | 例 | 状態 |
|
|
|
|
|
|
|------------|-----|------|
|
|
|
|
|
|
| CounterLike | `i = i + 1` | ✅ |
|
|
|
|
|
|
| AccumulationLike | `sum = sum + x` | ✅ |
|
|
|
|
|
|
| StringAppendChar | `s = s + ch` | ✅ |
|
|
|
|
|
|
| StringAppendLiteral | `s = s + "lit"` | ✅ |
|
|
|
|
|
|
| NumberAccumulation | `v = v * 10 + digit` | ✅ (Phase 190) |
|
|
|
|
|
|
| Complex | method call 含む | ❌ Fail-Fast |
|
|
|
|
|
|
|
|
|
|
|
|
**アーキテクチャ SSOT ライン**:
|
|
|
|
|
|
- ✅ LoopHeaderPhiBuilder: ループ変数・キャリアの PHI を SSOT で生成
|
|
|
|
|
|
- ✅ ExitLineReconnector: PHI dst → variable_map 接続
|
|
|
|
|
|
- ✅ JoinInlineBoundaryBuilder: 全パターンで Builder パターン統一
|
|
|
|
|
|
- ✅ JoinIRVerifier: デバッグビルドで契約検証
|
|
|
|
|
|
- ✅ ExitLine Contract Verifier: PHI 配線検証(Phase 190-impl-D)
|
|
|
|
|
|
|
2025-12-09 03:59:53 +09:00
|
|
|
|
### 7.2 残タスク(Phase 192+ で対応予定)
|
2025-12-09 03:18:05 +09:00
|
|
|
|
|
2025-12-09 03:59:53 +09:00
|
|
|
|
1. **✅ body-local 変数の init + update lowering** → Phase 191 完了
|
|
|
|
|
|
- `local digit = i + 1` のような body-local 変数の JoinIR/MIR 生成完了
|
|
|
|
|
|
- 対応済み: 整数リテラル、変数参照、二項演算
|
|
|
|
|
|
- テスト: `phase191_body_local_atoi.hako` → 期待値 123 ✅
|
2025-12-09 03:18:05 +09:00
|
|
|
|
|
2025-12-09 04:28:10 +09:00
|
|
|
|
2. **✅ Complex addend 対応** → Phase 192 完了
|
|
|
|
|
|
- `v = v * 10 + digits.indexOf(ch)` のような method call を含む NumberAccumulation対応
|
|
|
|
|
|
- ComplexAddendNormalizer で `temp = f(x)` に分解してから NumberAccumulation に載せる実装完了
|
|
|
|
|
|
- テスト: phase192_normalization_demo.hako → 123 ✅
|
|
|
|
|
|
- 制約: MethodCall を含む init 式は Phase 193 で対応予定
|
2025-12-09 03:18:05 +09:00
|
|
|
|
|
2025-12-09 13:22:14 +09:00
|
|
|
|
3. **✅ MethodCall を含む init 式の対応** → Phase 193 完了
|
|
|
|
|
|
- `local digit = digits.indexOf(ch)` のような MethodCall init の lowering 完了
|
2025-12-09 04:28:10 +09:00
|
|
|
|
- LoopBodyLocalInitLowerer 拡張(BoxCall emission)
|
2025-12-09 13:22:14 +09:00
|
|
|
|
- メソッド whitelist: indexOf, get, toString 対応
|
|
|
|
|
|
- 制約: body-local init のみ対応、condition 内の MethodCall は Phase 200+
|
|
|
|
|
|
|
|
|
|
|
|
4. **✅ JsonParser 実戦投入(P1/P2/P5 検証)** → Phase 194 完了
|
|
|
|
|
|
- 4/10 ループが JoinIR 経路で動作確認 (40% coverage)
|
|
|
|
|
|
- Target loops: _skip_whitespace, _trim (x2), _match_literal
|
|
|
|
|
|
- Deferred loops: _parse_number, _atoi (ConditionEnv constraint)
|
|
|
|
|
|
- Deferred loops: _parse_string, _unescape_string (complex carriers)
|
|
|
|
|
|
- Deferred loops: _parse_array, _parse_object (multiple MethodCalls)
|
|
|
|
|
|
- 詳細: phase194-loop-inventory.md, phase194-jsonparser-deployment.md
|
|
|
|
|
|
|
2025-12-09 14:45:04 +09:00
|
|
|
|
5. **Pattern 3 拡張(複数キャリア対応)** → Phase 195 + 196 完了 ✅
|
2025-12-09 13:22:14 +09:00
|
|
|
|
- 目的: P3(If-Else PHI)で 2-3 個の Carrier を同時処理
|
2025-12-09 14:45:04 +09:00
|
|
|
|
- **Phase 195**: Lowerer 側完了(multi-carrier PHI 生成: sum + count)✅
|
|
|
|
|
|
- **Phase 196**: Select 二重 remap バグ修正 ✅
|
|
|
|
|
|
- 根本原因: `instruction_rewriter.rs` で PHI inputs を二重 remap
|
|
|
|
|
|
- 修正: block ID のみ remap、ValueId は既に remap 済み
|
|
|
|
|
|
- **E2E 結果**: phase195_sum_count.hako → 93 ✅
|
|
|
|
|
|
- 詳細: phase196-select-bug-analysis.md
|
|
|
|
|
|
|
2025-12-09 15:28:49 +09:00
|
|
|
|
6. **✅ JoinIR 実戦適用(軽量ループ検証)** → Phase 197 完了 ✅
|
|
|
|
|
|
- 目的: Phase 196 までの安定基盤を実戦の小さいループで検証
|
|
|
|
|
|
- 対象ループ(5本):
|
|
|
|
|
|
1. `_match_literal` (P1) - JsonParser 単純 while ✅
|
|
|
|
|
|
2. `_skip_whitespace` (P2) - JsonParser break パターン ✅
|
|
|
|
|
|
3. `phase195_sum_count.hako` (P3 multi-carrier) ✅
|
|
|
|
|
|
4. `loop_if_phi.hako` (P3 single-carrier) ✅
|
|
|
|
|
|
5. `loop_min_while.hako` (P1 minimal) ✅
|
|
|
|
|
|
- 結果:
|
|
|
|
|
|
- [x] routing 確認: 全ループ whitelisted ✅
|
|
|
|
|
|
- [x] E2E 実行: 4/5 ループで期待値出力、1/5 routing 確認 ✅
|
|
|
|
|
|
- [x] 退行なし: Phase 190-196 テスト全 PASS ✅
|
|
|
|
|
|
- 詳細: phase197-lightweight-loops-deployment.md
|
|
|
|
|
|
|
|
|
|
|
|
7. **JsonParser/selfhost 実戦 JoinIR 適用状況** (2025-12-09 更新)
|
|
|
|
|
|
|
|
|
|
|
|
| Function | Pattern | Status | Note |
|
|
|
|
|
|
|----------|---------|--------|------|
|
|
|
|
|
|
| `_match_literal` | P1 | ✅ JoinIR OK | Phase 197 検証済み(E2E PASS)|
|
|
|
|
|
|
| `_skip_whitespace` | P2 | ✅ JoinIR OK | Phase 197 routing 確認(whitelisted)|
|
|
|
|
|
|
| `_trim` (leading) | P5 | ✅ JoinIR OK | Phase 173 実証済み |
|
|
|
|
|
|
| `_trim` (trailing) | P5 | ✅ JoinIR OK | Phase 173 実証済み |
|
|
|
|
|
|
| `phase195_sum_count` | P3 | ✅ JoinIR OK | Phase 196 検証済み(multi-carrier)|
|
|
|
|
|
|
| `loop_if_phi` | P3 | ✅ JoinIR OK | Phase 196 検証済み(single-carrier)|
|
|
|
|
|
|
| `loop_min_while` | P1 | ✅ JoinIR OK | Phase 165 基本検証済み |
|
|
|
|
|
|
| `_parse_number` | P2 | ⚠️ Deferred | ConditionEnv 制約(Phase 200+)|
|
|
|
|
|
|
| `_atoi` | P2 | ⚠️ Deferred | ConditionEnv 制約(Phase 200+)|
|
|
|
|
|
|
| `_parse_string` | P3 | ⚠️ Deferred | 複雑キャリア(Phase 195+ 拡張後)|
|
|
|
|
|
|
| `_unescape_string` | P3 | ⚠️ Deferred | 複雑キャリア(Phase 195+ 拡張後)|
|
|
|
|
|
|
| `_parse_array` | - | ⚠️ Deferred | 複数 MethodCall(Phase 195+)|
|
|
|
|
|
|
| `_parse_object` | - | ⚠️ Deferred | 複数 MethodCall(Phase 195+)|
|
|
|
|
|
|
|
|
|
|
|
|
**Coverage**: 7/13 ループ JoinIR 対応済み(54%)
|
|
|
|
|
|
**Verification**: 4/7 ループ E2E PASS、3/7 structural/routing 確認済み
|
|
|
|
|
|
|
|
|
|
|
|
8. **JsonParser 残り複雑ループへの適用(Phase 198+, 200+)**
|
2025-12-09 13:22:14 +09:00
|
|
|
|
- Phase 200+: ConditionEnv 拡張 (function-scoped variables) → _parse_number, _atoi
|
2025-12-09 15:28:49 +09:00
|
|
|
|
- Phase 198+: Pattern 3 拡張 (multi-flag carriers) → _parse_string, _unescape_string
|
|
|
|
|
|
- Phase 198+: MethodCall 拡張 (multiple calls in body) → _parse_array, _parse_object
|
2025-12-09 13:22:14 +09:00
|
|
|
|
- selfhost `.hako` コンパイラの全ループを JoinIR で処理 (Phase 210+)
|
2025-12-10 02:07:28 +09:00
|
|
|
|
|
|
|
|
|
|
9. **Pattern 3 If-Sum AST ベース実装** → Phase 213-217 完了 ✅
|
|
|
|
|
|
- **Phase 213**: If-sum パターン AST ベース lowerer 実装
|
|
|
|
|
|
- `loop_with_if_phi_if_sum.rs`: AST 抽出 + JoinIR 生成
|
|
|
|
|
|
- Dual-mode 構成: if-sum mode / legacy mode
|
|
|
|
|
|
- **Phase 214**: Dynamic join inputs 対応(hardcoded 3-input 除去)
|
|
|
|
|
|
- **Phase 215**: ExprResult exit contract 確立
|
|
|
|
|
|
- **Phase 216**: Selfhost if-sum production test 検証
|
|
|
|
|
|
- **Phase 217**: Multi-carrier if-sum 動作確認(追加実装ゼロ行)
|
|
|
|
|
|
- 詳細: phase213-if-sum-implementation.md, phase217-if-sum-multi.md
|
|
|
|
|
|
|
|
|
|
|
|
10. **Phase 218: JsonParser If-Sum 適用調査** → 🔍 調査完了
|
|
|
|
|
|
- **目的**: JsonParser-style if-sum パターン (`sum = sum + digit`) への Pattern 3 適用
|
|
|
|
|
|
- **結果**: パターン認識ギャップを発見
|
|
|
|
|
|
- Phantom `count` carrier が誤検出され、`is_if_sum_pattern()` が false
|
|
|
|
|
|
- AST ベース lowerer は実装済みだが起動されていない
|
|
|
|
|
|
- 根本原因: carrier 検出ロジックの name heuristic が脆弱
|
|
|
|
|
|
- **次フェーズ**: Carrier 検出修正(Phase 219)
|
|
|
|
|
|
- 詳細: phase218-jsonparser-if-sum-min.md
|