docs: Phase 195 Pattern 3 extension design (multi-carrier support)

Phase 195 design document for P3 (If-Else PHI) multi-carrier expansion:
- Goal: Handle 2-3 carriers in if-else branches simultaneously
- Scope: if-complete multi-carrier updates (flag+buffer, sum+count patterns)

Task breakdown:
- 195-1: Loop inventory (_parse_string simple, if-sum patterns)
- 195-2: LoopUpdateSummary/CarrierInfo design (multi-carrier support)
- 195-3: Pattern3 lowerer design (PhiGroup vs ExitLine extension)
- 195-4: Implementation scope (2-3 carriers, existing UpdateKind range)
- 195-5: Documentation updates (CURRENT_TASK.md + overview)

Design decisions:
-  ExitLine extension (no PhiGroupBox - YAGNI principle)
-  Both-branch carrier definition check (unchanged = use previous value)
-  No ConditionEnv expansion (Phase 200+ deferred)
-  LoopBodyLocal + MethodCall mix deferred to Phase 195+

Target loops:
1. JsonParser _parse_string (escaped flag + buffer)
   - Carrier 1: escaped (BoolFlag) - conditional flag
   - Carrier 2: buffer (StringAppend) - else-only update
2. selfhost if-sum (sum + count)
   - Carrier 1: sum (NumberAccumulation) - then-only update
   - Carrier 2: count (CounterLike) - then-only update

Test cases designed:
- phase195_flag_buffer.hako (BoolFlag + StringAppend)
- phase195_sum_count.hako (NumberAccumulation + CounterLike)

Expected outcome:
- phase195-pattern3-extension-design.md (complete design spec)
- Clear implementation scope for Phase 195-impl
- Path to 40% → 60% JsonParser coverage

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-09 13:22:14 +09:00
parent 3ca84e8d59
commit 22f97b67b1
3 changed files with 701 additions and 11 deletions

View File

@ -295,10 +295,61 @@
- ⚠️ 保留: 外部ローカルをレシーバーとする MethodCall (`digits.indexOf(ch)`)
- **理由**: Phase 170-200 の 2-tier 境界設計ConditionEnv/LoopBodyLocalEnvを保持
- **将来**: Phase 200+ で独立した箱として設計、または .hako リライト対応
- [ ] Phase 194: JsonParser 残りループ展開
- _parse_array, _parse_object P4 Continue, MethodCall 複数対応
- _parse_string 完全版 P2/P4, string concat + escape
- _unescape_string P4 Continue, 複雑キャリア + flatten
- [x] **Phase 194: JsonParser P1/P2/P5 実戦投入(検証フェーズ)** ✅ (2025-12-09)
- **目的**: Phase 170-193 インフラの実コード検証Fail-Fast 戦略
- 194-1: Loop inventory 作成 ✅
- 4/10 ループ JoinIR 対応_skip_whitespace, _trim x2, _match_literal
- 6/10 ループ保留(明確な理由付き)
- 詳細: phase194-loop-inventory.md10ループ完全分類
- 194-2: Routing 確認 ✅
- Structure-only mode 動作確認whitelist 不要)
- 既存 whitelist に全4ループ登録済み
- 194-3: E2E 実行 ✅
- 結果: Compilation ErrorExpected - Fail-Fast 戦略成功)
- エラー: `digits.indexOf()` → ConditionEnv constraint
- 分析: function-scoped variables は Phase 193 非対応
- 194-4: Regression tests ✅
- phase190_atoi_impl.hako → 12 ✅
- phase191_body_local_atoi.hako → 123 ✅
- phase193_init_method_call.hako → RC:0 ✅
- 194-5: ドキュメント更新 ✅
- phase194-jsonparser-deployment.mdImplementation Status 完全記録)
- joinir-architecture-overview.mdSection 7.2 Phase 194 完了マーク)
- CURRENT_TASK.md本項目追加
- **成果**: インフラ品質検証完了、次 Phase への明確なロードマップ提示
- ✅ P5 Trim pattern 実戦検証_trim で動作確認)
- ✅ ConditionEnv 制約明確化function-scoped variables 未対応)
- ✅ 退行なしPhase 190-193 全テスト PASS
- **技術的発見**:
1. ConditionEnv constraintfunction-scoped variables 非対応)
- 影響: _parse_number, _atoidigits.indexOf 依存)
- 解決策案: Phase 200+ ConditionEnv 拡張 OR .hako リライト
2. Complex carriers多段フラグ
- 影響: _parse_string, _unescape_string
- 解決策: Phase 195+ Pattern 3 拡張
3. Multiple MethodCallsループ body 内複数呼び出し)
- 影響: _parse_array, _parse_object
- 解決策: Phase 195+ MethodCall 拡張
- **推奨ロードマップ**:
- Phase 195: Pattern 3 extensionif-in-loop + multi-flag carriers
- Phase 200+: ConditionEnv expansionfunction-scoped locals
- Phase 201+: MethodCall extensionmultiple calls in body
- [ ] **Phase 195: Pattern 3 拡張(設計フェーズ)**
- **目的**: P3If-Else PHIを複数キャリア対応に拡張する設計
- 195-1: 対象ループ絞り込み_parse_string 簡易版、if-sum
- 195-2: LoopUpdateSummary/CarrierInfo 設計整理(複数キャリア対応)
- 195-3: Pattern3 lowerer 設計更新PhiGroup vs ExitLine 拡張判断)
- 195-4: 実装スコープ決定2-3キャリア、既存 UpdateKind 範囲内)
- 195-5: ドキュメント更新CURRENT_TASK.md + overview 更新)
- **設計判断**:
- ✅ ExitLine 拡張で対応PhiGroupBox は作らない - YAGNI 原則)
- ✅ 両分岐での Carrier 定義確認(更新なし = 前の値使用)
- ❌ ConditionEnv 拡張なしPhase 200+ 保留)
- ❌ LoopBodyLocal + MethodCall 混在は Phase 195+ 延期
- **期待成果**:
- phase195-pattern3-extension-design.md完全設計書
- Phase 195-impl の実装スコープ明確化
- JsonParser カバレッジ 40% → 60% への道筋
---

View File

