diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/apply_policy_step_box.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/apply_policy_step_box.rs index 9bf3a809..2a8cf29f 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/apply_policy_step_box.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/apply_policy_step_box.rs @@ -11,24 +11,13 @@ pub(crate) struct ApplyPolicyStepBox; impl ApplyPolicyStepBox { pub(crate) fn apply(condition: &ASTNode, body: &[ASTNode], facts: Pattern2Facts) -> Result { - use super::super::policies::balanced_depth_scan_policy; + use super::super::policies::balanced_depth_scan_policy_box::BalancedDepthScanPolicyBox; use super::super::policies::PolicyDecision; use crate::mir::join_ir::lowering::common::body_local_slot::ReadOnlyBodyLocalSlotBox; // Phase 107: balanced depth-scan (return-in-loop) policy. // This route provides its own break-cond + derived recipe + post-loop early return plan. - let decision = balanced_depth_scan_policy::classify_balanced_depth_scan_array_end(condition, body); - if crate::config::env::joinir_dev_enabled() { - use crate::mir::builder::control_flow::joinir::trace; - let summary = match &decision { - PolicyDecision::Use(_) => "Use".to_string(), - PolicyDecision::Reject(reason) => format!("Reject: {}", reason), - PolicyDecision::None => "None".to_string(), - }; - trace::trace().dev("phase107/balanced_depth_scan_policy", &summary); - } - - match decision { + match BalancedDepthScanPolicyBox::decide(condition, body) { PolicyDecision::Use(result) => { return Ok(Pattern2Inputs { loop_var_name: facts.loop_var_name, diff --git a/src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy_box.rs b/src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy_box.rs new file mode 100644 index 00000000..c8fc4ee0 --- /dev/null +++ b/src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy_box.rs @@ -0,0 +1,34 @@ +//! BalancedDepthScanPolicyBox (Phase 107) +//! +//! Responsibility: +//! - Provide a single SSOT entry point for the balanced depth-scan policy decision +//! so callers (routing/apply) don't duplicate Use/Reject/None handling. + +use crate::ast::ASTNode; + +use super::balanced_depth_scan_policy::{classify_balanced_depth_scan_array_end, BalancedDepthScanPolicyResult}; +use super::PolicyDecision; + +pub(crate) struct BalancedDepthScanPolicyBox; + +impl BalancedDepthScanPolicyBox { + pub(crate) fn decide( + condition: &ASTNode, + body: &[ASTNode], + ) -> PolicyDecision { + let decision = classify_balanced_depth_scan_array_end(condition, body); + + if crate::config::env::joinir_dev_enabled() { + use crate::mir::builder::control_flow::joinir::trace; + let summary = match &decision { + PolicyDecision::Use(_) => "Use".to_string(), + PolicyDecision::Reject(reason) => format!("Reject: {}", reason), + PolicyDecision::None => "None".to_string(), + }; + trace::trace().dev("phase107/balanced_depth_scan_policy", &summary); + } + + decision + } +} + diff --git a/src/mir/builder/control_flow/joinir/patterns/policies/mod.rs b/src/mir/builder/control_flow/joinir/patterns/policies/mod.rs index 89674244..9e0144ec 100644 --- a/src/mir/builder/control_flow/joinir/patterns/policies/mod.rs +++ b/src/mir/builder/control_flow/joinir/patterns/policies/mod.rs @@ -34,3 +34,4 @@ pub(in crate::mir::builder) mod p5b_escape_derived_policy; pub(in crate::mir::builder) mod trim_policy; pub(in crate::mir::builder) mod loop_true_read_digits_policy; pub(in crate::mir::builder) mod balanced_depth_scan_policy; +pub(in crate::mir::builder) mod balanced_depth_scan_policy_box; diff --git a/src/mir/builder/control_flow/joinir/routing.rs b/src/mir/builder/control_flow/joinir/routing.rs index 741ac361..cb1136f2 100644 --- a/src/mir/builder/control_flow/joinir/routing.rs +++ b/src/mir/builder/control_flow/joinir/routing.rs @@ -17,14 +17,14 @@ pub(in crate::mir::builder) fn choose_pattern_kind( body: &[ASTNode], ) -> crate::mir::loop_pattern_detection::LoopPatternKind { use crate::mir::builder::control_flow::joinir::patterns::ast_feature_extractor as ast_features; - use crate::mir::builder::control_flow::joinir::patterns::policies::balanced_depth_scan_policy::classify_balanced_depth_scan_array_end; + use crate::mir::builder::control_flow::joinir::patterns::policies::balanced_depth_scan_policy_box::BalancedDepthScanPolicyBox; use crate::mir::builder::control_flow::joinir::patterns::policies::PolicyDecision; use crate::mir::loop_pattern_detection; // Phase 107: Route balanced depth-scan (return-in-loop) to Pattern2 via policy. // // This keeps Pattern routing structural: no by-name dispatch, no silent fallback. - match classify_balanced_depth_scan_array_end(condition, body) { + match BalancedDepthScanPolicyBox::decide(condition, body) { PolicyDecision::Use(_) => { return loop_pattern_detection::LoopPatternKind::Pattern2Break; }