refactor(joinir): Phase 27.9 - Modular separation of join_ir.rs into directory structure

Phase 27.9 で join_ir.rs (~1,336行) を以下のモジュール構造に分離:

## 新規ディレクトリ構造:
```
src/mir/join_ir/
├── mod.rs                           # 型定義・共通ユーティリティ (~330行)
└── lowering/
    ├── mod.rs                       # lowering インターフェース
    ├── min_loop.rs                  # lower_min_loop_to_joinir (~140行)
    ├── skip_ws.rs                   # skip_ws lowering 3関数 (~390行)
    └── funcscanner_trim.rs          # trim lowering (~480行)
```

## 技術的変更:
- **型定義統一**: JoinFuncId, JoinInst, JoinModule 等を mod.rs に集約
- **lowering 分離**: 3つの lowering 関数を個別モジュールに移動
- **後方互換性**: pub use で lowering 関数を re-export(既存コード影響なし)
- **削除**: src/mir/join_ir.rs (旧単一ファイル)

## テスト結果:
- **385 passed** (+1 from 384)
- **9 failed** (-1 from 10)
- **ビルド成功**: 0 errors, 18 warnings (変化なし)

## 効果:
- **保守性向上**: 1,336行 → 4ファイル(各300-500行)で可読性向上
- **モジュール境界明確化**: 型定義 vs lowering 実装の責務分離
- **将来の拡張容易**: 新 lowering 関数追加が簡単に

Phase 27.8 で実装した MIR 自動解析 lowering の基盤整備完了。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-23 16:49:49 +09:00
parent a575b046ad
commit 3d5979c78e
9 changed files with 1393 additions and 1337 deletions

View File

@ -0,0 +1,138 @@
//! Phase 26-H: JoinIrMin.main/0 専用の MIR → JoinIR 変換
//!
//! 目的: apps/tests/joinir_min_loop.hako の MIR を JoinIR に変換する最小実装
//!
//! 期待される変換:
//! ```text
//! // MIR (元):
//! static box JoinIrMin {
//! main() {
//! local i = 0
//! loop(i < 3) {
//! if i >= 2 { break }
//! i = i + 1
//! }
//! return i
//! }
//! }
//!
//! // JoinIR (変換後):
//! fn main(k_exit) {
//! let i_init = 0
//! loop_step(i_init, k_exit)
//! }
//!
//! fn loop_step(i, k_exit) {
//! if i >= 2 {
//! k_exit(i) // break
//! } else {
//! loop_step(i + 1, k_exit) // continue
//! }
//! }
//! ```
use crate::mir::ValueId;
use crate::mir::join_ir::{
BinOpKind, CompareOp, ConstValue, JoinFuncId, JoinFunction, JoinInst, JoinModule, MirLikeInst,
};
pub fn lower_min_loop_to_joinir(module: &crate::mir::MirModule) -> Option<JoinModule> {
// Step 1: "JoinIrMin.main/0" を探す
let target_func = module.functions.get("JoinIrMin.main/0")?;
eprintln!("[joinir/lower] Found JoinIrMin.main/0");
eprintln!("[joinir/lower] MIR blocks: {}", target_func.blocks.len());
// Step 2: JoinModule を構築
let mut join_module = JoinModule::new();
// Phase 26-H: 最小実装として、固定的な JoinIR を生成
// (実際の MIR 解析は Phase 27 以降)
// main 関数: i_init = 0, loop_step(0, k_exit)
let main_id = JoinFuncId::new(0);
let mut main_func = JoinFunction::new(main_id, "main".to_string(), vec![]);
let i_init = ValueId(1000); // 固定 ValueId
let const_0 = ValueId(1001);
let const_1 = ValueId(1002);
let const_2 = ValueId(1003);
// const 0
main_func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: i_init,
value: ConstValue::Integer(0),
}));
// loop_step(i_init, k_exit)
let loop_step_id = JoinFuncId::new(1);
main_func.body.push(JoinInst::Call {
func: loop_step_id,
args: vec![i_init],
k_next: None, // main は直接 loop_step を呼ぶ
dst: None,
});
join_module.add_function(main_func);
// loop_step 関数: if i >= 2 { ret i } else { loop_step(i+1) }
let mut loop_step_func = JoinFunction::new(
loop_step_id,
"loop_step".to_string(),
vec![ValueId(2000)], // i パラメータ
);
let i_param = ValueId(2000);
let cmp_result = ValueId(2001);
let i_plus_1 = ValueId(2002);
// const 2 (for comparison)
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: const_2,
value: ConstValue::Integer(2),
}));
// cmp_result = (i >= 2)
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::Compare {
dst: cmp_result,
op: CompareOp::Ge,
lhs: i_param,
rhs: const_2,
}));
// if cmp_result { ret i } else { loop_step(i+1) }
// Phase 26-H 簡略化: 分岐はせず両方の経路を示す
// ret i (break path)
loop_step_func.body.push(JoinInst::Ret {
value: Some(i_param),
});
// const 1 (for increment)
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_param,
rhs: const_1,
}));
// loop_step(i + 1) (continue path)
loop_step_func.body.push(JoinInst::Call {
func: loop_step_id,
args: vec![i_plus_1],
k_next: None,
dst: None,
});
join_module.add_function(loop_step_func);
eprintln!("[joinir/lower] Generated {} JoinIR functions", join_module.functions.len());
Some(join_module)
}