@ -509,12 +509,28 @@ JoinIR は Rust 側だけでなく、将来的に .hako selfhost コンパイラ
- テスト: phase192_normalization_demo.hako → 123 ✅
- 制約: MethodCall を含む init 式は Phase 193 で対応予定
3. **MethodCall を含む init 式の対応Phase 193**
- `local digit = digits.indexOf(ch)` のような MethodCall init の lowering
3. **MethodCall を含む init 式の対応** → Phase 193 完了
- `local digit = digits.indexOf(ch)` のような MethodCall init の lowering 完了
- LoopBodyLocalInitLowerer 拡張BoxCall emission
- メソッド whitelist: indexOf, substring
- メソッド whitelist: indexOf, get, toString 対応
- 制約: body-local init のみ対応、condition 内の MethodCall は Phase 200+
4. **JsonParser 残り複雑ループ・selfhost ループへの適用(Phase 194+**
- `_parse_array` / `_parse_object`P4 Continue + 複数 MethodCall
- `_unescape_string`(複雑なキャリア + flatten
- selfhost `.hako` コンパイラの全ループを JoinIR で処理
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
5. **Pattern 3 拡張(複数キャリア対応)** → Phase 195 設計中
- 目的: P3If-Else PHIで 2-3 個の Carrier を同時処理
- 設計判断: ExitLine 拡張で対応PhiGroupBox は作らない - YAGNI 原則)
- 対象: _parse_stringflag+buffer、if-sumsum+count
- Phase 195-impl で実装予定
6. **JsonParser 残り複雑ループへの適用Phase 195+, 200+**
- Phase 200+: ConditionEnv 拡張 (function-scoped variables) → _parse_number, _atoi
- Phase 195+: Pattern 3 拡張 (multi-flag carriers) → _parse_string, _unescape_string
- Phase 195+: MethodCall 拡張 (multiple calls in body) → _parse_array, _parse_object
- selfhost `.hako` コンパイラの全ループを JoinIR で処理 (Phase 210+)

View File

@ -0,0 +1,623 @@
# Phase 195: Pattern 3 拡張if-in-loop + マルチキャリア)
**Status**: Design Phase
**Date**: 2025-12-09
**Prerequisite**: Phase 194 complete (JsonParser deployment & validation)
---
## 目的
**Pattern 3If-Else PHIの対応範囲を拡張**し、複数キャリアの条件付き更新を JoinIR で扱えるようにする。
**スコープ**:
- ✅ if 内で完結する複数キャリア更新2-3個程度
- ❌ ConditionEnv 拡張は行わない外部ローカル・digits 系は Phase 200+ 保留)
- ❌ LoopBodyLocal + MethodCall 混在は Phase 195+ に延期
---
## Task 195-1: 対象ループの絞り込みdoc-only
### 目標
JsonParser / selfhost から「P3 で攻めたいループ」を **1-2 本だけ**選定し、AST 構造を詳細に分析する。
### 候補ループ
#### 候補 1: JsonParser `_parse_string` の簡易版(優先度: 高)
**ループ構造**:
```nyash
// _parse_string (escape 処理の簡略版)
static box JsonParser {
_parse_string(s, start) {
local buffer = ""
local escaped = false
local i = start
loop(i < s.length() and s[i] != '"') {
local ch = s[i]
if(ch == '\\') {
escaped = true // ← Carrier 1 update
} else {
buffer = buffer + ch // ← Carrier 2 update
escaped = false // ← Carrier 1 update
}
i = i + 1
}
return buffer
}
}
```
**AST 構造**:
```
Loop {
condition: BinOp(i < len AND s[i] != '"')
body: [
LocalVar { name: "ch", init: ArrayAccess(s, i) }, // body-local
If {
condition: Compare(ch == '\\'),
then: [
Assign { lhs: "escaped", rhs: BoolLiteral(true) }
],
else: [
Assign { lhs: "buffer", rhs: BinOp(buffer + ch) },
Assign { lhs: "escaped", rhs: BoolLiteral(false) }
]
},
Assign { lhs: "i", rhs: BinOp(i + 1) }
]
}
```
**キャリア分析**:
| Carrier | Type | Update Pattern | Then Branch | Else Branch |
|---------|------|----------------|-------------|-------------|
| `escaped` | BoolBox | Conditional flag | `true` | `false` |
| `buffer` | StringBox | StringAppend | (unchanged) | `buffer + ch` |
| `i` | IntegerBox | CounterLike | `i + 1` | `i + 1` |
**P3 で扱う範囲**:
-`escaped`: 条件フラグ(両分岐で定義)
-`buffer`: StringAppendelse のみ更新、then は不変)
-`i`: ループ外で統一更新P3 の外で処理)
**制約**:
- `ch` は body-local 変数Phase 191 で対応済み)
- `s[i]` の配列アクセスは ConditionEnv で解決(`s` は outer local → Phase 200+
- **この Phase では `ch = "x"` のような定数で代替してテスト**
#### 候補 2: selfhost の if-sum パターン(優先度: 中)
**ループ構造**:
```nyash
// selfhost: 条件付き集計
static box Aggregator {
sum_positive(array) {
local sum = 0
local count = 0
local i = 0
loop(i < array.length()) {
if(array[i] > 0) {
sum = sum + array[i] // ← Carrier 1 update
count = count + 1 // ← Carrier 2 update
}
i = i + 1
}
return sum
}
}
```
**AST 構造**:
```
Loop {
condition: Compare(i < array.length())
body: [
If {
condition: Compare(array[i] > 0),
then: [
Assign { lhs: "sum", rhs: BinOp(sum + array[i]) },
Assign { lhs: "count", rhs: BinOp(count + 1) }
],
else: [] // 空(更新なし)
},
Assign { lhs: "i", rhs: BinOp(i + 1) }
]
}
```
**キャリア分析**:
| Carrier | Type | Update Pattern | Then Branch | Else Branch |
|---------|------|----------------|-------------|-------------|
| `sum` | IntegerBox | NumberAccumulation | `sum + array[i]` | (unchanged) |
| `count` | IntegerBox | CounterLike | `count + 1` | (unchanged) |
| `i` | IntegerBox | CounterLike | `i + 1` | `i + 1` |
**P3 で扱う範囲**:
-`sum`: NumberAccumulationthen のみ更新)
-`count`: CounterLikethen のみ更新)
-`i`: ループ外で統一更新
**制約**:
- `array[i]` の配列アクセスは ConditionEnv で解決(`array` は outer local → Phase 200+
- **この Phase では `i` のような既存パラメータで代替してテスト**
### Phase 195 での選定
**優先順位 1**: 候補 1_parse_string 簡易版)
- 理由: JsonParser の実戦コード、flag + buffer の2キャリア
- 簡略化: `ch = "x"` 定数で配列アクセス回避
**優先順位 2**: 候補 2if-sum
- 理由: selfhost の典型パターン、sum + count の2キャリア
- 簡略化: `i` のみで配列アクセス回避
**成果物**:
- 選定したループの詳細 AST 構造記録(本セクション)
- キャリア分析表UpdateKind 分類済み)
---
## Task 195-2: LoopUpdateSummary / CarrierInfo の設計整理
### 現状の P3 サポートPhase 170-189
**既存の P3 は単一キャリアのみ対応**:
```rust
// 既存の P3 ケース
if(cond) {
sum = sum + i // ← 単一キャリア "sum"
} else {
sum = sum - i
}
```
**LoopUpdateSummary / CarrierInfo の構造**:
```rust
pub struct CarrierInfo {
pub carriers: Vec<String>, // キャリア名リスト
pub updates: HashMap<String, ASTNode>, // name → update式
}
pub struct LoopUpdateSummary {
pub kind: UpdateKind, // CounterLike | NumberAccumulation | ...
// ...
}
```
### Phase 195 で扱う「複数キャリア + 条件付き更新」
**拡張要件**:
```rust
// Phase 195 の P3 ケース
if(cond) {
escaped = true // ← Carrier 1
// buffer は更新なし(不変)
} else {
buffer = buffer + ch // ← Carrier 2
escaped = false // ← Carrier 1
}
```
**設計原則**:
1. **両分岐で同じ Carrier が必ず定義**されることPHI 生成の前提)
- 片方の分岐で更新なし(不変)の場合、明示的に `carrier = carrier` を挿入
- OR: PHI 生成時に「更新なし = 前の値を使う」として扱う
2. **各 Carrier の update 式は既存 UpdateKind 範囲内**:
- CounterLike: `count + 1`, `count - 1`
- NumberAccumulation: `sum + i`, `sum * base + addend`
- StringAppend: `buffer + ch`
- BoolFlag: `true`, `false`(新規 UpdateKind 候補)
3. **CarrierInfo は複数 Carrier を同時に保持**:
```rust
CarrierInfo {
carriers: vec!["escaped", "buffer"],
updates: {
"escaped": ..., // then/else で異なる式
"buffer": ...,
}
}
```
### 制約の明確化
**P3 で扱う Carrier の制約** (Phase 195):
- ✅ if-else の**両分岐で同じ Carrier が定義**される(明示的 or 不変)
- ✅ 各 update 式は**既存 UpdateKind に対応**する
- ❌ MethodCall を含む update は Phase 193 の制約に従う(ループパラメータのみ)
- ❌ 外部ローカル変数(`digits` 等)は Phase 200+ に保留
**例OK**:
```nyash
if(ch == '\\') {
escaped = true // ✅ BoolFlag
} else {
buffer = buffer + ch // ✅ StringAppend
escaped = false // ✅ BoolFlag
}
```
**例NG - Phase 195 範囲外)**:
```nyash
if(cond) {
digit = digits.indexOf(ch) // ❌ 外部ローカル (Phase 200+)
sum = sum + digit
}
```
### 成果物
- 複数キャリア対応の設計原則(本セクション)
- UpdateKind 拡張候補BoolFlagの検討
- CarrierInfo 構造の拡張仕様(擬似コード)
---
## Task 195-3: Pattern3 lowerer の設計更新
### 現状の P3 lowererPhase 170-189
**単一キャリアの処理フロー**:
```
1. If-Else AST を検出
2. Then/Else 各分岐で carrier 更新式を抽出
3. JoinIR で Then/Else ブロック生成
4. Merge 点で PHI 命令生成1つの carrier のみ)
5. ExitLine で PHI 結果を variable_map に接続
```
### Phase 195 での拡張設計
#### 1. 複数 Carrier の同時処理
**設計案**: 複数 PHI を同じ Merge 点で生成
```rust
// 擬似コード: Pattern3 lowerer 拡張
// Step 1: If-Else で更新される全 Carrier を収集
let carriers_in_then = extract_carriers(&if_node.then_branch);
let carriers_in_else = extract_carriers(&if_node.else_branch);
let all_carriers = carriers_in_then.union(&carriers_in_else);
// Step 2: 各 Carrier について Then/Else の update 式を取得
let mut carrier_updates = HashMap::new();
for carrier in all_carriers {
let then_update = get_update_or_unchanged(&if_node.then_branch, carrier);
let else_update = get_update_or_unchanged(&if_node.else_branch, carrier);
carrier_updates.insert(carrier, (then_update, else_update));
}
// Step 3: JoinIR で Then/Else ブロック生成(複数 update を emit
let then_block = emit_then_branch(&carrier_updates);
let else_block = emit_else_branch(&carrier_updates);
// Step 4: Merge 点で複数 PHI 生成
let merge_block = create_merge_block();
for (carrier, (then_val, else_val)) in carrier_updates {
let phi_result = emit_phi(merge_block, then_val, else_val);
// ExitLine で variable_map に接続
exit_line.connect(carrier, phi_result);
}
```
#### 2. PhiGroupBox vs ExitLine/CarrierInfo 拡張
**Option A: PhiGroupBox新規箱**
```rust
pub struct PhiGroupBox {
pub phis: Vec<PhiInfo>, // 複数 PHI の束
}
pub struct PhiInfo {
pub carrier_name: String,
pub then_value: ValueId,
pub else_value: ValueId,
pub result: ValueId,
}
```
**メリット**:
- 複数 PHI の関係性を明示的に管理
- 単一責任の原則PHI グループ専用)
**デメリット**:
- 新規箱の追加(複雑度増加)
- 既存の ExitLine との統合が必要
**Option B: ExitLine/CarrierInfo 拡張(既存箱再利用)**
```rust
// 既存の ExitLine を拡張
pub struct ExitLine {
pub phi_connections: HashMap<String, ValueId>, // carrier → PHI result
}
// CarrierInfo は既に複数 Carrier 対応
pub struct CarrierInfo {
pub carriers: Vec<String>,
pub updates: HashMap<String, ASTNode>,
}
```
**メリット**:
- 新規箱なし(既存インフラ再利用)
- ExitLine が既に複数 Carrier 接続をサポート
**デメリット**:
- ExitLine の責務が拡大
**Phase 195 での判断**:
→ **Option B既存箱拡張を採用**
**理由**:
- ExitLine は既に「variable_map への接続」を担当
- 複数 Carrier → 複数 PHI は自然な拡張
- 新規箱を作る必要性が低いYAGNI 原則)
#### 3. 更新なし(不変)の扱い
**ケース**: 片方の分岐で Carrier が更新されない
```nyash
if(ch == '\\') {
escaped = true
// buffer は更新なし(不変)
} else {
buffer = buffer + ch
escaped = false
}
```
**設計案**: PHI 生成時に「前の値」を使用
```rust
// Then 分岐で buffer 更新なし
let then_buffer_value = previous_buffer_value; // ← ループ header の PHI param
// Else 分岐で buffer 更新あり
let else_buffer_value = emit_string_append(...);
// Merge 点で PHI
let buffer_phi = emit_phi(merge, then_buffer_value, else_buffer_value);
```
**実装詳細**:
- `get_update_or_unchanged()` 関数で検出
- 更新なし → `ValueId` として「前の値」を返す
- PHI 生成時に自動的に接続
### 成果物
- Pattern3 lowerer の擬似コード(本セクション)
- PhiGroupBox vs ExitLine 拡張の判断Option B 採用)
- 更新なし(不変)の扱い方設計
---
## Task 195-4: 実装スコープの決定(どこまでやるか)
### Phase 195-impl の範囲
**✅ Phase 195-impl で実装する**:
1. **複数 Carrier の P3 処理**2-3個程度
- `escaped` + `buffer` のような flag + accumulation
- `sum` + `count` のような accumulation + counter
2. **既存 UpdateKind 範囲内の update**:
- CounterLike: `count + 1`
- NumberAccumulation: `sum + i`
- StringAppend: `buffer + ch`
- BoolFlag: `true`, `false`(新規 UpdateKind 追加候補)
3. **両分岐での定義確認**:
- Then/Else で同じ Carrier が定義されるケース
- 更新なし(不変)の場合は自動的に「前の値」を使用
4. **E2E テスト**:
- 簡易版 _parse_string`ch = "x"` 定数版)
- 簡易版 if-sum配列アクセスなし版
**❌ Phase 195-impl で実装しない**:
1. **LoopBodyLocal + MethodCall 混在**:
- `local ch = s[i]; if(...) { buf += ch }`
- → Phase 191body-local initと Phase 193MethodCallの組み合わせ
- → Phase 195+ に延期(複雑度高い)
2. **外部ローカル変数ConditionEnv 拡張)**:
- `local digits = "012..."; digit = digits.indexOf(ch)`
- → Phase 200+ に保留(設計判断済み)
3. **ネストした If**:
- `if(...) { if(...) { ... } }`
- → Phase 196+ に延期P3 の P3
### ゴールの明確化
**Phase 195-impl のゴール**:
> 「Named carrier が 2-3 個あっても P3 lowerer が壊れない」こと。
>
> JsonParser/simple selfhost で「flag + count」くらいの例が通ること。
**成功基準**:
- [ ] 簡易版 _parse_string が JoinIR で動作escaped + buffer
- [ ] 簡易版 if-sum が JoinIR で動作sum + count
- [ ] 既存テストphase190-194が退行しない
- [ ] ドキュメント更新Implementation Status セクション追加)
### テストケース設計
#### テスト 1: flag + buffer (BoolFlag + StringAppend)
**ファイル**: `apps/tests/phase195_flag_buffer.hako`
```nyash
static box Main {
main() {
local buffer = ""
local escaped = false
local i = 0
loop(i < 3) {
local ch = "a" // ← 定数(配列アクセス回避)
if(i == 1) {
escaped = true
} else {
buffer = buffer + ch
escaped = false
}
i = i + 1
}
print(buffer) // Expected: "aa" (i=0,2 で追加)
return 0
}
}
```
#### テスト 2: sum + count (NumberAccumulation + CounterLike)
**ファイル**: `apps/tests/phase195_sum_count.hako`
```nyash
static box Main {
main() {
local sum = 0
local count = 0
local i = 0
loop(i < 5) {
if(i > 2) {
sum = sum + i // i=3,4 で加算
count = count + 1
}
i = i + 1
}
print(sum) // Expected: 7 (3+4)
print(count) // Expected: 2
return 0
}
}
```
---
## Task 195-5: CURRENT_TASK / overview 更新
### CURRENT_TASK.md 更新内容
```markdown
## Phase 195: Pattern 3 拡張(設計フェーズ)(完了予定: 2025-12-XX)
**目的**: P3If-Else PHIを複数キャリア対応に拡張する設計
**タスク**:
- [ ] 195-1: 対象ループ絞り込み_parse_string 簡易版、if-sum
- [ ] 195-2: LoopUpdateSummary/CarrierInfo 設計整理(複数キャリア対応)
- [ ] 195-3: Pattern3 lowerer 設計更新PhiGroup vs ExitLine 拡張判断)
- [ ] 195-4: 実装スコープ決定2-3キャリア、既存 UpdateKind 範囲内)
- [ ] 195-5: ドキュメント更新(本項目 + overview 更新)
**設計判断**:
- ✅ ExitLine 拡張で対応PhiGroupBox は作らない)
- ✅ 両分岐での Carrier 定義確認(更新なし = 前の値使用)
- ❌ ConditionEnv 拡張なしPhase 200+ 保留)
- ❌ LoopBodyLocal + MethodCall 混在は Phase 195+ 延期
**期待成果**:
- phase195-pattern3-extension-design.md完全設計書
- Phase 195-impl の実装スコープ明確化
- JsonParser カバレッジ 40% → 60% への道筋
```
### joinir-architecture-overview.md 更新内容
Section 7.2 "残タスク" に追記:
```markdown
- [ ] **Phase 195**: Pattern 3 拡張(複数キャリア対応)
- 設計フェーズ: P3 で 2-3 個の Carrier を同時処理
- ExitLine 拡張で複数 PHI 生成PhiGroupBox は不要)
- 対象: _parse_stringflag+buffer、if-sumsum+count
- Phase 195-impl で実装予定
```
---
## 成功基準(設計フェーズ)
- [x] 対象ループ選定完了_parse_string 簡易版、if-sum
- [x] キャリア分析表作成UpdateKind 分類済み)
- [x] 複数キャリア対応の設計原則明確化
- [x] Pattern3 lowerer の擬似コード作成
- [x] PhiGroupBox vs ExitLine 拡張の判断Option B 採用)
- [x] 実装スコープ決定Phase 195-impl 範囲明確化)
- [x] テストケース設計2ケース
- [x] ドキュメント更新計画作成
---
## 関連ファイル
### 設計対象
- `src/mir/builder/control_flow/joinir/patterns/pattern3_with_if.rs`Phase 195-impl で実装)
- `src/mir/join_ir/lowering/loop_update_summary.rs`BoolFlag UpdateKind 追加候補)
- `src/mir/join_ir/lowering/carrier_info.rs`(複数 Carrier 対応確認)
### テストファイルPhase 195-impl で作成)
- `apps/tests/phase195_flag_buffer.hako`BoolFlag + StringAppend
- `apps/tests/phase195_sum_count.hako`NumberAccumulation + CounterLike
### ドキュメント
- `docs/development/current/main/phase195-pattern3-extension-design.md`(本ファイル)
- `docs/development/current/main/joinir-architecture-overview.md`(更新予定)
- `CURRENT_TASK.md`Phase 195 設計タスク追加)
---
## 次のステップ
### Phase 195-impl: Pattern3 拡張実装
設計書(本ファイル)に基づいて実装:
1. Pattern3 lowerer に複数 Carrier 処理追加
2. ExitLine で複数 PHI 接続
3. BoolFlag UpdateKind 追加(必要に応じて)
4. E2E テストphase195_flag_buffer.hako, phase195_sum_count.hako
5. ドキュメント更新Implementation Status セクション)
### Phase 196+: 候補
- Pattern 3 のネスト対応if-in-if
- LoopBodyLocal + MethodCall + P3 の統合
- JsonParser の _parse_string 完全版(配列アクセス対応 = Phase 200+
---
## 設計原則Phase 195
1. **既存箱再利用**:
- PhiGroupBox を作らず、ExitLine/CarrierInfo を拡張
- YAGNIYou Aren't Gonna Need It原則
2. **段階的拡張**:
- 単一キャリアPhase 170-189→ 複数キャリアPhase 195
- 2-3 個程度に限定(無理に全部対応しない)
3. **Fail-Fast 継承**:
- ConditionEnv 拡張なしPhase 200+ 保留)
- 複雑なパターンは Phase 195+ に延期
4. **箱理論の実践**:
- 設計フェーズで構造を固める
- 実装フェーズは lowerer のみに集中
- ドキュメント駆動開発