docs: Phase 193 ConditionEnv design decision - maintain 2-tier boundary

Phase 193 設計判断の記録:
- ConditionEnv を「ループパラメータ専用 view」として維持
- 外部ローカル変数(digits 等)は含めない判断を明記
- 理由: Phase 170-200 の 2-tier 境界設計(ConditionEnv/LoopBodyLocalEnv)保持
- 安全性と保守性を優先(箱理論の実践)

phase193-init-methodcall-design.md:
- "ConditionEnv 制約の設計判断" セクション追加
- 対応範囲明確化: ループパラメータベース MethodCall のみ
- 将来の対応案: 独立した箱として設計、または .hako リライト
- Phase 194+ は Option C(実戦投入優先)を推奨

CURRENT_TASK.md:
- Phase 193 完了マーク(2025-12-09)
- 重要な設計判断セクション追加
- digits.indexOf(ch) は Phase 200+ に保留と明記

設計原則:
> 「LoopBodyLocal + Param ベースの安全な init」は JoinIR に乗せる。
> 「テーブル+メソッド呼び出し」のような複合パターンは、次の箱案件にする。

🤖 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 06:04:09 +09:00
parent a722e51a56
commit eb1eb2c712
2 changed files with 138 additions and 7 deletions

View File

@ -284,13 +284,17 @@
- ✅ Fail-Fast: Unsupported patterns → NormalizationResult::Unchanged - ✅ Fail-Fast: Unsupported patterns → NormalizationResult::Unchanged
- ✅ 再利用性: Phase 191 (body-local init) + Phase 190 (NumberAccumulation) 活用 - ✅ 再利用性: Phase 191 (body-local init) + Phase 190 (NumberAccumulation) 活用
- ✅ 変更最小化: Emission ラインCarrierUpdateEmitter, LoopBodyLocalInitLowererは変更なし - ✅ 変更最小化: Emission ラインCarrierUpdateEmitter, LoopBodyLocalInitLowererは変更なし
- [ ] Phase 193: LoopBodyLocalInit MethodCall Extension - [x] **Phase 193: LoopBodyLocalInit MethodCall Extension** (完了: 2025-12-09)
- **目的**: Phase 186 limitation 解除、MethodCall/Call を init 式でサポート - **目的**: Phase 186 limitation 部分解除、MethodCall を init 式でサポート
- 193-1: `lower_init_expr()` 拡張MethodCall/Call 分岐追加) - `emit_method_call_init()` 実装(~80行、MethodCall → BoxCall 変換
- 193-2: JoinIR emission ロジック(既存 method lowering 再利用 - ✅ String literal init サポート追加Phase 186 拡張
- 193-3: UpdateEnv integrationtemp の ValueId 解決) - ✅ Method whitelistindexOf, get, toStringFail-Fast 実装
- 193-4: E2E テスト`result = result * 10 + digits.indexOf(ch)` が完全動作) - E2E テスト: `i.toString()` 成功、退行なし
- **期待成果**: Phase 192 normalization と組み合わせて JsonParser 完全対応 - **重要な設計判断**: ConditionEnv を「ループパラメータ専用」として維持
- ✅ 対応: ループパラメータをレシーバーとする MethodCall (`i.toString()`)
- ⚠️ 保留: 外部ローカルをレシーバーとする MethodCall (`digits.indexOf(ch)`)
- **理由**: Phase 170-200 の 2-tier 境界設計ConditionEnv/LoopBodyLocalEnvを保持
- **将来**: Phase 200+ で独立した箱として設計、または .hako リライト対応
- [ ] Phase 194: JsonParser 残りループ展開 - [ ] Phase 194: JsonParser 残りループ展開
- _parse_array, _parse_object P4 Continue, MethodCall 複数対応) - _parse_array, _parse_object P4 Continue, MethodCall 複数対応)
- _parse_string 完全版 P2/P4, string concat + escape - _parse_string 完全版 P2/P4, string concat + escape

View File

@ -538,3 +538,130 @@ Phase 193 完了マークを追加:
- 条件分岐を跨ぐ PHI 接続 - 条件分岐を跨ぐ PHI 接続
Phase 193 完了後、ユーザーと相談して次の優先順位を決定する。 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実戦投入優先を推奨**