# Phase 231: ExprLowerer パイロット実装(Pattern2 条件式限定) ## 概要 Phase 231 は、Phase 230 で設計した ExprLowerer / ScopeManager アーキテクチャの実現可能性を検証するパイロット実装。 Pattern2 の break 条件式に限定し、新しい変数解決システムが既存コードに素直に統合できることを確認した。 ## 実装内容 ### 1. ScopeManager trait(変数解決の統一インターフェース) **ファイル**: `src/mir/join_ir/lowering/scope_manager.rs` **責務**: - 変数参照を統一的に扱う trait - ConditionEnv / LoopBodyLocalEnv / CapturedEnv / CarrierInfo を統合 - 変数のスコープ種別(LoopVar / Carrier / LoopBodyLocal / Captured)を判定 **設計原則**: - **Box-First**: trait-based "box" で変数解決を抽象化 - **Single Responsibility**: 変数解決のみ担当(AST lowering や ValueId 割り当ては別箱) - **Testable**: 独立してテスト可能 ### 2. Pattern2ScopeManager(Pattern2 専用実装) **ファイル**: `src/mir/join_ir/lowering/scope_manager.rs` **責務**: - Pattern2 のすべての環境を統合(ConditionEnv, LoopBodyLocalEnv, CapturedEnv, CarrierInfo) - promoted_loopbodylocals の名前解決(`digit_pos` → `is_digit_pos` 変換) **Lookup 順序**: 1. ConditionEnv(ループ変数、キャリア、条件専用変数) 2. LoopBodyLocalEnv(ボディローカル変数) 3. CapturedEnv(キャプチャされた外部変数) 4. Promoted LoopBodyLocal(昇格された変数の名前変換) ### 3. ExprLowerer(式 lowering の統一 API) **ファイル**: `src/mir/join_ir/lowering/expr_lowerer.rs` **責務**: - AST 式を JoinIR ValueId へ lowering - ScopeManager を使った変数解決 - サポートされていない AST ノードの検出と fallback **Phase 231 スコープ**: - **Context**: Condition のみ(loop/break 条件) - **Supported**: リテラル、変数、比較演算(<, >, ==, !=, <=, >=)、論理演算(and, or, not) - **Not Supported**: MethodCall, NewBox, 複雑な式 **設計原則**: - **Fail-Safe**: 未対応ノードは明示的エラー(実行時エラーにしない) - **Thin Wrapper**: 既存の condition_lowerer を活用(Phase 231 は API 統一が目的) - **Incremental Adoption**: 検証専用、実際の lowering 置き換えは Phase 232+ ### 4. Pattern2 統合(pre-validation) **ファイル**: `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs` **統合方法**: - break 条件 lowering の **前** に ExprLowerer で検証 - 成功: ログ出力(`[pattern2/phase231] ✓ ExprLowerer successfully validated`) - UnsupportedNode: fallback ログ(期待される動作) - 予期しないエラー: 警告ログ(legacy path が処理) **重要**: Phase 231 は **検証専用**。実際の lowering は従来通り `lower_loop_with_break_minimal` が実行。 ## テスト結果 ### 単体テスト ``` test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_loop_var ... ok test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_carrier ... ok test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_promoted_variable ... ok test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_body_local ... ok test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_simple_comparison ... ok test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_variable_not_found ... ok test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_unsupported_node ... ok test mir::join_ir::lowering::expr_lowerer::tests::test_is_supported_condition ... ok ``` ### 統合テスト ``` test result: PASSED. 890 passed; 7 failed; 64 ignored ``` - 890 PASS(変更前と同じ) - 7 FAIL(pre-existing issues、Phase 231 とは無関係) - Pattern2 関連テスト全て PASS ### E2E テスト ```bash $ ./target/release/hakorune /tmp/test_phase231.hako 2>&1 | grep phase231 [pattern2/phase231] ✓ ExprLowerer successfully validated break condition ``` テストプログラム: ```nyash static box Phase231Test { main() { local i = 0 local sum = 0 loop(i < 10) { if i >= 5 { break } sum = sum + i i = i + 1 } return sum // RC: 0(正常動作) } } ``` ## ファイル変更 ### 新規ファイル(2ファイル) 1. `src/mir/join_ir/lowering/scope_manager.rs`(280 lines) - ScopeManager trait - Pattern2ScopeManager 実装 - VarScopeKind enum - 4 unit tests 2. `src/mir/join_ir/lowering/expr_lowerer.rs`(455 lines) - ExprLowerer struct - ExprContext / ExprLoweringError enum - 3 unit tests ### 変更ファイル(3ファイル) 1. `src/mir/join_ir/lowering/mod.rs`(+2 lines) - scope_manager, expr_lowerer モジュール追加 2. `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`(+36 lines) - ExprLowerer pre-validation 追加 3. `docs/development/current/main/joinir-architecture-overview.md`(+20 lines) - Phase 231 実装内容を追加 ## 設計上の重要な判断 ### 1. Pre-validation アプローチ **Why**: 既存の proven lowering path を保持しつつ、新 API の検証データを収集。 **Benefits**: - 既存コードへの影響ゼロ(fallback 完備) - 段階的移行が可能(Phase 232+ で実際の lowering 置き換え) - どのパターンが動くか/動かないかのデータ収集 ### 2. ScopeManager を trait に **Why**: Pattern2 以外にも拡張しやすくするため。 **Benefits**: - Pattern1/Pattern3/Pattern4 で異なる実装を提供可能 - テスト時にモック実装が作れる - 将来の拡張(General context 対応)がしやすい ### 3. ExprLowerer は condition_lowerer を再利用 **Why**: Phase 231 は API 統一が目的、ロジック reimplementation は不要。 **Benefits**: - 実装コストが低い(thin wrapper) - 既存の proven logic を活用(品質保証済み) - ScopeManager → ConditionEnv 変換だけに集中 ## 箱化・モジュール化の原則 ### Box-First - **ScopeManager**: 変数解決を統一的に扱う trait-based "box" - **ExprLowerer**: 式 lowering を1箇所に集約(パイロット段階) ### Single Responsibility - **ScopeManager**: 変数解決のみ(AST lowering や ValueId 割り当ては別箱) - **ExprLowerer**: 式 lowering のみ(変数環境管理は ScopeManager に委譲) ### Fail-Safe - 未対応 AST ノードは明示的エラー(UnsupportedNode) - フォールバック経路を必ず用意(legacy path が処理) - 実行時エラーにしない(コンパイル時に検出) ### Testability - ScopeManager は trait なので独立してテスト可能 - ExprLowerer は MirBuilder に依存するが、最小限の stub で動作 - 単体テストで各種エラーケースを網羅 ## 次のステップ ### Phase 232: Pattern1/Pattern3 への拡大 - Pattern1ScopeManager, Pattern3ScopeManager 実装 - loop 条件も ExprLowerer で pre-validation - データ収集: どのパターンが動くか確認 ### Phase 233: 実際の lowering 置き換え - ExprLowerer を実際の lowering path として使用 - fallback path を削除(ExprLowerer が完全に置き換え) - テスト: すべての Pattern2/Pattern1/Pattern3 で動作確認 ### Phase 234+: General context 対応 - ExprContext::General 実装 - MethodCall, NewBox, 複雑な式のサポート - 完全な式 lowering 統一 ## まとめ Phase 231 は ExprLowerer / ScopeManager アーキテクチャの実現可能性を実証した。 **成功要因**: - Pre-validation アプローチで既存コードへの影響ゼロ - ScopeManager trait で変数解決を統一的に抽象化 - Box-First / Fail-Safe 原則の徹底 **次の課題**: - Pattern1/Pattern3 への拡大(Phase 232) - 実際の lowering 置き換え(Phase 233) - General context 対応(Phase 234+) Phase 231 の成果により、Phase 230 の設計が正しいことが検証され、次のフェーズへの明確な道筋がついた。