feat(joinir): route balanced depth-scan via Pattern2 policy
This commit is contained in:
@ -16,6 +16,7 @@ use crate::mir::join_ir::lowering::debug_output_box::DebugOutputBox;
|
||||
use crate::mir::join_ir::lowering::join_value_space::JoinValueSpace;
|
||||
use crate::mir::join_ir::lowering::loop_body_local_env::LoopBodyLocalEnv;
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
use crate::mir::join_ir::lowering::loop_update_analyzer::UpdateExpr;
|
||||
use crate::mir::ValueId;
|
||||
|
||||
use crate::mir::loop_pattern_detection::function_scope_capture::CapturedEnv;
|
||||
@ -78,6 +79,15 @@ pub(in crate::mir::builder) struct Pattern2Inputs {
|
||||
/// Phase 94: BodyLocalDerived recipe for P5b "ch" reassignment + escape counter.
|
||||
pub body_local_derived_recipe:
|
||||
Option<crate::mir::join_ir::lowering::common::body_local_derived_emitter::BodyLocalDerivedRecipe>,
|
||||
/// Phase 107: Balanced depth-scan (find_balanced_*) derived recipe.
|
||||
pub balanced_depth_scan_recipe:
|
||||
Option<crate::mir::join_ir::lowering::common::balanced_depth_scan_emitter::BalancedDepthScanRecipe>,
|
||||
/// Phase 107: Carrier updates override (policy SSOT).
|
||||
pub carrier_updates_override: Option<std::collections::BTreeMap<String, UpdateExpr>>,
|
||||
/// Phase 107: Post-loop early return plan for return-in-loop normalization.
|
||||
pub post_loop_early_return: Option<
|
||||
crate::mir::builder::control_flow::joinir::patterns::policies::balanced_depth_scan_policy::PostLoopEarlyReturnPlan,
|
||||
>,
|
||||
}
|
||||
|
||||
pub(crate) struct Pattern2InputsFactsBox;
|
||||
|
||||
@ -11,8 +11,37 @@ pub(crate) struct ApplyPolicyStepBox;
|
||||
|
||||
impl ApplyPolicyStepBox {
|
||||
pub(crate) fn apply(condition: &ASTNode, body: &[ASTNode], facts: Pattern2Facts) -> Result<Pattern2Inputs, String> {
|
||||
use super::super::policies::balanced_depth_scan_policy;
|
||||
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.
|
||||
if let PolicyDecision::Use(result) =
|
||||
balanced_depth_scan_policy::classify_balanced_depth_scan_array_end(condition, body)
|
||||
{
|
||||
return Ok(Pattern2Inputs {
|
||||
loop_var_name: facts.loop_var_name,
|
||||
loop_var_id: facts.loop_var_id,
|
||||
carrier_info: facts.carrier_info,
|
||||
scope: facts.scope,
|
||||
captured_env: facts.captured_env,
|
||||
join_value_space: facts.join_value_space,
|
||||
env: facts.env,
|
||||
condition_bindings: facts.condition_bindings,
|
||||
body_local_env: facts.body_local_env,
|
||||
allowed_body_locals_for_conditions: result.allowed_body_locals_for_conditions,
|
||||
read_only_body_local_slot: None,
|
||||
break_condition_node: result.break_condition_node,
|
||||
is_loop_true_read_digits: false,
|
||||
condition_only_recipe: None,
|
||||
body_local_derived_recipe: None,
|
||||
balanced_depth_scan_recipe: Some(result.derived_recipe),
|
||||
carrier_updates_override: Some(result.carrier_updates_override),
|
||||
post_loop_early_return: Some(result.post_loop_early_return),
|
||||
});
|
||||
}
|
||||
|
||||
let break_routing = Pattern2BreakConditionPolicyRouterBox::route(condition, body)?;
|
||||
|
||||
let read_only_body_local_slot = if break_routing.allowed_body_locals_for_conditions.is_empty() {
|
||||
@ -40,7 +69,9 @@ impl ApplyPolicyStepBox {
|
||||
is_loop_true_read_digits: break_routing.is_loop_true_read_digits,
|
||||
condition_only_recipe: None,
|
||||
body_local_derived_recipe: None,
|
||||
balanced_depth_scan_recipe: None,
|
||||
carrier_updates_override: None,
|
||||
post_loop_early_return: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -83,8 +83,11 @@ impl PromoteStepBox {
|
||||
}
|
||||
|
||||
use crate::mir::join_ir::lowering::loop_update_analyzer::LoopUpdateAnalyzer;
|
||||
let carrier_updates =
|
||||
LoopUpdateAnalyzer::analyze_carrier_updates(analysis_body, &inputs.carrier_info.carriers);
|
||||
let carrier_updates = if let Some(override_map) = inputs.carrier_updates_override.take() {
|
||||
override_map
|
||||
} else {
|
||||
LoopUpdateAnalyzer::analyze_carrier_updates(analysis_body, &inputs.carrier_info.carriers)
|
||||
};
|
||||
Pattern2DebugLog::new(verbose).log(
|
||||
"updates",
|
||||
format!("Phase 176-3: Analyzed {} carrier updates", carrier_updates.len()),
|
||||
|
||||
@ -17,8 +17,20 @@ 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::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.
|
||||
if matches!(
|
||||
classify_balanced_depth_scan_array_end(condition, body),
|
||||
PolicyDecision::Use(_)
|
||||
) {
|
||||
return loop_pattern_detection::LoopPatternKind::Pattern2Break;
|
||||
}
|
||||
|
||||
// Phase 193: Use AST Feature Extractor Box for break/continue detection
|
||||
let has_continue = ast_features::detect_continue_in_body(body);
|
||||
let has_break = ast_features::detect_break_in_body(body);
|
||||
|
||||
Reference in New Issue
Block a user