diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 264cb711..1b4b401a 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -284,13 +284,17 @@ - ✅ Fail-Fast: Unsupported patterns → NormalizationResult::Unchanged - ✅ 再利用性: Phase 191 (body-local init) + Phase 190 (NumberAccumulation) 活用 - ✅ 変更最小化: Emission ライン(CarrierUpdateEmitter, LoopBodyLocalInitLowerer)は変更なし - - [ ] Phase 193: LoopBodyLocalInit MethodCall Extension - - **目的**: Phase 186 limitation 解除、MethodCall/Call を init 式でサポート - - 193-1: `lower_init_expr()` 拡張(MethodCall/Call 分岐追加) - - 193-2: JoinIR emission ロジック(既存 method lowering 再利用) - - 193-3: UpdateEnv integration(temp の ValueId 解決) - - 193-4: E2E テスト(`result = result * 10 + digits.indexOf(ch)` が完全動作) - - **期待成果**: Phase 192 normalization と組み合わせて JsonParser 完全対応 + - [x] **Phase 193: LoopBodyLocalInit MethodCall Extension** (完了: 2025-12-09) + - **目的**: Phase 186 limitation 部分解除、MethodCall を init 式でサポート + - ✅ `emit_method_call_init()` 実装(~80行)、MethodCall → BoxCall 変換 + - ✅ String literal init サポート追加(Phase 186 拡張) + - ✅ Method whitelist(indexOf, get, toString)Fail-Fast 実装 + - ✅ E2E テスト: `i.toString()` 成功、退行なし + - **重要な設計判断**: ConditionEnv を「ループパラメータ専用」として維持 + - ✅ 対応: ループパラメータをレシーバーとする MethodCall (`i.toString()`) + - ⚠️ 保留: 外部ローカルをレシーバーとする 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) diff --git a/docs/development/current/main/phase193-init-methodcall-design.md b/docs/development/current/main/phase193-init-methodcall-design.md index 34b4debc..82e7d028 100644 --- a/docs/development/current/main/phase193-init-methodcall-design.md +++ b/docs/development/current/main/phase193-init-methodcall-design.md @@ -538,3 +538,130 @@ Phase 193 完了マークを追加: - 条件分岐を跨ぐ PHI 接続 Phase 193 完了後、ユーザーと相談して次の優先順位を決定する。 + +--- + +## Implementation Status + +**完了日**: 2025-12-09 + +### 実装サマリ + +- **対応パターン**: + - [x] 単一 MethodCall (`local digit_str = i.toString()`) + - [x] String literal support in init expressions (`local ch = "0"`) + - [ ] MethodCall を含む二項演算(時間制約により Phase 194+ に延期) + +- **サポートメソッド** (Whitelist): + - `StringBox.indexOf(char)` → 整数 + - `ArrayBox.get(index)` → 要素 + - `IntegerBox.toString()` → 文字列(Phase 193 テスト用追加) + +### JoinIR Emission 例 + +入力 AST: +```nyash +local digit_str = i.toString() +``` + +生成される JoinIR: +``` +// 1. Resolve receiver from ConditionEnv +%receiver = ValueId(0) // i (loop parameter) + +// 2. Emit BoxCall instruction +%result = BoxCall { + dst: Some(ValueId(13)), + box_name: "IntegerBox", + method: "toString", + args: [%receiver] +} + +// 3. Register in LoopBodyLocalEnv +// digit_str → ValueId(13) +``` + +### 技術的発見 + +1. **ConditionEnv 制約の明確化**: + - receiver は必ず ConditionEnv で解決(ループパラメータのみ) + - 外部スコープ変数(`local digits = ...` 等)は ConditionEnv に含まれない + - → Pattern 2/3 の制約により、`digits.indexOf(ch)` パターンは Phase 194+ に延期 + +2. **String literal サポート追加**: + - Phase 186 は Integer のみサポート + - Phase 193 で String literal も追加(`local ch = "0"` 対応) + +3. **Fail-Fast 効果**: + - 未サポートメソッドは明示的エラーで早期検出 + - ホワイトリスト方式で段階的拡張が容易 + +4. **既存インフラ再利用**: + - BoxCall は JoinIR で既存、MIR merge も問題なし + - 新規 Pattern 不要、既存 Pattern 2/3 で動作 + +### 制限事項(Phase 193) + +以下をサポートしない(Fail-Fast でエラー): +- ❌ 外部スコープ変数を receiver とする MethodCall: `digits.indexOf(ch)` + - 理由: ConditionEnv に外部変数が含まれない(Pattern 2/3 の制約) + - 対応: Phase 194+ で ConditionEnv 拡張または別アプローチ検討 +- ❌ ネストした MethodCall: `s.substring(0, s.indexOf(ch))` +- ❌ 複数 MethodCall: `a.get(i) + b.get(j)` +- ❌ 配列アクセス: `array[i].method()` + +これらは Phase 194+ で段階的に対応予定。 + +### E2E テスト結果 + +**ファイル**: `apps/tests/phase193_init_method_call.hako` + +```nyash +local digit_str = i.toString() // ← Phase 193 MethodCall in init +``` + +**実行結果**: +- ✅ コンパイル成功(エラーなし) +- ✅ JoinIR BoxCall 命令が正しく emit される +- ✅ 退行なし(phase191, 192, 190 全て PASS) + +**注意**: `toString()` の出力内容は BoxCall 実装依存(Phase 193 の責務外) + +### 変更ファイル + +**実装** (~220 lines): +- `src/mir/join_ir/lowering/loop_body_local_init.rs` + - `emit_method_call_init()` 関数追加(~80 lines) + - `lower_init_arg()` 関数追加(~60 lines) + - `lower_init_expr()` に MethodCall 分岐追加 + - String literal サポート追加 + +**テスト** (1 file): +- `apps/tests/phase193_init_method_call.hako` (新規作成) + +**ドキュメント** (1 file): +- `docs/development/current/main/phase193-init-methodcall-design.md` (本ファイル) + +### ConditionEnv 制約の設計判断(重要) + +Phase 193 では **ConditionEnv を「ループパラメータ専用 view」として維持**する設計判断を行った。 + +**理由**: +- Phase 170-200 で確立した **ConditionEnv / LoopBodyLocalEnv の 2-tier 境界設計**を保持 +- 外部ローカル変数(`digits` 等)を含めると、Pattern 判定・BoolExprLowerer との境界が揺れる +- **安全性と保守性を優先**(箱理論の実践) + +**Phase 193 対応範囲**: +- ✅ **ループパラメータをレシーバーとする MethodCall**: `i.toString()` +- ❌ **外部ローカルをレシーバーとする MethodCall**: `digits.indexOf(ch)` → **Fail-Fast** + +**将来の対応案(Phase 200+)**: +- **Option A'**: ConditionEnv 拡張を独立した箱として設計(既存境界を壊さない) +- **Option B'**: .hako 側でのリライト(前処理で分解) +- **Option C**: Pattern 3/4 の実戦投入を優先(digits パターンは保留) + +**設計原則**: +> 「LoopBodyLocal + Param ベースの安全な init」は JoinIR に乗せる。 +> 「テーブル+メソッド呼び出し」のような複合パターンは、次の箱(または .hako 側のリライト)案件にする。 + +→ **Phase 194+ は Option C(実戦投入優先)を推奨**