phase29ao(p27): strict/dev adopt pattern6 scan_with_init subset from facts

This commit is contained in:
2025-12-30 13:41:18 +09:00
parent d9afc803ef
commit bbd1194a26
7 changed files with 74 additions and 13 deletions

View File

@ -379,6 +379,29 @@ pub(crate) fn route_loop_pattern(
return PlanLowerer::lower(builder, core_plan, ctx);
}
if strict_or_dev
&& matches!(
domain_plan,
crate::mir::builder::control_flow::plan::DomainPlan::ScanWithInit(_)
)
&& matches!(
outcome.plan.as_ref(),
Some(crate::mir::builder::control_flow::plan::DomainPlan::ScanWithInit(_))
)
{
let facts = outcome
.facts
.as_ref()
.ok_or_else(|| "pattern6 strict/dev adopt failed: facts missing".to_string())?;
if facts.facts.scan_with_init.is_none() {
return Err("pattern6 strict/dev adopt failed: facts mismatch".to_string());
}
let core_plan = PlanNormalizer::normalize_scan_with_init_from_facts(builder, facts, ctx)?
.ok_or_else(|| "pattern6 strict/dev adopt failed: compose rejected".to_string())?;
PlanVerifier::verify(&core_plan)?;
return PlanLowerer::lower(builder, core_plan, ctx);
}
if strict_or_dev
&& matches!(
domain_plan,

View File

@ -1,14 +1,31 @@
use super::{CoreEffectPlan, CoreLoopPlan, CorePhiInfo, CorePlan, ScanWithInitPlan};
use crate::ast::{ASTNode, Span};
use crate::mir::builder::control_flow::plan::ScanDirection;
use crate::mir::basic_block::EdgeArgs;
use crate::mir::builder::control_flow::edgecfg::api::{BranchStub, EdgeStub, ExitKind, Frag};
use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternContext;
use crate::mir::builder::control_flow::plan::facts::loop_facts::ScanWithInitFacts;
use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
use crate::mir::builder::MirBuilder;
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
use crate::mir::{BinaryOp, CompareOp, ConstValue, Effect, EffectMask, MirType};
use std::collections::BTreeMap;
impl super::PlanNormalizer {
pub(in crate::mir::builder) fn normalize_scan_with_init_from_facts(
builder: &mut MirBuilder,
facts: &CanonicalLoopFacts,
ctx: &LoopPatternContext,
) -> Result<Option<CorePlan>, String> {
let Some(scan) = facts.facts.scan_with_init.as_ref() else {
return Ok(None);
};
let parts = plan_from_facts(scan);
let core_plan = Self::normalize_scan_with_init(builder, parts, ctx)?;
Ok(Some(core_plan))
}
/// ScanWithInit → CorePlan 変換
///
/// Expands scan-specific semantics into generic CorePlan:
@ -384,3 +401,19 @@ impl super::PlanNormalizer {
Ok(CorePlan::Loop(loop_plan))
}
}
fn plan_from_facts(facts: &ScanWithInitFacts) -> ScanWithInitPlan {
ScanWithInitPlan {
loop_var: facts.loop_var.clone(),
haystack: facts.haystack.clone(),
needle: facts.needle.clone(),
step_lit: facts.step_lit,
early_return_expr: ASTNode::Variable {
name: facts.loop_var.clone(),
span: Span::unknown(),
},
not_found_return_lit: -1,
scan_direction: ScanDirection::Forward,
dynamic_needle: false,
}
}