feat(joinir): add Pattern2 post-loop early return step
This commit is contained in:
@ -11,6 +11,7 @@ use super::pattern2_steps::apply_policy_step_box::ApplyPolicyStepBox;
|
|||||||
use super::pattern2_steps::emit_joinir_step_box::EmitJoinIRStepBox;
|
use super::pattern2_steps::emit_joinir_step_box::EmitJoinIRStepBox;
|
||||||
use super::pattern2_steps::gather_facts_step_box::GatherFactsStepBox;
|
use super::pattern2_steps::gather_facts_step_box::GatherFactsStepBox;
|
||||||
use super::pattern2_steps::merge_step_box::MergeStepBox;
|
use super::pattern2_steps::merge_step_box::MergeStepBox;
|
||||||
|
use super::pattern2_steps::post_loop_early_return_step_box::PostLoopEarlyReturnStepBox;
|
||||||
use super::pattern2_steps::promote_step_box::PromoteStepBox;
|
use super::pattern2_steps::promote_step_box::PromoteStepBox;
|
||||||
|
|
||||||
pub(crate) struct Pattern2LoweringOrchestrator;
|
pub(crate) struct Pattern2LoweringOrchestrator;
|
||||||
@ -54,6 +55,8 @@ impl Pattern2LoweringOrchestrator {
|
|||||||
skeleton,
|
skeleton,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
MergeStepBox::merge(builder, emitted.join_module, emitted.boundary, debug)
|
let out = MergeStepBox::merge(builder, emitted.join_module, emitted.boundary, debug)?;
|
||||||
|
PostLoopEarlyReturnStepBox::maybe_emit(builder, promoted.inputs.post_loop_early_return.as_ref())?;
|
||||||
|
Ok(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,5 +10,5 @@ pub(crate) mod apply_policy_step_box;
|
|||||||
pub(crate) mod emit_joinir_step_box;
|
pub(crate) mod emit_joinir_step_box;
|
||||||
pub(crate) mod gather_facts_step_box;
|
pub(crate) mod gather_facts_step_box;
|
||||||
pub(crate) mod merge_step_box;
|
pub(crate) mod merge_step_box;
|
||||||
|
pub(crate) mod post_loop_early_return_step_box;
|
||||||
pub(crate) mod promote_step_box;
|
pub(crate) mod promote_step_box;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
//! PostLoopEarlyReturnStepBox (Phase 107)
|
||||||
|
//!
|
||||||
|
//! Responsibility: emulate `return i` inside the loop by emitting a post-loop
|
||||||
|
//! early-return guard. This keeps JoinIR lowering "break-only" while preserving
|
||||||
|
//! source semantics for the recognized family.
|
||||||
|
|
||||||
|
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||||
|
use crate::mir::builder::MirBuilder;
|
||||||
|
|
||||||
|
pub(crate) struct PostLoopEarlyReturnStepBox;
|
||||||
|
|
||||||
|
impl PostLoopEarlyReturnStepBox {
|
||||||
|
pub(crate) fn maybe_emit(
|
||||||
|
builder: &mut MirBuilder,
|
||||||
|
plan: Option<
|
||||||
|
&crate::mir::builder::control_flow::joinir::patterns::policies::balanced_depth_scan_policy::PostLoopEarlyReturnPlan,
|
||||||
|
>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let Some(plan) = plan else { return Ok(()); };
|
||||||
|
|
||||||
|
// if i < n { return i }
|
||||||
|
let cond = ASTNode::BinaryOp {
|
||||||
|
operator: BinaryOperator::Less,
|
||||||
|
left: Box::new(ASTNode::Variable {
|
||||||
|
name: plan.loop_counter_name.clone(),
|
||||||
|
span: Span::unknown(),
|
||||||
|
}),
|
||||||
|
right: Box::new(ASTNode::Variable {
|
||||||
|
name: plan.bound_name.clone(),
|
||||||
|
span: Span::unknown(),
|
||||||
|
}),
|
||||||
|
span: Span::unknown(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ret_stmt = ASTNode::Return {
|
||||||
|
value: Some(Box::new(ASTNode::Variable {
|
||||||
|
name: plan.loop_counter_name.clone(),
|
||||||
|
span: Span::unknown(),
|
||||||
|
})),
|
||||||
|
span: Span::unknown(),
|
||||||
|
};
|
||||||
|
|
||||||
|
builder.build_statement(ASTNode::If {
|
||||||
|
condition: Box::new(cond),
|
||||||
|
then_body: vec![ret_stmt],
|
||||||
|
else_body: None,
|
||||||
|
span: Span::unknown(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user