From 89e138a2f8163f2d36fba79d8e1a3019f522a185 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Fri, 5 Dec 2025 21:44:07 +0900 Subject: [PATCH] docs: Complete generic_case_a modularization (Phase 5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated mod.rs with comprehensive module organization documentation - Documented before/after line counts and size reductions - Removed old generic_case_a_old.rs monolith file - Verified all imports are clean (no unused warnings) - Verified all visibility is correct (pub(crate) for public API) Final statistics: - Before: 1,056 lines in single file - After: 1,634 lines across 7 focused modules - Main coordinator: 93 lines (91% reduction) - Average module size: 233 lines (manageable, focused) - Largest module: trim.rs at 537 lines (still maintainable) All success criteria met: ✅ All 7 modules created ✅ cargo build --release succeeds ✅ Zero breaking changes (all APIs compatible) ✅ Module documentation comprehensive ✅ All visibility correct Ref: Phase 192 modularization effort --- .../join_ir/lowering/generic_case_a/mod.rs | 19 +- .../join_ir/lowering/generic_case_a_old.rs | 1056 ----------------- 2 files changed, 15 insertions(+), 1060 deletions(-) delete mode 100644 src/mir/join_ir/lowering/generic_case_a_old.rs diff --git a/src/mir/join_ir/lowering/generic_case_a/mod.rs b/src/mir/join_ir/lowering/generic_case_a/mod.rs index 350bd769..fa2e1391 100644 --- a/src/mir/join_ir/lowering/generic_case_a/mod.rs +++ b/src/mir/join_ir/lowering/generic_case_a/mod.rs @@ -60,11 +60,22 @@ //! // Pattern mismatch, fallback to other lowering //! ``` //! -//! ## Module Organization +//! ## Module Organization (Phase 192) //! -//! Before modularization: 1,056 lines in single file -//! After modularization: ~100 lines coordinator + 6 focused modules (~210 lines avg) -//! Size reduction: **90%** for main file, improved maintainability +//! **Before modularization**: +//! - generic_case_a.rs: 1,056 lines monolith (all 4 patterns + helpers) +//! +//! **After modularization** (Phase 192 complete): +//! - mod.rs: 93 lines (coordinator, **91% reduction**) +//! - skip_ws.rs: 258 lines (whitespace skipping) +//! - trim.rs: 537 lines (string trimming, largest module) +//! - append_defs.rs: 202 lines (array concatenation) +//! - stage1_using_resolver.rs: 228 lines (namespace resolution) +//! - entry_builder.rs: 165 lines (helper, shared initialization) +//! - whitespace_check.rs: 151 lines (helper, shared validation) +//! +//! **Total**: 1,634 lines modularized (7 focused modules) +//! **Average module size**: 233 lines (vs. 1,056-line monolith) //! //! ## See Also //! diff --git a/src/mir/join_ir/lowering/generic_case_a_old.rs b/src/mir/join_ir/lowering/generic_case_a_old.rs deleted file mode 100644 index 0b8136c2..00000000 --- a/src/mir/join_ir/lowering/generic_case_a_old.rs +++ /dev/null @@ -1,1056 +0,0 @@ -//! Generic Case A LoopForm → JoinIR lowering (v1, minimal_ssa_skip_ws 専用) -//! -//! 制約(必読): -//! - 条件式の中身を解析しない(Compare/BinOp を MIR そのままコピーするだけ) -//! - 多重ヘッダ/ネストループは対象外(v1 は minimal_ssa_skip_ws の単純ループ専用) -//! - pinned/carrier/exit は LoopScopeShape から渡された前提で扱う -//! - 解析に失敗したら必ず None を返し、呼び元にフォールバックさせる - -use std::collections::BTreeMap; - -use crate::mir::join_ir::lowering::generic_case_a_entry_builder::EntryFunctionBuilder; -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::skip_ws as vid; -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; - -/// Phase 30: LoopScopeShape を直接受け取る skip_ws lowerer -/// -/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。 -/// CaseAContext::from_scope() 経由で ctx を作成。 -/// -/// # Arguments -/// -/// - `scope`: 事前に構築済みの LoopScopeShape -/// -/// # Returns -/// -/// Some(JoinModule) if successful, None if context building fails. -pub(crate) fn lower_case_a_skip_ws_with_scope( - scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape, -) -> Option { - // CaseAContext::from_scope() で ctx を構築 - let ctx = CaseAContext::from_scope(scope, "skip_ws", |offset| vid::loop_step(offset))?; - - // JoinModule 構築(既存 _for_minimal_skip_ws と同一ロジック) - lower_case_a_skip_ws_core(&ctx) -} - -/// skip_ws JoinModule 構築のコア実装 -/// -/// CaseAContext から JoinModule を構築する共通ロジック。 -/// `_for_minimal_skip_ws` と `_with_scope` の両方から呼ばれる。 -fn lower_case_a_skip_ws_core(ctx: &CaseAContext) -> Option { - let string_key = ctx.pinned_name_or_first(0)?; - let len_key = ctx - .pinned_name_or_first(1) - .unwrap_or_else(|| string_key.clone()); - let index_key = ctx.carrier_name_or_first(0)?; - - let s_loop = ctx.get_loop_id(&string_key)?; - let i_loop = ctx.get_loop_id(&index_key)?; - let n_loop = ctx.get_loop_id(&len_key)?; - - let mut join_module = JoinModule::new(); - - // entry: skip(s) - let skip_id = JoinFuncId::new(0); - let s_param = vid::entry(0); // 3000 - let mut skip_func = JoinFunction::new(skip_id, "skip".to_string(), vec![s_param]); - - let i_init = vid::entry(1); // 3001 - let n_val = vid::entry(2); // 3002 - - // Phase 192: Use EntryFunctionBuilder for boilerplate initialization - let mut entry_builder = EntryFunctionBuilder::new(); - entry_builder.add_var(string_key.clone(), s_param); - entry_builder.add_var(index_key.clone(), i_init); - entry_builder.add_var(len_key.clone(), n_val); - let entry_name_to_id = entry_builder.get_map().clone(); - - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: i_init, - value: ConstValue::Integer(0), - })); - - skip_func.body.push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(n_val), - box_name: "StringBox".to_string(), - method: "length".to_string(), - args: vec![s_param], - })); - - let loop_step_id = JoinFuncId::new(1); - let loop_call_args: Vec = ctx - .ordered_pinned - .iter() - .chain(ctx.ordered_carriers.iter()) - .map(|name| entry_name_to_id.get(name).copied()) - .collect::>()?; - - skip_func.body.push(JoinInst::Call { - func: loop_step_id, - args: loop_call_args, - k_next: None, - dst: None, - }); - - join_module.entry = Some(skip_id); - join_module.add_function(skip_func); - - // loop_step(s, i, n) - 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 cmp1_result = vid::loop_step(3); // 4003 - let ch = vid::loop_step(4); // 4004 - let cmp2_result = vid::loop_step(5); // 4005 - let i_plus_1 = vid::loop_step(6); // 4006 - let const_1 = vid::loop_step(7); // 4007 - let const_space = vid::loop_step(10); // 4010 - let bool_false = vid::loop_step(11); // 4011 - let cmp2_is_false = vid::loop_step(12); // 4012 - - // cmp1_result = (i >= n) - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp1_result, - op: CompareOp::Ge, - lhs: i_loop, - rhs: n_loop, - })); - - let _exit_shape = if ctx.exit_args.is_empty() { - LoopExitShape::new_manual(vec![i_loop]) - } else { - LoopExitShape::new_manual(ctx.exit_args.clone()) - }; // exit_args = [i] が期待値 - - // if i >= n { return i } - loop_step_func.body.push(JoinInst::Jump { - cont: JoinContId::new(0), - args: vec![i_loop], - cond: Some(cmp1_result), - }); - - // const 1 - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_1, - value: ConstValue::Integer(1), - })); - - // i_plus_1 = i + 1 - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: i_plus_1, - op: BinOpKind::Add, - lhs: i_loop, - rhs: const_1, - })); - - // ch = s.substring(i, i + 1) - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(ch), - box_name: "StringBox".to_string(), - method: "substring".to_string(), - args: vec![s_loop, i_loop, i_plus_1], - })); - - // const " " - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_space, - value: ConstValue::String(" ".to_string()), - })); - - // cmp2_result = (ch == " ") - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp2_result, - op: CompareOp::Eq, - lhs: ch, - rhs: const_space, - })); - - // bool false - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: bool_false, - value: ConstValue::Bool(false), - })); - - // cmp2_is_false = (cmp2_result == false) - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp2_is_false, - op: CompareOp::Eq, - lhs: cmp2_result, - rhs: bool_false, - })); - - // if ch != " " { return i } - loop_step_func.body.push(JoinInst::Jump { - cont: JoinContId::new(1), - args: vec![i_loop], - cond: Some(cmp2_is_false), - }); - - // continue: loop_step(s, i+1, n) - loop_step_func.body.push(JoinInst::Call { - func: loop_step_id, - args: vec![s_loop, i_plus_1, n_loop], - k_next: None, - dst: None, - }); - - join_module.add_function(loop_step_func); - - eprintln!( - "[joinir/generic_case_a] ✅ constructed JoinIR via _core (functions={}, value_range={}..{})", - join_module.functions.len(), - value_id_ranges::base::SKIP_WS, - value_id_ranges::base::SKIP_WS + 1999 - ); - - Some(join_module) -} - -/// Phase 30 F-3.0.3: LoopScopeShape を直接受け取る trim lowerer -/// -/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。 -/// CaseAContext::from_scope() 経由で ctx を作成。 -pub(crate) fn lower_case_a_trim_with_scope( - scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape, -) -> Option { - let ctx = CaseAContext::from_scope(scope, "trim", |offset| { - value_id_ranges::funcscanner_trim::loop_step(offset) - })?; - lower_case_a_trim_core(&ctx) -} - -/// trim JoinModule 構築のコア実装 -/// -/// CaseAContext から JoinModule を構築する共通ロジック。 -/// `_for_trim_minimal` と `_with_scope` の両方から呼ばれる。 -fn lower_case_a_trim_core(ctx: &CaseAContext) -> Option { - let string_key = ctx.pinned_name_or_first(0)?; - let base_key = ctx - .pinned_name_or_first(1) - .unwrap_or_else(|| string_key.clone()); - let carrier_key = ctx.carrier_name_or_first(0)?; - - let s_loop = ctx.get_loop_id(&string_key)?; - let b_loop = ctx.get_loop_id(&base_key)?; - let e_loop = ctx.get_loop_id(&carrier_key)?; - - let mut join_module = JoinModule::new(); - - // entry: trim_main(s_param) - let trim_main_id = JoinFuncId::new(0); - let s_param = value_id_ranges::funcscanner_trim::entry(0); - let mut trim_main_func = - JoinFunction::new(trim_main_id, "trim_main".to_string(), vec![s_param]); - - let str_val = value_id_ranges::funcscanner_trim::entry(1); - let n_val = value_id_ranges::funcscanner_trim::entry(2); - let b_val = value_id_ranges::funcscanner_trim::entry(3); - let e_init = value_id_ranges::funcscanner_trim::entry(4); - let const_empty = value_id_ranges::funcscanner_trim::entry(5); - let const_zero = value_id_ranges::funcscanner_trim::entry(6); - - trim_main_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_empty, - value: ConstValue::String("".to_string()), - })); - trim_main_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: str_val, - lhs: const_empty, - rhs: s_param, - op: BinOpKind::Add, - })); - trim_main_func - .body - .push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(n_val), - box_name: "StringBox".to_string(), - method: "length".to_string(), - args: vec![str_val], - })); - trim_main_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_zero, - value: ConstValue::Integer(0), - })); - - let skip_leading_id = JoinFuncId::new(2); - trim_main_func.body.push(JoinInst::Call { - func: skip_leading_id, - args: vec![str_val, const_zero, n_val], - k_next: None, - dst: Some(b_val), - }); - - trim_main_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: e_init, - op: BinOpKind::Add, - lhs: n_val, - rhs: const_zero, - })); - - // Phase 192: Use EntryFunctionBuilder for boilerplate initialization - let mut entry_builder = EntryFunctionBuilder::new(); - entry_builder.add_var(string_key.clone(), str_val); - entry_builder.add_var(base_key.clone(), b_val); - entry_builder.add_var(carrier_key.clone(), e_init); - let entry_name_to_id = entry_builder.get_map().clone(); - - let loop_call_args: Vec = ctx - .ordered_pinned - .iter() - .chain(ctx.ordered_carriers.iter()) - .map(|name| entry_name_to_id.get(name).copied()) - .collect::>()?; - - let loop_step_id = JoinFuncId::new(1); - trim_main_func.body.push(JoinInst::Call { - func: loop_step_id, - args: loop_call_args, - k_next: None, - dst: None, - }); - - join_module.entry = Some(trim_main_id); - join_module.add_function(trim_main_func); - - // loop_step(str, b, e) - 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 cond = value_id_ranges::funcscanner_trim::loop_step(3); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cond, - lhs: e_loop, - rhs: b_loop, - op: CompareOp::Gt, - })); - - let bool_false = value_id_ranges::funcscanner_trim::loop_step(19); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: bool_false, - value: ConstValue::Bool(false), - })); - - let trimmed_base = value_id_ranges::funcscanner_trim::loop_step(4); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(trimmed_base), - box_name: "StringBox".to_string(), - method: "substring".to_string(), - args: vec![s_loop, b_loop, e_loop], - })); - - let cond_is_false = value_id_ranges::funcscanner_trim::loop_step(20); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cond_is_false, - lhs: cond, - rhs: bool_false, - op: CompareOp::Eq, - })); - - let _exit_shape_trim = if ctx.exit_args.is_empty() { - LoopExitShape::new_manual(vec![e_loop]) - } else { - LoopExitShape::new_manual(ctx.exit_args.clone()) - }; - - loop_step_func.body.push(JoinInst::Jump { - cont: JoinContId::new(0), - args: vec![trimmed_base], - cond: Some(cond_is_false), - }); - - let const_1 = value_id_ranges::funcscanner_trim::loop_step(5); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_1, - value: ConstValue::Integer(1), - })); - - let e_minus_1 = value_id_ranges::funcscanner_trim::loop_step(6); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: e_minus_1, - lhs: e_loop, - rhs: const_1, - op: BinOpKind::Sub, - })); - - let ch = value_id_ranges::funcscanner_trim::loop_step(7); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(ch), - box_name: "StringBox".to_string(), - method: "substring".to_string(), - args: vec![s_loop, e_minus_1, e_loop], - })); - - let cmp_space = value_id_ranges::funcscanner_trim::loop_step(8); - let cmp_tab = value_id_ranges::funcscanner_trim::loop_step(9); - let cmp_newline = value_id_ranges::funcscanner_trim::loop_step(10); - let cmp_cr = value_id_ranges::funcscanner_trim::loop_step(11); - - let const_space = value_id_ranges::funcscanner_trim::loop_step(12); - let const_tab = value_id_ranges::funcscanner_trim::loop_step(13); - let const_newline = value_id_ranges::funcscanner_trim::loop_step(14); - let const_cr = value_id_ranges::funcscanner_trim::loop_step(15); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_space, - value: ConstValue::String(" ".to_string()), - })); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_space, - lhs: ch, - rhs: const_space, - op: CompareOp::Eq, - })); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_tab, - value: ConstValue::String("\\t".to_string()), - })); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_tab, - lhs: ch, - rhs: const_tab, - op: CompareOp::Eq, - })); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_newline, - value: ConstValue::String("\\n".to_string()), - })); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_newline, - lhs: ch, - rhs: const_newline, - op: CompareOp::Eq, - })); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Const { - dst: const_cr, - value: ConstValue::String("\\r".to_string()), - })); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_cr, - lhs: ch, - rhs: const_cr, - op: CompareOp::Eq, - })); - - let or1 = value_id_ranges::funcscanner_trim::loop_step(16); - let or2 = value_id_ranges::funcscanner_trim::loop_step(17); - let is_space = value_id_ranges::funcscanner_trim::loop_step(18); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: or1, - lhs: cmp_space, - rhs: cmp_tab, - op: BinOpKind::Or, - })); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: or2, - lhs: or1, - rhs: cmp_newline, - op: BinOpKind::Or, - })); - - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: is_space, - lhs: or2, - rhs: cmp_cr, - op: BinOpKind::Or, - })); - - let is_space_false = value_id_ranges::funcscanner_trim::loop_step(21); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::Compare { - dst: is_space_false, - lhs: is_space, - rhs: bool_false, - op: CompareOp::Eq, - })); - - loop_step_func.body.push(JoinInst::Jump { - cont: JoinContId::new(1), - args: vec![trimmed_base], - cond: Some(is_space_false), - }); - - let e_next = value_id_ranges::funcscanner_trim::loop_step(22); - loop_step_func - .body - .push(JoinInst::Compute(MirLikeInst::BinOp { - dst: e_next, - lhs: e_loop, - rhs: const_1, - op: BinOpKind::Sub, - })); - - loop_step_func.body.push(JoinInst::Call { - func: loop_step_id, - args: vec![s_loop, b_loop, e_next], - k_next: None, - dst: None, - }); - - join_module.add_function(loop_step_func); - - // skip_leading 関数(共通ロジックを手書き版と合わせる) - let mut skip_func = JoinFunction::new( - skip_leading_id, - "skip_leading".to_string(), - vec![ValueId(7000), ValueId(7001), ValueId(7002)], - ); - let s_skip = ValueId(7000); - let i_skip = ValueId(7001); - let n_skip = ValueId(7002); - let cmp_len = ValueId(7003); - let const_1_skip = ValueId(7004); - let i_plus_1_skip = ValueId(7005); - let ch_skip = ValueId(7006); - let cmp_space_skip = ValueId(7007); - let cmp_tab_skip = ValueId(7008); - let cmp_newline_skip = ValueId(7009); - let cmp_cr_skip = ValueId(7010); - let const_space_skip = ValueId(7011); - let const_tab_skip = ValueId(7012); - let const_newline_skip = ValueId(7013); - let const_cr_skip = ValueId(7014); - let or1_skip = ValueId(7015); - let or2_skip = ValueId(7016); - let is_space_skip = ValueId(7017); - let bool_false_skip = ValueId(7018); - let is_space_false_skip = ValueId(7019); - - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_len, - lhs: i_skip, - rhs: n_skip, - op: CompareOp::Ge, - })); - skip_func.body.push(JoinInst::Jump { - cont: JoinContId::new(2), - args: vec![i_skip], - cond: Some(cmp_len), - }); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: const_1_skip, - value: ConstValue::Integer(1), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::BinOp { - dst: i_plus_1_skip, - lhs: i_skip, - rhs: const_1_skip, - op: BinOpKind::Add, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::BoxCall { - dst: Some(ch_skip), - box_name: "StringBox".to_string(), - method: "substring".to_string(), - args: vec![s_skip, i_skip, i_plus_1_skip], - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: const_space_skip, - value: ConstValue::String(" ".to_string()), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_space_skip, - lhs: ch_skip, - rhs: const_space_skip, - op: CompareOp::Eq, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: const_tab_skip, - value: ConstValue::String("\\t".to_string()), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_tab_skip, - lhs: ch_skip, - rhs: const_tab_skip, - op: CompareOp::Eq, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: const_newline_skip, - value: ConstValue::String("\\n".to_string()), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_newline_skip, - lhs: ch_skip, - rhs: const_newline_skip, - op: CompareOp::Eq, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: const_cr_skip, - value: ConstValue::String("\\r".to_string()), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: cmp_cr_skip, - lhs: ch_skip, - rhs: const_cr_skip, - op: CompareOp::Eq, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::BinOp { - dst: or1_skip, - lhs: cmp_space_skip, - rhs: cmp_tab_skip, - op: BinOpKind::Or, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::BinOp { - dst: or2_skip, - lhs: or1_skip, - rhs: cmp_newline_skip, - op: BinOpKind::Or, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::BinOp { - dst: is_space_skip, - lhs: or2_skip, - rhs: cmp_cr_skip, - op: BinOpKind::Or, - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Const { - dst: bool_false_skip, - value: ConstValue::Bool(false), - })); - skip_func.body.push(JoinInst::Compute(MirLikeInst::Compare { - dst: is_space_false_skip, - lhs: is_space_skip, - rhs: bool_false_skip, - op: CompareOp::Eq, - })); - skip_func.body.push(JoinInst::Jump { - cont: JoinContId::new(3), - args: vec![i_skip], - cond: Some(is_space_false_skip), - }); - skip_func.body.push(JoinInst::Call { - func: skip_leading_id, - args: vec![s_skip, i_plus_1_skip, n_skip], - k_next: None, - dst: None, - }); - - join_module.add_function(skip_func); - - eprintln!( - "[joinir/generic_case_a/trim] ✅ constructed JoinIR (functions={}, value_range={}..{})", - join_module.functions.len(), - value_id_ranges::base::FUNCSCANNER_TRIM, - value_id_ranges::base::FUNCSCANNER_TRIM + 1999 - ); - - Some(join_module) -} - -/// 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 { - 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 { - 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 = ctx - .ordered_pinned - .iter() - .chain(ctx.ordered_carriers.iter()) - .map(|name| entry_name_to_id.get(name).copied()) - .collect::>()?; - - 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) -} - -/// 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 { - 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 { - 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 = ctx - .ordered_pinned - .iter() - .chain(ctx.ordered_carriers.iter()) - .map(|name| entry_name_to_id.get(name).copied()) - .collect::>()?; - - 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) -}