//! Phase 31: LoopToJoinLowerer - 統一 Loop→JoinIR 変換箱 //! //! このモジュールは MIR の LoopForm を JoinIR に変換する統一インターフェースを提供する。 //! //! ## 設計思想 //! //! - **単一エントリポイント**: `LoopToJoinLowerer::lower()` ですべてのループを処理 //! - **パターン自動判定**: LoopScopeShape を解析して適切な変換を選択 //! - **既存コード再利用**: generic_case_a の `_with_scope` 関数を内部で呼び出し //! //! ## 使用例 //! //! ```ignore //! let lowerer = LoopToJoinLowerer::new(); //! let join_module = lowerer.lower(func, &loop_form, &query)?; //! ``` use crate::mir::join_ir::lowering::generic_case_a; use crate::mir::join_ir::lowering::loop_form_intake::intake_loop_form; use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape; use crate::mir::join_ir::JoinModule; use crate::mir::loop_form::LoopForm; use crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox; use crate::mir::phi_core::loop_var_classifier::LoopVarClassBox; use crate::mir::query::MirQueryBox; use crate::mir::MirFunction; /// Loop→JoinIR 変換の統一箱 /// /// Phase 31 で導入された統一インターフェース。 /// 全ての MIR LoopForm を JoinIR に正規化する。 pub struct LoopToJoinLowerer { /// デバッグモード(詳細ログ出力) debug: bool, } impl Default for LoopToJoinLowerer { fn default() -> Self { Self::new() } } impl LoopToJoinLowerer { /// 新しい LoopToJoinLowerer を作成 pub fn new() -> Self { let debug = std::env::var("NYASH_LOOPTOJOIN_DEBUG") .map(|v| v == "1") .unwrap_or(false); Self { debug } } /// MIR LoopForm を JoinIR に変換 /// /// # Arguments /// /// - `func`: MIR 関数 /// - `loop_form`: 変換対象の LoopForm /// - `func_name`: 関数名(オプション、ルーティング用) /// /// # Returns /// /// - `Some(JoinModule)`: 変換成功 /// - `None`: 変換失敗(フォールバック経路へ) pub fn lower( &self, func: &MirFunction, loop_form: &LoopForm, func_name: Option<&str>, ) -> Option { if self.debug { eprintln!( "[LoopToJoinLowerer] lower() called for {:?}", func_name.unwrap_or("") ); } // Step 1: MirQuery を構築 let query = MirQueryBox::new(func); // Step 2: 分類箱を構築(Phase 31 では空箱、将来 MIR 解析で埋める) let var_classes = LoopVarClassBox::new(); let exit_live = LoopExitLivenessBox::new(); // Step 3: LoopFormIntake を構築 let intake = intake_loop_form(loop_form, &var_classes, &query, func)?; // Step 4: LoopScopeShape を構築 let scope = LoopScopeShape::from_existing_boxes(loop_form, &intake, &var_classes, &exit_live, &query, func_name)?; if self.debug { eprintln!( "[LoopToJoinLowerer] LoopScopeShape built: pinned={:?}, carriers={:?}, exit_live={:?}", scope.pinned, scope.carriers, scope.exit_live ); } // Step 5: パターンに応じた lowering を実行 self.lower_with_scope(scope, func_name) } /// LoopScopeShape から JoinModule を生成(内部メソッド) fn lower_with_scope( &self, scope: LoopScopeShape, func_name: Option<&str>, ) -> Option { let name = func_name.unwrap_or(""); // Case A minimal targets へのディスパッチ if name.contains("skip") || name == "Main.skip/1" { if self.debug { eprintln!("[LoopToJoinLowerer] dispatching to skip_ws lowerer"); } return generic_case_a::lower_case_a_skip_ws_with_scope(scope); } if name.contains("trim") || name == "FuncScannerBox.trim/1" { if self.debug { eprintln!("[LoopToJoinLowerer] dispatching to trim lowerer"); } return generic_case_a::lower_case_a_trim_with_scope(scope); } if name.contains("append_defs") || name == "FuncScannerBox.append_defs/2" { if self.debug { eprintln!("[LoopToJoinLowerer] dispatching to append_defs lowerer"); } return generic_case_a::lower_case_a_append_defs_with_scope(scope); } if name.contains("resolve_for_source") || name == "Stage1UsingResolverBox.resolve_for_source/5" { if self.debug { eprintln!("[LoopToJoinLowerer] dispatching to stage1 lowerer"); } return generic_case_a::lower_case_a_stage1_usingresolver_with_scope(scope); } // TODO: Phase 31 Step 3 で汎用 Case A 対応 if self.debug { eprintln!( "[LoopToJoinLowerer] no matching pattern for {:?}, returning None", name ); } None } // ======================================== // Convenience methods for specific patterns // ======================================== /// Main.skip/1 専用の lowering /// /// Phase 31 Step 1 の検証用メソッド。 /// 既存の `skip_ws.rs` からの移行確認に使用。 pub fn lower_minimal_skip_ws_case_a( &self, func: &MirFunction, loop_form: &LoopForm, ) -> Option { self.lower(func, loop_form, Some("Main.skip/1")) } /// FuncScannerBox.trim/1 専用の lowering pub fn lower_minimal_trim_case_a( &self, func: &MirFunction, loop_form: &LoopForm, ) -> Option { self.lower(func, loop_form, Some("FuncScannerBox.trim/1")) } /// FuncScannerBox.append_defs/2 専用の lowering pub fn lower_minimal_append_defs_case_a( &self, func: &MirFunction, loop_form: &LoopForm, ) -> Option { self.lower(func, loop_form, Some("FuncScannerBox.append_defs/2")) } /// Stage1UsingResolverBox.resolve_for_source/5 専用の lowering pub fn lower_minimal_stage1_case_a( &self, func: &MirFunction, loop_form: &LoopForm, ) -> Option { self.lower(func, loop_form, Some("Stage1UsingResolverBox.resolve_for_source/5")) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_lowerer_creation() { let lowerer = LoopToJoinLowerer::new(); assert!(!lowerer.debug || lowerer.debug); // Just check it compiles } }