feat(joinir): Phase 224 - DigitPosPromoter for A-4 pattern (core complete)

- New DigitPosPromoter Box for cascading indexOf pattern detection
- Two-tier promotion strategy: A-3 Trim → A-4 DigitPos fallback
- Unit tests 6/6 PASS (comparison operators, cascading dependency)
- Promotion verified: digit_pos → is_digit_pos carrier

⚠️ Lowerer integration gap: lower_loop_with_break_minimal doesn't
recognize promoted variables yet (Phase 224-continuation)

🤖 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-10 16:21:01 +09:00
parent b5661c1915
commit 00d1ec7cc5
8 changed files with 1704 additions and 33 deletions

View File

@ -308,26 +308,62 @@ Local Region (1000+):
- Phase 174 で `_parse_string` 最小化版(終端クォート検出)でも動作確認済み。
- → 空白文字以外の文字比較ループにも対応可能TrimLoopHelper の汎用性実証)。
- **LoopBodyCondPromoterPhase 223-3 実装完了)**
- **LoopBodyCondPromoterPhase 223-3 + 223.5 + 224 実装完了)**
- ファイル: `src/mir/loop_pattern_detection/loop_body_cond_promoter.rs`
- 責務:
- ループ条件header/break/continueに出てくる LoopBodyLocal を carrier に昇格する統一 API。
- P0Category A-3: _skip_whitespace: 単一変数の Trim パターンのみ対応
- Pattern 2/Pattern 4 両対応の薄いコーディネーター箱detection は LoopBodyCarrierPromoter に委譲)
- Pattern 2/Pattern 4 両対応の薄いコーディネーター箱detection は専門 Promoter に委譲)
- **Phase 224: Two-tier strategy** - A-3 Trim → A-4 DigitPos フォールバック型オーケストレーション
- Phase 223-3 実装内容:
- `extract_continue_condition()`: body 内の if 文から continue 条件を抽出。
- `try_promote_for_condition()`: LoopBodyCarrierPromoter を使った昇格処理。
- Pattern4 への統合完了: LoopBodyLocal 条件の昇格成功時に lowering を続行(以前は Fail-Fast
- Phase 223.5 実装内容:
- Pattern2 への統合完了: header/break 条件を分析し昇格を試みる。
- A-4digit_posテスト追加: cascading LoopBodyLocal パターンで Fail-Fast 動作を確認。
- error_messages.rs に Pattern2 用エラー関数追加: `format_error_pattern2_promotion_failed()` など。
- Phase 224 実装内容Core Implementation Complete ⚠️):
- **Two-tier promotion**: Step1 で A-3 Trim 試行 → 失敗なら Step2 で A-4 DigitPos 試行 → 両方失敗で Fail-Fast。
- **DigitPosPromoter 統合**: cascading indexOf パターンsubstring → indexOf → comparisonの昇格をサポート。
- **Unit test 完全成功**: 6/6 PASSpromoter 自体は完璧動作)。
- **Lowerer Integration Gap**: lower_loop_with_break_minimal が昇格済み変数を認識せず、独立チェックでエラー検出Phase 224-continuation で対応予定)。
- 設計原則:
- **Thin coordinator**: LoopBodyCarrierPromoter に promotion ロジックを委譲し、metadata のみ返す
- **Thin coordinator**: 専門 PromoterLoopBodyCarrierPromoter / DigitPosPromoterに昇格ロジックを委譲
- **Pattern-agnostic**: Pattern2 (break) / Pattern4 (continue) の統一入口として機能。
- **Fail-Fast**: 複雑パターンCategory B: 多段 if / method chainは引き続き reject
- **Fail-Fast with clear routing**: A-3 → A-4 順で試行し、両方失敗なら明示的エラー
- 入出力:
- 入力: `ConditionPromotionRequest`loop_param_name, cond_scope, break_cond/continue_cond, loop_body
- 出力: `ConditionPromotionResult::Promoted { carrier_info, promoted_var, carrier_name }` または `CannotPromote { reason, vars }`
- 使用元Phase 223-3 実装:
- 使用元Phase 223.5 実装完了、Phase 224 拡張済み:
- Pattern4: promotion-first昇格試行 → 成功なら CarrierInfo merge → 失敗なら Fail-Fast
- Pattern2: 既存 TrimLoopLowerer 経由で間接利用(将来的に統一可能
- Pattern2: promotion-first同上、break条件を分析対象とする
- **DigitPosPromoterPhase 224 実装完了 ⚠️ Core Complete**
- ファイル: `src/mir/loop_pattern_detection/loop_body_digitpos_promoter.rs`467 lines
- 責務:
- **A-4 pattern**: Cascading LoopBodyLocal with indexOfsubstring → indexOf → comparisonの昇格。
- **Pattern detection**: `local ch = s.substring(...); local digit_pos = digits.indexOf(ch); if digit_pos < 0 { break }`
- **Comparison operators**: `<`, `>`, `<=`, `>=`, `!=` をサポートequality `==` は A-3 Trim 領域)。
- **Dependency validation**: indexOf() が別の LoopBodyLocal に依存していることを検証cascading pattern
- Phase 224 実装内容:
- `try_promote()`: A-4 パターン検出 & bool carrier 昇格(`digit_pos` → `is_digit_pos`)。
- **Unit tests**: 6/6 PASSbasic pattern, non-indexOf rejection, no dependency rejection, comparison operators, equality rejection
- **Integration**: LoopBodyCondPromoter から A-3 Trim フォールバック後に呼ばれる。
- 設計原則:
- **One Box, One Question**: A-4 DigitPos パターン専用A-3 Trim は LoopBodyCarrierPromoter に残す)。
- **Separation of Concerns**: Trimequality-basedと DigitPoscomparison-basedを分離。
- **Bool carrier consistency**: A-3 Trim と同じく bool carrier に昇格(`is_digit_pos`)。
- 入出力:
- 入力: `DigitPosPromotionRequest`cond_scope, break_cond/continue_cond, loop_body
- 出力: `DigitPosPromotionResult::Promoted { carrier_info, promoted_var, carrier_name }` または `CannotPromote { reason, vars }`
- 現状の制約Phase 224-continuation で対応予定):
- **Promotion は成功**: LoopBodyCondPromoter → DigitPosPromoter → Promoted ✅
- **Lowerer integration gap**: lower_loop_with_break_minimal が昇格済み変数を認識せず、break condition AST に元の変数名が残っているため独立チェックでエラー。
- **Solution**: Option Bpromoted variable trackingで昇格済み変数リストを lowerer に渡す1-2h 実装予定)。
- 参考:
- 設計ドキュメント: `docs/development/current/main/phase224-digitpos-promoter-design.md`
- 完全サマリ: `docs/development/current/main/PHASE_224_SUMMARY.md`
- テストケース: `apps/tests/phase2235_p2_digit_pos_min.hako`
- **ContinueBranchNormalizer / LoopUpdateAnalyzer**
- ファイル: