2025-12-18 04:31:41 +09:00
|
|
|
|
//! Phase 121: StepTree → JoinModule shadow lowering (if-only)
|
|
|
|
|
|
//!
|
|
|
|
|
|
//! ## Responsibility
|
|
|
|
|
|
//!
|
|
|
|
|
|
//! - Convert StepTree to JoinModule (Normalized dialect)
|
|
|
|
|
|
//! - Only for if-only patterns (no loops)
|
|
|
|
|
|
//! - Returns None for out-of-scope patterns
|
|
|
|
|
|
//! - Returns Err for patterns that should be supported but conversion failed
|
|
|
|
|
|
|
2025-12-18 08:14:49 +09:00
|
|
|
|
use crate::mir::control_tree::normalized_shadow::env_layout::{
|
|
|
|
|
|
expected_env_field_count as calc_expected_env_fields, EnvLayout,
|
|
|
|
|
|
};
|
|
|
|
|
|
use crate::mir::control_tree::normalized_shadow::if_as_last_join_k::IfAsLastJoinKLowererBox;
|
|
|
|
|
|
use crate::mir::control_tree::normalized_shadow::legacy::LegacyLowerer;
|
2025-12-18 04:31:41 +09:00
|
|
|
|
use crate::mir::control_tree::step_tree::StepTree;
|
2025-12-18 07:53:27 +09:00
|
|
|
|
use crate::mir::join_ir::lowering::carrier_info::JoinFragmentMeta;
|
2025-12-18 04:31:41 +09:00
|
|
|
|
use crate::mir::join_ir::JoinModule;
|
2025-12-18 06:45:23 +09:00
|
|
|
|
use crate::mir::ValueId; // Phase 126
|
|
|
|
|
|
use std::collections::BTreeMap; // Phase 126
|
2025-12-18 04:31:41 +09:00
|
|
|
|
|
|
|
|
|
|
use super::contracts::{check_if_only, CapabilityCheckResult};
|
|
|
|
|
|
|
|
|
|
|
|
/// Box-First: StepTree → Normalized shadow lowering
|
|
|
|
|
|
pub struct StepTreeNormalizedShadowLowererBox;
|
|
|
|
|
|
|
|
|
|
|
|
impl StepTreeNormalizedShadowLowererBox {
|
2025-12-18 07:53:27 +09:00
|
|
|
|
/// Phase 129-B: Expected env field count (writes + inputs)
|
|
|
|
|
|
pub fn expected_env_field_count(
|
|
|
|
|
|
step_tree: &StepTree,
|
|
|
|
|
|
available_inputs: &BTreeMap<String, ValueId>,
|
|
|
|
|
|
) -> usize {
|
2025-12-18 08:14:49 +09:00
|
|
|
|
calc_expected_env_fields(step_tree, available_inputs)
|
2025-12-18 07:53:27 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Phase 129-B: If-as-last shape detection (no post-if)
|
|
|
|
|
|
pub fn expects_join_k_as_last(step_tree: &StepTree) -> bool {
|
2025-12-18 08:14:49 +09:00
|
|
|
|
IfAsLastJoinKLowererBox::expects_join_k_as_last(step_tree)
|
2025-12-18 07:53:27 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 04:31:41 +09:00
|
|
|
|
/// Try to lower an if-only StepTree to normalized form
|
|
|
|
|
|
///
|
|
|
|
|
|
/// - `Ok(None)`: Out of scope (e.g., contains loops)
|
|
|
|
|
|
/// - `Ok(Some(...))`: Shadow generation succeeded
|
|
|
|
|
|
/// - `Err(...)`: Should be supported but conversion failed (internal error)
|
|
|
|
|
|
pub fn try_lower_if_only(
|
|
|
|
|
|
step_tree: &StepTree,
|
2025-12-18 06:45:23 +09:00
|
|
|
|
available_inputs: &BTreeMap<String, ValueId>,
|
2025-12-18 04:31:41 +09:00
|
|
|
|
) -> Result<Option<(JoinModule, JoinFragmentMeta)>, String> {
|
|
|
|
|
|
let capability = check_if_only(step_tree);
|
|
|
|
|
|
match capability {
|
|
|
|
|
|
CapabilityCheckResult::Supported => {
|
2025-12-18 06:45:23 +09:00
|
|
|
|
Self::lower_if_only_to_normalized(step_tree, available_inputs)
|
2025-12-18 04:31:41 +09:00
|
|
|
|
}
|
2025-12-18 08:14:49 +09:00
|
|
|
|
CapabilityCheckResult::Unsupported(_reason) => Ok(None),
|
2025-12-18 04:31:41 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 06:45:23 +09:00
|
|
|
|
/// Lower if-only StepTree to Normalized JoinModule (Phase 122-126)
|
2025-12-18 04:50:32 +09:00
|
|
|
|
fn lower_if_only_to_normalized(
|
|
|
|
|
|
step_tree: &StepTree,
|
2025-12-18 06:45:23 +09:00
|
|
|
|
available_inputs: &BTreeMap<String, ValueId>,
|
2025-12-18 05:50:09 +09:00
|
|
|
|
) -> Result<Option<(JoinModule, JoinFragmentMeta)>, String> {
|
2025-12-18 06:45:23 +09:00
|
|
|
|
// Phase 126: EnvLayout 生成(available_inputs を使用)
|
|
|
|
|
|
let env_layout = EnvLayout::from_contract(&step_tree.contract, available_inputs);
|
2025-12-18 06:30:55 +09:00
|
|
|
|
|
2025-12-18 07:53:27 +09:00
|
|
|
|
// Phase 129-B: If-as-last join_k lowering (dev-only)
|
2025-12-18 08:14:49 +09:00
|
|
|
|
if let Some((module, meta)) = IfAsLastJoinKLowererBox::lower(step_tree, &env_layout)? {
|
2025-12-18 07:53:27 +09:00
|
|
|
|
return Ok(Some((module, meta)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 08:14:49 +09:00
|
|
|
|
// Legacy path (Phase 123-128 scope)
|
|
|
|
|
|
LegacyLowerer::lower_if_only_to_normalized(step_tree, &env_layout)
|
2025-12-18 04:50:32 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 08:14:49 +09:00
|
|
|
|
/// Dev log helper for out-of-scope cases
|
2025-12-18 04:31:41 +09:00
|
|
|
|
pub fn get_status_string(step_tree: &StepTree) -> String {
|
2025-12-18 08:14:49 +09:00
|
|
|
|
format!(
|
|
|
|
|
|
"shadow=skipped signature_basis={}",
|
|
|
|
|
|
step_tree.signature_basis_string()
|
|
|
|
|
|
)
|
2025-12-18 06:30:55 +09:00
|
|
|
|
}
|
2025-12-18 04:31:41 +09:00
|
|
|
|
}
|