feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装
## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks) ### 実装完了 ✅ **Phase 1: Fixture作成** - apps/tests/phase1883_nested_minimal.hako 追加 - Add/Compare のみ(乗算なし) - 期待 exit code: 9 (3×3 nested loops) - 既存 lowering で fallback 動作確認 **Phase 2: 選択ロジック (SSOT)** - LoopPatternContext に step_tree_max_loop_depth フィールド追加 - choose_pattern_kind() に Pattern6 選択ロジック実装: 1. Cheap check (has_inner_loop) 2. StepTree 構築 (max_loop_depth 取得) 3. AST validation (is_pattern6_lowerable) - pattern6_nested_minimal.rs モジュール作成 (stub) - LOOP_PATTERNS に Pattern6 entry 追加 - **検証**: Pattern6 が正しく選択される ✅ ### 設計原則 (確認済み) 1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない 2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+) 3. **最小実装**: inner local だけ、Pattern1 モデル二重化 4. **cfg! 依存なし**: production で動作 ### 検証結果 ``` [choose_pattern_kind] has_inner_loop=true [choose_pattern_kind] max_loop_depth=2 [choose_pattern_kind] is_pattern6_lowerable=true ✅ Pattern6 SELECTED! ``` Stub からの期待エラー: ``` [ERROR] ❌ [Pattern6] Nested loop lowering not yet implemented ``` ### 次: Phase 3 (Lowering 実装 - 推定4時間) 残りタスク: - Phase 3-1: AST 抽出ヘルパー - Phase 3-2: Validation ヘルパー - Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit) - Phase 3-4: fixture が exit=9 を返すことを検証 ### 変更ファイル **新規**: - apps/tests/phase1883_nested_minimal.hako - src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs - docs/development/current/main/phases/phase-188.{1,2,3}/README.md **変更**: - src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択) - src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張) - src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言) 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -74,6 +74,11 @@ pub(crate) struct LoopPatternContext<'a> {
|
||||
/// SSOT Principle: Avoid re-detecting ConditionalStep in lowering phase.
|
||||
#[allow(dead_code)]
|
||||
pub skeleton: Option<&'a LoopSkeleton>,
|
||||
|
||||
/// Phase 188.3: Cached StepTree max_loop_depth for Pattern6
|
||||
/// None if not computed, Some(depth) if Pattern6 candidate
|
||||
/// Avoids re-building StepTree in lowering phase
|
||||
pub step_tree_max_loop_depth: Option<u32>,
|
||||
}
|
||||
|
||||
impl<'a> LoopPatternContext<'a> {
|
||||
@ -111,6 +116,7 @@ impl<'a> LoopPatternContext<'a> {
|
||||
pattern_kind,
|
||||
fn_body: None, // Phase 200-C: Default to None
|
||||
skeleton: None, // Phase 92 P0-2: Default to None
|
||||
step_tree_max_loop_depth: None, // Phase 188.3: Default to None
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,6 +392,11 @@ pub(crate) struct LoopPatternEntry {
|
||||
/// Note: func_name is now only used for debug logging, not pattern detection
|
||||
/// Phase 286: Pattern5 removed (migrated to Plan-based routing)
|
||||
pub(crate) static LOOP_PATTERNS: &[LoopPatternEntry] = &[
|
||||
LoopPatternEntry {
|
||||
name: "Pattern6_NestedLoopMinimal", // Phase 188.3: 1-level nested loop
|
||||
detect: super::pattern6_nested_minimal::can_lower,
|
||||
lower: super::pattern6_nested_minimal::lower,
|
||||
},
|
||||
LoopPatternEntry {
|
||||
name: "Pattern4_WithContinue",
|
||||
detect: super::pattern4_with_continue::can_lower,
|
||||
|
||||
Reference in New Issue
Block a user