feat(joinir): Phase 131-11 A-C - InfiniteEarlyExit パターン追加(検出部分)

## Step A: Feature Detection
- LoopPatternKind::InfiniteEarlyExit (Pattern 5) 追加
- LoopFeatures::is_infinite_loop フィールド追加
- detect_infinite_loop() で loop(true) 検出

## Step B: Classification Logic
- classify() を更新: Pattern 5 を Pattern 4 より優先
- Pattern 4 を狭化: has_continue && !has_break のみ
- 誤ルーティング完全除去

## Step C: Pattern Module
- pattern5_infinite_early_exit.rs 新規作成
- Fail-Fast 設計: 超狭い shape guard
- lowering はスケルトン(Phase 131-11-D で実装)

## 動作確認
- Pattern 5 正常検出 
- Shape guards 動作(1 break, 1 continue, 1 carrier)
- Pattern 4 誤ルーティング回避 

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-14 09:59:34 +09:00
parent e1d706d2e0
commit 233a49d902
8 changed files with 253 additions and 17 deletions

View File

@ -69,6 +69,7 @@ impl<'a> LoopPatternContext<'a> {
/// Phase 194+: Automatically detects continue/break statements in body
/// Phase 192: Extract features and classify pattern from AST
/// Phase 193: Feature extraction delegated to ast_feature_extractor module
/// Phase 131-11: Detects infinite loop condition
pub(crate) fn new(
condition: &'a ASTNode,
body: &'a [ASTNode],
@ -80,7 +81,8 @@ impl<'a> LoopPatternContext<'a> {
let has_break = ast_features::detect_break_in_body(body);
// Phase 193: Extract features using modularized extractor
let features = ast_features::extract_features(body, has_continue, has_break);
// Phase 131-11: Pass condition for infinite loop detection
let features = ast_features::extract_features(condition, body, has_continue, has_break);
// Phase 192: Classify pattern based on features
let pattern_kind = crate::mir::loop_pattern_detection::classify(&features);
@ -135,10 +137,14 @@ pub(crate) struct LoopPatternEntry {
/// Static table of all registered loop patterns.
/// Patterns are tried in priority order (lowest first).
///
/// # Current Patterns (Phase 192: Structure-based detection)
/// # Current Patterns (Phase 131-11: Pattern 5 added)
///
/// All patterns now use structure-based detection via LoopFeatures and classify():
///
/// - Pattern 5 (priority 1): Infinite Loop with Early Exit (llvm_stage3_loop_only.hako) [Phase 131-11]
/// - Detection: pattern_kind == InfiniteEarlyExit
/// - Structure: is_infinite_loop && has_break && has_continue
///
/// - Pattern 4 (priority 5): Loop with Continue (loop_continue_pattern4.hako)
/// - Detection: pattern_kind == Pattern4Continue
/// - Structure: has_continue && !has_break
@ -157,9 +163,15 @@ pub(crate) struct LoopPatternEntry {
///
/// Note: func_name is now only used for debug logging, not pattern detection
pub(crate) static LOOP_PATTERNS: &[LoopPatternEntry] = &[
LoopPatternEntry {
name: "Pattern5_InfiniteEarlyExit",
priority: 1, // Highest priority - most specific (infinite loop with break+continue)
detect: super::pattern5_infinite_early_exit::can_lower,
lower: super::pattern5_infinite_early_exit::lower,
},
LoopPatternEntry {
name: "Pattern4_WithContinue",
priority: 5, // Highest priority - continue is most specific
priority: 5, // Second priority - continue without break
detect: super::pattern4_with_continue::can_lower,
lower: super::pattern4_with_continue::lower,
},