refactor: Extract append_defs and stage1 lowerers (Phase 4)
- Created append_defs.rs with lower_case_a_append_defs_with_scope() - Extracted 173 lines of append_defs lowering logic - Implements array concatenation loop (ArrayBox.get/push) - ValueId allocation: entry(8000-8999), loop_step(9000-9999) - Created stage1_using_resolver.rs with lower_case_a_stage1_usingresolver_with_scope() - Extracted 185 lines of stage1 using resolver logic - Implements namespace resolution loop with OR accumulation - ValueId allocation: entry(10000-10999), loop_step(11000-11999) Both modules use EntryFunctionBuilder helper for boilerplate initialization. Sizes: append_defs (173 lines), stage1 (185 lines) Ref: Phase 192 modularization effort
This commit is contained in:
202
src/mir/join_ir/lowering/generic_case_a/append_defs.rs
Normal file
202
src/mir/join_ir/lowering/generic_case_a/append_defs.rs
Normal file
@ -0,0 +1,202 @@
|
||||
//! Array Append Loop Lowering (Case A)
|
||||
//!
|
||||
//! Phase 192: Extracted from generic_case_a.rs monolith.
|
||||
//!
|
||||
//! ## Responsibility
|
||||
//!
|
||||
//! Lowers FuncScannerBox.append_defs/2 array concatenation loop to JoinIR.
|
||||
//!
|
||||
//! ## Pattern Structure
|
||||
//!
|
||||
//! ```text
|
||||
//! entry: append_defs_entry(dst, defs_box, n)
|
||||
//! i = 0
|
||||
//! call loop_step(dst, defs_box, n, i)
|
||||
//!
|
||||
//! loop_step(dst, defs_box, n, i):
|
||||
//! if i >= n { return } // Exit condition
|
||||
//! item = defs_box.get(i)
|
||||
//! dst.push(item) // Append item to dst
|
||||
//! continue loop_step(dst, defs_box, n, i+1)
|
||||
//! ```
|
||||
//!
|
||||
//! ## ValueId Allocation
|
||||
//!
|
||||
//! - Entry range: 8000-8999 (`value_id_ranges::funcscanner_append_defs::entry`)
|
||||
//! - Loop range: 9000-9999 (`value_id_ranges::funcscanner_append_defs::loop_step`)
|
||||
//!
|
||||
//! ## See Also
|
||||
//!
|
||||
//! - `value_id_ranges::funcscanner_append_defs` - ValueId allocation strategy
|
||||
//! - `loop_scope_shape::CaseAContext` - Context extraction
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::CaseAContext;
|
||||
use crate::mir::join_ir::lowering::value_id_ranges;
|
||||
use crate::mir::join_ir::{
|
||||
BinOpKind, CompareOp, ConstValue, JoinContId, JoinFuncId, JoinFunction, JoinInst, JoinModule,
|
||||
LoopExitShape, LoopHeaderShape, MirLikeInst,
|
||||
};
|
||||
use crate::mir::ValueId;
|
||||
|
||||
use super::entry_builder::EntryFunctionBuilder;
|
||||
|
||||
/// Phase 30 F-3.0.4: LoopScopeShape を直接受け取る append_defs lowerer
|
||||
///
|
||||
/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。
|
||||
/// CaseAContext::from_scope() 経由で ctx を作成。
|
||||
pub(crate) fn lower_case_a_append_defs_with_scope(
|
||||
scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape,
|
||||
) -> Option<JoinModule> {
|
||||
let ctx = CaseAContext::from_scope(scope, "append_defs", |offset| {
|
||||
value_id_ranges::funcscanner_append_defs::loop_step(offset)
|
||||
})?;
|
||||
lower_case_a_append_defs_core(&ctx)
|
||||
}
|
||||
|
||||
/// append_defs JoinModule 構築のコア実装
|
||||
///
|
||||
/// CaseAContext から JoinModule を構築する共通ロジック。
|
||||
/// `_for_append_defs_minimal` と `_with_scope` の両方から呼ばれる。
|
||||
fn lower_case_a_append_defs_core(ctx: &CaseAContext) -> Option<JoinModule> {
|
||||
let dst_key = ctx.pinned_name_or_first(0)?;
|
||||
let defs_key = ctx
|
||||
.pinned_name_or_first(1)
|
||||
.unwrap_or_else(|| dst_key.clone());
|
||||
let n_key = ctx
|
||||
.pinned_name_or_first(2)
|
||||
.unwrap_or_else(|| defs_key.clone());
|
||||
let i_key = ctx.carrier_name_or_first(0)?;
|
||||
|
||||
let dst_loop = ctx.get_loop_id(&dst_key)?;
|
||||
let defs_loop = ctx.get_loop_id(&defs_key)?;
|
||||
let n_loop = ctx.get_loop_id(&n_key)?;
|
||||
let i_loop = ctx.get_loop_id(&i_key)?;
|
||||
|
||||
let mut join_module = JoinModule::new();
|
||||
|
||||
// entry: append_defs_entry(dst, defs_box, n)
|
||||
let entry_id = JoinFuncId::new(0);
|
||||
let dst_param = value_id_ranges::funcscanner_append_defs::entry(0);
|
||||
let defs_box_param = value_id_ranges::funcscanner_append_defs::entry(1);
|
||||
let n_param = value_id_ranges::funcscanner_append_defs::entry(2);
|
||||
let mut entry_func = JoinFunction::new(
|
||||
entry_id,
|
||||
"append_defs_entry".to_string(),
|
||||
vec![dst_param, defs_box_param, n_param],
|
||||
);
|
||||
|
||||
let i_init = value_id_ranges::funcscanner_append_defs::entry(10);
|
||||
entry_func.body.push(JoinInst::Compute(MirLikeInst::Const {
|
||||
dst: i_init,
|
||||
value: ConstValue::Integer(0),
|
||||
}));
|
||||
// Phase 192: Use EntryFunctionBuilder for boilerplate initialization
|
||||
let mut entry_builder = EntryFunctionBuilder::new();
|
||||
entry_builder.add_var("s".to_string(), dst_param); // intake で param0 を "s" にするため
|
||||
entry_builder.add_var("dst".to_string(), dst_param);
|
||||
entry_builder.add_var("param1".to_string(), defs_box_param);
|
||||
entry_builder.add_var("defs_box".to_string(), defs_box_param);
|
||||
entry_builder.add_var("n".to_string(), n_param);
|
||||
entry_builder.add_var("i".to_string(), i_init);
|
||||
let entry_name_to_id = entry_builder.get_map().clone();
|
||||
|
||||
let loop_call_args: Vec<ValueId> = ctx
|
||||
.ordered_pinned
|
||||
.iter()
|
||||
.chain(ctx.ordered_carriers.iter())
|
||||
.map(|name| entry_name_to_id.get(name).copied())
|
||||
.collect::<Option<_>>()?;
|
||||
|
||||
let loop_step_id = JoinFuncId::new(1);
|
||||
entry_func.body.push(JoinInst::Call {
|
||||
func: loop_step_id,
|
||||
args: loop_call_args,
|
||||
k_next: None,
|
||||
dst: None,
|
||||
});
|
||||
|
||||
join_module.entry = Some(entry_id);
|
||||
join_module.add_function(entry_func);
|
||||
|
||||
// loop_step(dst, defs_box, n, i)
|
||||
let header_shape = LoopHeaderShape::new_manual(ctx.pinned_ids.clone(), ctx.carrier_ids.clone());
|
||||
let loop_params = header_shape.to_loop_step_params();
|
||||
let mut loop_step_func =
|
||||
JoinFunction::new(loop_step_id, "loop_step".to_string(), loop_params.clone());
|
||||
|
||||
let cmp_result = value_id_ranges::funcscanner_append_defs::loop_step(10);
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::Compare {
|
||||
dst: cmp_result,
|
||||
op: CompareOp::Ge,
|
||||
lhs: i_loop,
|
||||
rhs: n_loop,
|
||||
}));
|
||||
|
||||
let _exit_shape = LoopExitShape::new_manual(ctx.exit_args.clone());
|
||||
|
||||
loop_step_func.body.push(JoinInst::Jump {
|
||||
cont: JoinContId::new(0),
|
||||
args: ctx.exit_args.clone(),
|
||||
cond: Some(cmp_result),
|
||||
});
|
||||
|
||||
let item_value = value_id_ranges::funcscanner_append_defs::loop_step(11);
|
||||
let next_i = value_id_ranges::funcscanner_append_defs::loop_step(12);
|
||||
let const_1 = value_id_ranges::funcscanner_append_defs::loop_step(13);
|
||||
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BoxCall {
|
||||
dst: Some(item_value),
|
||||
box_name: "ArrayBox".to_string(),
|
||||
method: "get".to_string(),
|
||||
args: vec![defs_loop, i_loop],
|
||||
}));
|
||||
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BoxCall {
|
||||
dst: None,
|
||||
box_name: "ArrayBox".to_string(),
|
||||
method: "push".to_string(),
|
||||
args: vec![dst_loop, item_value],
|
||||
}));
|
||||
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::Const {
|
||||
dst: const_1,
|
||||
value: ConstValue::Integer(1),
|
||||
}));
|
||||
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BinOp {
|
||||
dst: next_i,
|
||||
op: BinOpKind::Add,
|
||||
lhs: i_loop,
|
||||
rhs: const_1,
|
||||
}));
|
||||
|
||||
loop_step_func.body.push(JoinInst::Call {
|
||||
func: loop_step_id,
|
||||
args: vec![dst_loop, defs_loop, n_loop, next_i],
|
||||
k_next: None,
|
||||
dst: None,
|
||||
});
|
||||
|
||||
join_module.add_function(loop_step_func);
|
||||
|
||||
eprintln!(
|
||||
"[joinir/generic_case_a/append_defs] ✅ constructed JoinIR (functions={}, value_range={}..{})",
|
||||
join_module.functions.len(),
|
||||
value_id_ranges::base::FUNCSCANNER_APPEND_DEFS,
|
||||
value_id_ranges::base::FUNCSCANNER_APPEND_DEFS + 1999
|
||||
);
|
||||
|
||||
Some(join_module)
|
||||
}
|
||||
228
src/mir/join_ir/lowering/generic_case_a/stage1_using_resolver.rs
Normal file
228
src/mir/join_ir/lowering/generic_case_a/stage1_using_resolver.rs
Normal file
@ -0,0 +1,228 @@
|
||||
//! Stage-1 Using Resolver Loop Lowering (Case A)
|
||||
//!
|
||||
//! Phase 192: Extracted from generic_case_a.rs monolith.
|
||||
//!
|
||||
//! ## Responsibility
|
||||
//!
|
||||
//! Lowers Stage1UsingResolverBox.resolve_for_source/5 using namespace resolution loop to JoinIR.
|
||||
//!
|
||||
//! ## Pattern Structure
|
||||
//!
|
||||
//! ```text
|
||||
//! entry: resolve_entries(entries, n, modules, seen, prefix_init)
|
||||
//! i = 0
|
||||
//! call loop_step(entries, n, modules, seen, prefix_init, i)
|
||||
//!
|
||||
//! loop_step(entries, n, modules, seen, prefix, i):
|
||||
//! if i >= n { return prefix } // Exit condition
|
||||
//! entry = entries.get(i)
|
||||
//! new_prefix = prefix | entry // OR operation (accumulate)
|
||||
//! continue loop_step(entries, n, modules, seen, new_prefix, i+1)
|
||||
//! ```
|
||||
//!
|
||||
//! ## ValueId Allocation
|
||||
//!
|
||||
//! - Entry range: 10000-10999 (`value_id_ranges::stage1_using_resolver::entry`)
|
||||
//! - Loop range: 11000-11999 (`value_id_ranges::stage1_using_resolver::loop_step`)
|
||||
//!
|
||||
//! ## See Also
|
||||
//!
|
||||
//! - `value_id_ranges::stage1_using_resolver` - ValueId allocation strategy
|
||||
//! - `loop_scope_shape::CaseAContext` - Context extraction
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::CaseAContext;
|
||||
use crate::mir::join_ir::lowering::value_id_ranges;
|
||||
use crate::mir::join_ir::lowering::value_id_ranges::stage1_using_resolver as stage1_vid;
|
||||
use crate::mir::join_ir::{
|
||||
BinOpKind, CompareOp, ConstValue, JoinContId, JoinFuncId, JoinFunction, JoinInst, JoinModule,
|
||||
LoopExitShape, LoopHeaderShape, MirLikeInst,
|
||||
};
|
||||
use crate::mir::ValueId;
|
||||
|
||||
use super::entry_builder::EntryFunctionBuilder;
|
||||
|
||||
/// Phase 30 F-3.0.5: LoopScopeShape を直接受け取る Stage-1 UsingResolver lowerer
|
||||
///
|
||||
/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。
|
||||
/// CaseAContext::from_scope() 経由で ctx を作成。
|
||||
pub(crate) fn lower_case_a_stage1_usingresolver_with_scope(
|
||||
scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape,
|
||||
) -> Option<JoinModule> {
|
||||
let ctx = CaseAContext::from_scope(scope, "stage1", |offset| stage1_vid::loop_step(offset))?;
|
||||
lower_case_a_stage1_usingresolver_core(&ctx)
|
||||
}
|
||||
|
||||
/// Stage-1 UsingResolver JoinModule 構築のコア実装
|
||||
///
|
||||
/// CaseAContext から JoinModule を構築する共通ロジック。
|
||||
/// `_for_stage1_usingresolver_minimal` と `_with_scope` の両方から呼ばれる。
|
||||
fn lower_case_a_stage1_usingresolver_core(ctx: &CaseAContext) -> Option<JoinModule> {
|
||||
let entries_key = ctx.pinned_name_or_first(0)?;
|
||||
let n_key = ctx
|
||||
.pinned_name_or_first(1)
|
||||
.unwrap_or_else(|| entries_key.clone());
|
||||
let modules_key = ctx
|
||||
.pinned_name_or_first(2)
|
||||
.unwrap_or_else(|| entries_key.clone());
|
||||
let seen_key = ctx
|
||||
.pinned_name_or_first(3)
|
||||
.unwrap_or_else(|| entries_key.clone());
|
||||
let prefix_key = ctx.carrier_name_or_first(0)?;
|
||||
let i_key = ctx
|
||||
.carrier_name_or_first(1)
|
||||
.unwrap_or_else(|| prefix_key.clone());
|
||||
|
||||
let entries_loop = ctx.get_loop_id(&entries_key)?;
|
||||
let n_loop = ctx.get_loop_id(&n_key)?;
|
||||
let modules_loop = ctx.get_loop_id(&modules_key)?;
|
||||
let seen_loop = ctx.get_loop_id(&seen_key)?;
|
||||
let prefix_loop = ctx.get_loop_id(&prefix_key)?;
|
||||
let i_loop = ctx.get_loop_id(&i_key)?;
|
||||
|
||||
let mut join_module = JoinModule::new();
|
||||
|
||||
// entry: resolve_entries(entries, n, modules, seen, prefix_init)
|
||||
let resolve_id = JoinFuncId::new(0);
|
||||
let entries_param = stage1_vid::entry(0);
|
||||
let n_param = stage1_vid::entry(1);
|
||||
let modules_param = stage1_vid::entry(2);
|
||||
let seen_param = stage1_vid::entry(3);
|
||||
let prefix_param = stage1_vid::entry(4);
|
||||
let mut resolve_func = JoinFunction::new(
|
||||
resolve_id,
|
||||
"resolve_entries".to_string(),
|
||||
vec![
|
||||
entries_param,
|
||||
n_param,
|
||||
modules_param,
|
||||
seen_param,
|
||||
prefix_param,
|
||||
],
|
||||
);
|
||||
|
||||
let i_init = stage1_vid::entry(10);
|
||||
resolve_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::Const {
|
||||
dst: i_init,
|
||||
value: ConstValue::Integer(0),
|
||||
}));
|
||||
|
||||
// Phase 192: Use EntryFunctionBuilder for boilerplate initialization
|
||||
let mut entry_builder = EntryFunctionBuilder::new();
|
||||
entry_builder.add_var(entries_key.clone(), entries_param);
|
||||
entry_builder.add_var(n_key.clone(), n_param);
|
||||
entry_builder.add_var(modules_key.clone(), modules_param);
|
||||
entry_builder.add_var(seen_key.clone(), seen_param);
|
||||
entry_builder.add_var(prefix_key.clone(), prefix_param);
|
||||
entry_builder.add_var(i_key.clone(), i_init);
|
||||
let entry_name_to_id = entry_builder.get_map().clone();
|
||||
|
||||
let loop_call_args: Vec<ValueId> = ctx
|
||||
.ordered_pinned
|
||||
.iter()
|
||||
.chain(ctx.ordered_carriers.iter())
|
||||
.map(|name| entry_name_to_id.get(name).copied())
|
||||
.collect::<Option<_>>()?;
|
||||
|
||||
let loop_step_id = JoinFuncId::new(1);
|
||||
resolve_func.body.push(JoinInst::Call {
|
||||
func: loop_step_id,
|
||||
args: loop_call_args,
|
||||
k_next: None,
|
||||
dst: None,
|
||||
});
|
||||
|
||||
join_module.entry = Some(resolve_id);
|
||||
join_module.add_function(resolve_func);
|
||||
|
||||
// loop_step(entries, n, modules, seen, prefix, i)
|
||||
let header_shape = LoopHeaderShape::new_manual(ctx.pinned_ids.clone(), ctx.carrier_ids.clone());
|
||||
let loop_params = header_shape.to_loop_step_params();
|
||||
let mut loop_step_func =
|
||||
JoinFunction::new(loop_step_id, "loop_step".to_string(), loop_params.clone());
|
||||
|
||||
let cmp_result = stage1_vid::loop_step(10);
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::Compare {
|
||||
dst: cmp_result,
|
||||
op: CompareOp::Ge,
|
||||
lhs: i_loop,
|
||||
rhs: n_loop,
|
||||
}));
|
||||
|
||||
let exit_shape = if ctx.exit_args.is_empty() {
|
||||
LoopExitShape::new_manual(vec![prefix_loop])
|
||||
} else {
|
||||
LoopExitShape::new_manual(ctx.exit_args.clone())
|
||||
};
|
||||
|
||||
loop_step_func.body.push(JoinInst::Jump {
|
||||
cont: JoinContId::new(0),
|
||||
args: exit_shape.exit_args.clone(),
|
||||
cond: Some(cmp_result),
|
||||
});
|
||||
|
||||
let entry_value = stage1_vid::loop_step(11);
|
||||
let next_i = stage1_vid::loop_step(12);
|
||||
let const_1 = stage1_vid::loop_step(13);
|
||||
let new_prefix = stage1_vid::loop_step(14);
|
||||
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BoxCall {
|
||||
dst: Some(entry_value),
|
||||
box_name: "ArrayBox".to_string(),
|
||||
method: "get".to_string(),
|
||||
args: vec![entries_loop, i_loop],
|
||||
}));
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::Const {
|
||||
dst: const_1,
|
||||
value: ConstValue::Integer(1),
|
||||
}));
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BinOp {
|
||||
dst: next_i,
|
||||
op: BinOpKind::Add,
|
||||
lhs: i_loop,
|
||||
rhs: const_1,
|
||||
}));
|
||||
loop_step_func
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BinOp {
|
||||
dst: new_prefix,
|
||||
op: BinOpKind::Or,
|
||||
lhs: prefix_loop,
|
||||
rhs: entry_value,
|
||||
}));
|
||||
loop_step_func.body.push(JoinInst::Call {
|
||||
func: loop_step_id,
|
||||
args: vec![
|
||||
entries_loop,
|
||||
n_loop,
|
||||
modules_loop,
|
||||
seen_loop,
|
||||
new_prefix,
|
||||
next_i,
|
||||
],
|
||||
k_next: None,
|
||||
dst: None,
|
||||
});
|
||||
|
||||
join_module.add_function(loop_step_func);
|
||||
|
||||
eprintln!(
|
||||
"[joinir/generic_case_a/stage1] ✅ constructed JoinIR (functions={}, value_range={}..{})",
|
||||
join_module.functions.len(),
|
||||
value_id_ranges::base::STAGE1_USING_RESOLVER,
|
||||
value_id_ranges::base::STAGE1_USING_RESOLVER + 1999
|
||||
);
|
||||
|
||||
Some(join_module)
|
||||
}
|
||||
Reference in New Issue
Block a user