Files
hakorune/docs/development/current/main/phases/phase-92/p0-2-skeleton-to-context.md

193 lines
6.3 KiB
Markdown
Raw Normal View History

# Phase 92 P0-2: Skeleton Integration to LoopPatternContext (Option A)
## 概要
ConditionalStep情報をPattern2 lowererに渡すため、LoopPatternContextにSkeletonフィールドを追加しました。
feat(mir): Phase 92 P2-2 - Body-local variable support for ConditionalStep Phase 92 P2-2完了:ConditionalStepのcondition(ch == '\\'など)でbody-local変数をサポート ## 主要変更 ### 1. condition_lowerer.rs拡張 - `lower_condition_to_joinir`に`body_local_env`パラメータ追加 - 変数解決優先度:ConditionEnv → LoopBodyLocalEnv - すべての再帰ヘルパー(comparison, logical_and, logical_or, not, value_expression)対応 ### 2. conditional_step_emitter.rs修正 - `emit_conditional_step_update`に`body_local_env`パラメータ追加 - condition loweringにbody-local環境を渡す ### 3. loop_with_break_minimal.rs修正 - break condition loweringをbody-local init の**後**に移動(line 411) - header_break_lowering::lower_break_conditionにbody_local_env渡す - emit_conditional_step_updateにbody_local_env渡す(line 620) ### 4. header_break_lowering.rs修正 - `lower_break_condition`に`body_local_env`パラメータ追加 - scope_managerにbody-local環境を渡す ### 5. 全呼び出し箇所修正 - expr_lowerer.rs (2箇所) - method_call_lowerer.rs (2箇所) - loop_with_if_phi_if_sum.rs (3箇所) - loop_with_continue_minimal.rs (1箇所) - carrier_update_emitter.rs (1箇所・legacy) ## アーキテクチャ改善 ### Break Condition Lowering順序修正 旧: Header → **Break Cond** → Body-local Init 新: Header → **Body-local Init** → Break Cond 理由:break conditionが`ch == '\"'`のようにbody-local変数を参照する場合、body-local initが先に必要 ### 変数解決優先度(Phase 92 P2-2) 1. ConditionEnv(ループパラメータ、captured変数) 2. LoopBodyLocalEnv(body-local変数like `ch`) ## テスト ### ビルド ✅ cargo build --release成功(30 warnings、0 errors) ### E2E ⚠️ body-local promotion問題でブロック(Phase 92範囲外) - Pattern2はbody-local変数をcarrier promotionする必要あり - 既存パターン(A-3 Trim, A-4 DigitPos)に`ch = get_char(i)`が該当しない - **Phase 92 P2-2目標(condition loweringでbody-local変数サポート)は達成** ## 次タスク(Phase 92 P3以降) - body-local variable promotion拡張(Pattern2で`ch`のような変数を扱う) - P5b E2Eテスト完全動作確認 ## Phase 92 P2-2完了 ✅ Body-local変数のcondition lowering対応完了 ✅ ConditionalStepでbody-local変数参照可能 ✅ Break condition lowering順序修正
2025-12-16 17:08:15 +09:00
## UpdatePhase 92 P1
Phase 92 P1 で境界を整理し、routing 層から skeleton を取り除いた。
本ドキュメントは「P0-2 で一度試した配線Option A」の記録として残し、現行の入口は `docs/development/current/main/phases/phase-92/README.md` を SSOT とする。
## SSOT原則
**中心的なルール**: Canonicalizerが一度検出したConditionalStep情報を、lowering側で再検出しない。Skeleton経由でUpdate情報を渡す。
## 実装内容
### 1. router.rs - LoopPatternContextの拡張
**追加フィールド**:
```rust
/// Phase 92 P0-2: Optional LoopSkeleton from canonicalizer
/// This provides ConditionalStep information for Pattern2 lowering.
/// None if canonicalizer hasn't run yet (backward compatibility).
/// SSOT Principle: Avoid re-detecting ConditionalStep in lowering phase.
pub skeleton: Option<&'a LoopSkeleton>,
```
**新規メソッド**:
```rust
/// Phase 92 P0-2: Set skeleton (for canonicalizer integration)
pub(crate) fn with_skeleton(mut self, skeleton: &'a LoopSkeleton) -> Self {
self.skeleton = Some(skeleton);
self
}
```
**変更内容**:
- `skeleton: None`をデフォルト値として`new()`に追加
- 後方互換性を保つため、Optionalとして実装
### 2. parity_checker.rs - Skeletonの取得と返却
**関数シグネチャ変更**:
```rust
// Before:
pub(super) fn verify_router_parity(...) -> Result<(), String>
// After (Phase 92 P0-2):
pub(super) fn verify_router_parity(...)
-> (Result<(), String>, Option<LoopSkeleton>)
```
**変更理由**:
- 既に`canonicalize_loop_expr()`を呼び出していた
- Skeletonを破棄せず、呼び出し側に返すことで再利用可能に
- パリティチェックとSkeleton取得の2つの責務を同時に実行
### 3. routing.rs - Skeletonのコンテキストへの設定
**実装パターン**:
```rust
// Phase 92 P0-2: Get skeleton from canonicalizer for Option A
let skeleton_holder: Option<crate::mir::loop_canonicalizer::LoopSkeleton>;
if crate::config::env::joinir_dev_enabled() {
let (result, skeleton_opt) = self.verify_router_parity(condition, body, func_name, &ctx);
result?;
skeleton_holder = skeleton_opt;
if skeleton_holder.is_some() {
// Set skeleton reference in context (must use holder lifetime)
ctx.skeleton = skeleton_holder.as_ref();
}
} else {
skeleton_holder = None;
}
```
**設計ポイント**:
- `skeleton_holder`でライフタイムを延長
- `ctx.skeleton = skeleton_holder.as_ref()`で参照を設定
- `joinir_dev_enabled()`時のみ有効(パフォーマンス考慮)
### 4. pattern2_with_break.rs - ConditionalStepの検出
**can_lower()への追加**:
```rust
// Phase 92 P0-2: Check skeleton for ConditionalStep support
if let Some(skeleton) = ctx.skeleton {
use crate::mir::loop_canonicalizer::UpdateKind;
// Count ConditionalStep carriers
let conditional_step_count = skeleton.carriers.iter()
.filter(|c| matches!(c.update_kind, UpdateKind::ConditionalStep { .. }))
.count();
if conditional_step_count > 0 {
if ctx.debug {
trace::trace().debug(
"pattern2/can_lower",
&format!(
"Phase 92 P0-2: Found {} ConditionalStep carriers in skeleton",
conditional_step_count
),
);
}
// Phase 92 P0-2: ConditionalStep support enabled
// Pattern2 can handle these via if-else JoinIR generation
// TODO: Implement actual lowering in cf_loop_pattern2_with_break_impl
}
}
```
**実装戦略**:
- まず検出ロジックのみ実装TODOマーク付き
- 実際のloweringは次のフェーズで実装
- デバッグトレース追加で動作確認可能
## 箱化モジュール化の原則
### 責任分離
| モジュール | 責任 |
|-----------|------|
| **loop_canonicalizer** | LoopSkeleton生成、ConditionalStep検出 |
| **parity_checker** | パリティ検証、Skeleton取得 |
| **routing** | Skeletonのコンテキスト設定 |
| **pattern2_with_break** | ConditionalStepのlowering将来実装 |
### Fail-Fast原則
- **未対応ケース**: TODOコメントで明示
- **エラーケース**: 既存のエラーハンドリングを維持
- **検証**: can_lower()で早期チェック
## 後方互換性
### 既存パターンへの影響
- **Pattern 1-5**: `ctx.skeleton``None`のまま、既存動作に影響なし
- **Pattern 2**: Skeletonがある場合のみ追加機能が有効化
- **テスト**: 全20テスト中18テスト成功2テスト無視
### 段階的導入
1. **Phase 92 P0-2** (このフェーズ): Skeleton配線のみ
2. **Phase 92 P1**: ConditionalStep lowering実装
3. **Phase 92 P2**: carrier_update_emitter統合
## ビルド結果
```bash
cargo check --release
# ✅ 成功 (警告のみ、エラーなし)
cargo test --release --lib pattern2
# ✅ 18 passed; 0 failed; 2 ignored
```
## 次のステップ (Phase 92 P1)
### ConditionalStep Lowering実装
1. **carrier_update_emitter.rs**:
- `UpdateKind::ConditionalStep`のマッチング追加
- if-else形式のJoinIR生成
2. **loop_update_analyzer.rs**:
- ConditionalStep用の処理追加必要に応じて
3. **pattern2_with_break.rs**:
- TODO実装
- Skeletonからのthen_delta/else_delta読み取り
- JoinIR if-else構造の生成
### テストケース追加
- `test_escape_sequence_loop()`: `i += 2` vs `i += 1`
- `test_conditional_delta_carriers()`: 複数キャリア対応
## ファイル一覧
実装で変更されたファイル:
- `/home/tomoaki/git/hakorune-selfhost/src/mir/builder/control_flow/joinir/patterns/router.rs`
- `/home/tomoaki/git/hakorune-selfhost/src/mir/builder/control_flow/joinir/parity_checker.rs`
- `/home/tomoaki/git/hakorune-selfhost/src/mir/builder/control_flow/joinir/routing.rs`
- `/home/tomoaki/git/hakorune-selfhost/src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`
## 参照
- **Skeleton定義**: `/home/tomoaki/git/hakorune-selfhost/src/mir/loop_canonicalizer/skeleton_types.rs`
- **UpdateKind Contract**: skeleton_types.rs L63-109 (ConditionalStepのコメント)