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::gather_facts_step_box::GatherFactsStepBox;
|
||||
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;
|
||||
|
||||
pub(crate) struct Pattern2LoweringOrchestrator;
|
||||
@ -54,6 +55,8 @@ impl Pattern2LoweringOrchestrator {
|
||||
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 gather_facts_step_box;
|
||||
pub(crate) mod merge_step_box;
|
||||
pub(crate) mod post_loop_early_return_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