diff --git a/docs/private b/docs/private index 6932ae78..a5a00fc7 160000 --- a/docs/private +++ b/docs/private @@ -1 +1 @@ -Subproject commit 6932ae78573177d67ea1266199bf089da4ff3f5c +Subproject commit a5a00fc717f1f0ee348a867a6d873072400070b4 diff --git a/src/mir/join_ir/lowering/loop_to_join.rs b/src/mir/join_ir/lowering/loop_to_join.rs new file mode 100644 index 00000000..24c3f481 --- /dev/null +++ b/src/mir/join_ir/lowering/loop_to_join.rs @@ -0,0 +1,203 @@ +//! 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 + } +} diff --git a/src/mir/join_ir/lowering/mod.rs b/src/mir/join_ir/lowering/mod.rs index d9232970..1b5f975c 100644 --- a/src/mir/join_ir/lowering/mod.rs +++ b/src/mir/join_ir/lowering/mod.rs @@ -20,6 +20,7 @@ pub mod funcscanner_trim; pub mod generic_case_a; pub mod loop_form_intake; pub mod loop_scope_shape; +pub mod loop_to_join; pub mod min_loop; pub mod skip_ws; pub mod stage1_using_resolver; @@ -30,6 +31,8 @@ pub mod value_id_ranges; // Re-export public lowering functions pub use funcscanner_append_defs::lower_funcscanner_append_defs_to_joinir; pub use funcscanner_trim::lower_funcscanner_trim_to_joinir; +// Phase 31: LoopToJoinLowerer 統一箱 +pub use loop_to_join::LoopToJoinLowerer; // Phase 30 F-3: 旧 lower_case_a_loop_to_joinir_for_minimal_skip_ws は _with_scope に置き換え済みのため削除 pub use min_loop::lower_min_loop_to_joinir; pub use skip_ws::lower_skip_ws_to_joinir;