feat(joinir): Phase 33-9.1 Loop/If lowering responsibility separation
Implement clear separation between Loop and If lowering responsibilities: **Guard Implementation:** - Add is_loop_lowered_function() to identify 6 Loop-dedicated functions - Exclude Loop functions from If lowering path in try_lower_if_to_joinir() - Enforce "1 function → 1 lowering" principle **Documentation:** - Add responsibility comments to loop_to_join.rs - Add responsibility comments to if_select.rs and if_merge.rs - Update if_joinir_design.md with Phase 33-9.1 section **Testing:** - Add unit test test_is_loop_lowered_function() (PASS) - Verify no regression in existing JoinIR tests **Loop-dedicated functions (6):** - Main.skip/1 - FuncScannerBox.trim/1 - FuncScannerBox.append_defs/2 - Stage1UsingResolverBox.resolve_for_source/5 - StageBBodyExtractorBox.build_body_src/2 - StageBFuncScannerBox.scan_all_boxes/1 This prevents future conflicts when both Loop and If lowering expand. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -47,6 +47,34 @@ pub use stageb_funcscanner::lower_stageb_funcscanner_to_joinir;
|
||||
use crate::mir::join_ir::JoinInst;
|
||||
use crate::mir::{BasicBlockId, MirFunction};
|
||||
|
||||
/// Phase 33-9.1: Loop lowering対象関数の判定
|
||||
///
|
||||
/// これらの関数は Phase 32/33 で LoopToJoinLowerer によって処理されます。
|
||||
/// If lowering (Select/IfMerge) の対象から除外することで、Loop/If の責務を明確に分離します。
|
||||
///
|
||||
/// ## 対象関数(6本)
|
||||
/// - Main.skip/1: 空白スキップループ
|
||||
/// - FuncScannerBox.trim/1: 前後空白削除ループ
|
||||
/// - FuncScannerBox.append_defs/2: 配列結合ループ
|
||||
/// - Stage1UsingResolverBox.resolve_for_source/5: using解析ループ
|
||||
/// - StageBBodyExtractorBox.build_body_src/2: Stage-B本体抽出ループ
|
||||
/// - StageBFuncScannerBox.scan_all_boxes/1: Stage-B Box走査ループ
|
||||
///
|
||||
/// ## 将来の拡張
|
||||
/// NYASH_JOINIR_LOWER_GENERIC=1 で汎用 Case-A ループにも拡張可能
|
||||
pub(crate) fn is_loop_lowered_function(name: &str) -> bool {
|
||||
const LOOP_LOWERED_FUNCTIONS: &[&str] = &[
|
||||
"Main.skip/1",
|
||||
"FuncScannerBox.trim/1",
|
||||
"FuncScannerBox.append_defs/2",
|
||||
"Stage1UsingResolverBox.resolve_for_source/5",
|
||||
"StageBBodyExtractorBox.build_body_src/2",
|
||||
"StageBFuncScannerBox.scan_all_boxes/1",
|
||||
];
|
||||
|
||||
LOOP_LOWERED_FUNCTIONS.contains(&name)
|
||||
}
|
||||
|
||||
/// Phase 33-7: Try to lower if/else to JoinIR Select/IfMerge instruction
|
||||
///
|
||||
/// Scope:
|
||||
@ -73,6 +101,13 @@ pub fn try_lower_if_to_joinir(
|
||||
return None;
|
||||
}
|
||||
|
||||
// Phase 33-9.1: Loop専任関数の除外(Loop/If責務分離)
|
||||
// Loop lowering対象関数はIf loweringの対象外にすることで、
|
||||
// 1関数につき1 loweringの原則を保証します
|
||||
if is_loop_lowered_function(&func.signature.name) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Phase 33-8: デバッグログレベル取得(0-3)
|
||||
let debug_level = crate::config::env::joinir_debug_level();
|
||||
let _debug = debug || debug_level >= 1;
|
||||
@ -148,3 +183,40 @@ pub fn try_lower_if_to_joinir(
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Phase 33-9.1: is_loop_lowered_function() の動作確認
|
||||
#[test]
|
||||
fn test_is_loop_lowered_function() {
|
||||
// Loop 専任関数(6本)は true を返す
|
||||
assert!(is_loop_lowered_function("Main.skip/1"));
|
||||
assert!(is_loop_lowered_function("FuncScannerBox.trim/1"));
|
||||
assert!(is_loop_lowered_function("FuncScannerBox.append_defs/2"));
|
||||
assert!(is_loop_lowered_function(
|
||||
"Stage1UsingResolverBox.resolve_for_source/5"
|
||||
));
|
||||
assert!(is_loop_lowered_function(
|
||||
"StageBBodyExtractorBox.build_body_src/2"
|
||||
));
|
||||
assert!(is_loop_lowered_function(
|
||||
"StageBFuncScannerBox.scan_all_boxes/1"
|
||||
));
|
||||
|
||||
// If lowering 対象関数は false を返す
|
||||
assert!(!is_loop_lowered_function("IfSelectTest.simple_return/0"));
|
||||
assert!(!is_loop_lowered_function("IfMergeTest.multiple_true/0"));
|
||||
assert!(!is_loop_lowered_function(
|
||||
"JsonShapeToMap._read_value_from_pair/1"
|
||||
));
|
||||
assert!(!is_loop_lowered_function(
|
||||
"Stage1JsonScannerBox.value_start_after_key_pos/2"
|
||||
));
|
||||
|
||||
// 一般的な関数も false を返す
|
||||
assert!(!is_loop_lowered_function("SomeBox.some_method/3"));
|
||||
assert!(!is_loop_lowered_function("Main.main/0"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user