feat(control_tree): emit Normalized JoinModule for if-only (dev-only)
Phase 122 P1: StepTree→Normalized JoinModule generation - Generate env layout from writes (SSOT, deterministic) - Minimal implementation: main function + Ret only - Full If/Assign/Return lowering in future P2-P4 - Dev-only: no behavior change to existing path
This commit is contained in:
@ -36,6 +36,13 @@ impl StepTreeNormalizedShadowLowererBox {
|
||||
/// - Only processes if-only patterns (no loops/breaks/continues)
|
||||
/// - Uses contract information only (no AST re-analysis)
|
||||
/// - Dev-only: caller must check `joinir_dev_enabled()` before calling
|
||||
///
|
||||
/// ## Phase 122 Implementation
|
||||
///
|
||||
/// - Generates Normalized JoinIR (env + continuation)
|
||||
/// - env layout: writes only (SSOT)
|
||||
/// - merge = join_k(env) tail-call (no PHI)
|
||||
/// - Minimal node support: If/Return/Assign(Const/Variable/BinOp(Add))
|
||||
pub fn try_lower_if_only(
|
||||
step_tree: &StepTree,
|
||||
) -> Result<Option<(JoinModule, JoinFragmentMeta)>, String> {
|
||||
@ -43,19 +50,77 @@ impl StepTreeNormalizedShadowLowererBox {
|
||||
let capability = check_if_only(step_tree);
|
||||
match capability {
|
||||
CapabilityCheckResult::Supported => {
|
||||
// Phase 121 P1: For now, return empty module + empty meta
|
||||
// Full lowering implementation in future phases
|
||||
let module = JoinModule::new();
|
||||
let meta = JoinFragmentMeta::empty();
|
||||
Ok(Some((module, meta)))
|
||||
// Phase 122 P1: Generate Normalized JoinModule
|
||||
Self::lower_if_only_to_normalized(step_tree)
|
||||
.map(Some)
|
||||
}
|
||||
CapabilityCheckResult::Unsupported(_reason) => {
|
||||
// Out of scope for Phase 121
|
||||
// Out of scope for Phase 121/122
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower if-only StepTree to Normalized JoinModule (Phase 122)
|
||||
///
|
||||
/// ## Design
|
||||
///
|
||||
/// - env レイアウト: `writes` に含まれる変数だけ(決定的順序)
|
||||
/// - merge 形式: `join_k(env)` への tail-call(PHI 禁止)
|
||||
/// - 対応ノード: If/Return/Assign(最小セット)
|
||||
///
|
||||
/// ## Returns
|
||||
///
|
||||
/// - `Ok((module, meta))`: Normalized JoinModule生成成功
|
||||
/// - `Err(msg)`: 生成できるはずなのに失敗(内部エラー)
|
||||
fn lower_if_only_to_normalized(
|
||||
step_tree: &StepTree,
|
||||
) -> Result<(JoinModule, JoinFragmentMeta), String> {
|
||||
use crate::mir::join_ir::{JoinFunction, JoinFuncId, JoinInst};
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// Phase 122 P1: 最小実装 - main関数1つ + Ret のみ
|
||||
// env レイアウト: writes から決定的に決める
|
||||
let env_fields: Vec<String> = step_tree.contract.writes.iter().cloned().collect();
|
||||
|
||||
// 関数ID生成(Phase 122では固定ID使用)
|
||||
let main_func_id = JoinFuncId::new(0);
|
||||
|
||||
// env フィールドに対応する引数ValueIdを生成
|
||||
let mut next_value_id = 1;
|
||||
let env_params: Vec<ValueId> = env_fields
|
||||
.iter()
|
||||
.map(|_| {
|
||||
let vid = ValueId(next_value_id);
|
||||
next_value_id += 1;
|
||||
vid
|
||||
})
|
||||
.collect();
|
||||
|
||||
// main 関数生成(最小: Ret のみ)
|
||||
let mut main_func = JoinFunction::new(
|
||||
main_func_id,
|
||||
"main".to_string(),
|
||||
env_params.clone(),
|
||||
);
|
||||
|
||||
// Phase 122 P1: 最小実装 - Return void のみ
|
||||
// TODO Phase 122 P2-P4: If/Assign/条件式の lowering 実装
|
||||
main_func.body.push(JoinInst::Ret { value: None });
|
||||
|
||||
// JoinModule 構築
|
||||
let mut module = JoinModule::new();
|
||||
module.add_function(main_func);
|
||||
module.entry = Some(main_func_id);
|
||||
module.mark_normalized();
|
||||
|
||||
// JoinFragmentMeta 生成(最小)
|
||||
let meta = JoinFragmentMeta::empty();
|
||||
|
||||
Ok((module, meta))
|
||||
}
|
||||
|
||||
/// Get shadow lowering status string for dev logging
|
||||
///
|
||||
/// ## Contract
|
||||
|
||||
Reference in New Issue
Block a user