feat(phase31): Add LoopToJoinLowerer unified box
Phase 31 Step 1 complete: - Create src/mir/join_ir/lowering/loop_to_join.rs - Add LoopToJoinLowerer struct with lower() method - Implement lower_minimal_skip_ws_case_a() via generic_case_a - Support for trim, append_defs, stage1 patterns - Re-export from mod.rs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Submodule docs/private updated: 6932ae7857...a5a00fc717
203
src/mir/join_ir/lowering/loop_to_join.rs
Normal file
203
src/mir/join_ir/lowering/loop_to_join.rs
Normal file
@ -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<JoinModule> {
|
||||
if self.debug {
|
||||
eprintln!(
|
||||
"[LoopToJoinLowerer] lower() called for {:?}",
|
||||
func_name.unwrap_or("<unknown>")
|
||||
);
|
||||
}
|
||||
|
||||
// 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<JoinModule> {
|
||||
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<JoinModule> {
|
||||
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<JoinModule> {
|
||||
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<JoinModule> {
|
||||
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<JoinModule> {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user