Files
hakorune/src/mir/join_ir_runner.rs

818 lines
29 KiB
Rust
Raw Normal View History

//! JoinIR Runner - Development Harness (Structure Validation Only)
//!
//! # Two Routes
//!
//! ## Route A: JoinIR→MIR→VM (Recommended SSOT)
//! - Full semantic validation via MIR lowering pipeline
//! - Tests should use `JoinIrFrontendTestRunner` or `run_joinir_via_vm`
//! - Examples: Phase 34 tests (IfSelect, Loop, Break, Continue)
//! - **Use this route for ALL semantic tests**
//!
//! ## Route B: Direct JoinIR Runner (Structure Validation)
//! - For structure-only validation of JoinIR constructs
//! - Use `run_joinir_function` only when Route A is insufficient
//! - Examples: Handwritten JoinIR module tests, low-level instruction tests
//! - Note: Some operations (e.g., MethodCall) may be unimplemented in Runner
//!
//! # Phase 35-4 Unification Strategy
//! All semantic tests migrated to Route A. Route B kept only for fundamental
//! structure validation that cannot be verified through MIR→VM path.
//!
//! # Original Purpose (Phase 27.2)
//! hand-written / minimal JoinIR を VM と A/B 比較するための軽量ランナー。
//! - 対応値: i64 / bool / String / Unit
//! - 対応命令: Const / BinOp / Compare / BoxCall(StringBox: length, substring) /
//! Call / Jump / Ret
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
//!
//! Phase 27.8: ops box 統合
//! - JoinValue / JoinIrOpError は join_ir_ops から再エクスポート
//! - eval_binop() / eval_compare() を使用(実装を一箇所に集約)
use std::collections::HashMap;
use crate::mir::join_ir::{ConstValue, JoinFuncId, JoinInst, JoinModule, MirLikeInst, VarId};
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
// Phase 27.8: ops box からの再エクスポート
pub use crate::mir::join_ir_ops::{JoinIrOpError, JoinValue};
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
// Phase 27.8: 互換性のため JoinRuntimeError を JoinIrOpError の別名として保持
pub type JoinRuntimeError = JoinIrOpError;
pub fn run_joinir_function(
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
vm: &mut crate::backend::mir_interpreter::MirInterpreter,
module: &JoinModule,
entry: JoinFuncId,
args: &[JoinValue],
) -> Result<JoinValue, JoinRuntimeError> {
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
execute_function(vm, module, entry, args.to_vec())
}
fn execute_function(
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
vm: &mut crate::backend::mir_interpreter::MirInterpreter,
module: &JoinModule,
mut current_func: JoinFuncId,
mut current_args: Vec<JoinValue>,
) -> Result<JoinValue, JoinRuntimeError> {
'exec: loop {
let func = module.functions.get(&current_func).ok_or_else(|| {
JoinRuntimeError::new(format!("Function {:?} not found", current_func))
})?;
if func.params.len() != current_args.len() {
return Err(JoinRuntimeError::new(format!(
"Arity mismatch for {:?}: expected {}, got {}",
func.id,
func.params.len(),
current_args.len()
)));
}
let mut locals: HashMap<VarId, JoinValue> = HashMap::new();
for (param, arg) in func.params.iter().zip(current_args.iter()) {
locals.insert(*param, arg.clone());
}
let mut ip = 0usize;
while ip < func.body.len() {
match &func.body[ip] {
JoinInst::Compute(inst) => {
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
eval_compute(vm, inst, &mut locals)?;
ip += 1;
}
JoinInst::Call {
func: target,
args,
k_next,
dst,
} => {
if k_next.is_some() {
return Err(JoinRuntimeError::new(
"Join continuation (k_next) is not supported in the experimental runner",
));
}
let resolved_args = materialize_args(args, &locals)?;
if let Some(dst_var) = dst {
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
let value = execute_function(vm, module, *target, resolved_args)?;
locals.insert(*dst_var, value);
ip += 1;
} else {
current_func = *target;
current_args = resolved_args;
continue 'exec;
}
}
JoinInst::Jump {
cont: _,
args,
cond,
} => {
let should_jump = match cond {
Some(var) => as_bool(&read_var(&locals, *var)?)?,
None => true,
};
if should_jump {
let ret = if let Some(first) = args.first() {
read_var(&locals, *first)?
} else {
JoinValue::Unit
};
return Ok(ret);
}
ip += 1;
}
JoinInst::Ret { value } => {
let ret = match value {
Some(var) => read_var(&locals, *var)?,
None => JoinValue::Unit,
};
return Ok(ret);
}
// Phase 33: Select instruction execution
JoinInst::Select {
dst,
cond,
then_val,
else_val,
} => {
// 1. Evaluate cond (Bool or Int)
let cond_value = read_var(&locals, *cond)?;
eprintln!(
"[SELECT DEBUG] cond={:?}, cond_value={:?}",
cond, cond_value
);
let cond_bool = match cond_value {
JoinValue::Bool(b) => b,
JoinValue::Int(i) => i != 0, // Int も許す0=false, それ以外=true
_ => {
return Err(JoinRuntimeError::new(format!(
"Select: cond must be Bool or Int, got {:?}",
cond_value
)))
}
};
// 2. Select then_val or else_val
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
let then_value = read_var(&locals, *then_val)?;
let else_value = read_var(&locals, *else_val)?;
eprintln!(
"[SELECT DEBUG] cond_bool={}, then_val={:?}={:?}, else_val={:?}={:?}",
cond_bool, then_val, then_value, else_val, else_value
);
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
let selected_id = if cond_bool { *then_val } else { *else_val };
let selected_value = read_var(&locals, selected_id)?;
eprintln!(
"[SELECT DEBUG] selected_id={:?}, selected_value={:?}",
selected_id, selected_value
);
// 3. Write to dst
locals.insert(*dst, selected_value);
ip += 1;
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-6: IfMerge instruction execution (複数変数 PHI)
JoinInst::IfMerge {
cond,
merges,
k_next,
} => {
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-6 最小実装: k_next は None のみサポート
if k_next.is_some() {
return Err(JoinRuntimeError::new(
"IfMerge: k_next continuation is not yet supported (Phase 33-6 minimal)",
));
}
// 1. Evaluate cond (Bool or Int)
let cond_value = read_var(&locals, *cond)?;
let cond_bool = match cond_value {
JoinValue::Bool(b) => b,
JoinValue::Int(i) => i != 0,
_ => {
return Err(JoinRuntimeError::new(format!(
"IfMerge: cond must be Bool or Int, got {:?}",
cond_value
)))
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
};
// 2. 各 merge ペアについて、cond に応じて値を選択して代入
for merge in merges {
let selected_id = if cond_bool {
merge.then_val
} else {
merge.else_val
};
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
let selected_value = read_var(&locals, selected_id)?;
locals.insert(merge.dst, selected_value);
}
ip += 1;
}
// Phase 34-6: MethodCall instruction execution
JoinInst::MethodCall { .. } => {
// Phase 34-6: MethodCall は JoinIR Runner では未対応
// JoinIR → MIR 変換経由で VM が実行する
return Err(JoinRuntimeError::new(
"MethodCall is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)"
));
}
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
// Phase 56: ConditionalMethodCall instruction execution
JoinInst::ConditionalMethodCall { .. } => {
// Phase 56: ConditionalMethodCall は JoinIR Runner では未対応
// JoinIR → MIR 変換経由で VM が実行する
return Err(JoinRuntimeError::new(
"ConditionalMethodCall is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)"
));
}
// Phase 41-4: NestedIfMerge instruction execution
JoinInst::NestedIfMerge { .. } => {
// Phase 41-4: NestedIfMerge は JoinIR Runner では未対応
// JoinIR → MIR 変換経由で VM が実行する
return Err(JoinRuntimeError::new(
"NestedIfMerge is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)"
));
}
// Phase 51: FieldAccess instruction execution
JoinInst::FieldAccess { .. } => {
// Phase 51: FieldAccess は JoinIR Runner では未対応
// JoinIR → MIR 変換経由で VM が実行する
return Err(JoinRuntimeError::new(
"FieldAccess is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)"
));
}
// Phase 51: NewBox instruction execution
JoinInst::NewBox { .. } => {
// Phase 51: NewBox は JoinIR Runner では未対応
// JoinIR → MIR 変換経由で VM が実行する
return Err(JoinRuntimeError::new(
"NewBox is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)"
));
}
}
}
// fallthrough without explicit return
return Ok(JoinValue::Unit);
}
}
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
fn eval_compute(
vm: &mut crate::backend::mir_interpreter::MirInterpreter,
inst: &MirLikeInst,
locals: &mut HashMap<VarId, JoinValue>,
) -> Result<(), JoinRuntimeError> {
match inst {
MirLikeInst::Const { dst, value } => {
let v = match value {
ConstValue::Integer(i) => JoinValue::Int(*i),
ConstValue::Bool(b) => JoinValue::Bool(*b),
ConstValue::String(s) => JoinValue::Str(s.clone()),
ConstValue::Null => JoinValue::Unit,
};
locals.insert(*dst, v);
}
MirLikeInst::BinOp { dst, op, lhs, rhs } => {
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
// Phase 27.8: ops box の eval_binop() を使用
let l = read_var(locals, *lhs)?;
let r = read_var(locals, *rhs)?;
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
let v = crate::mir::join_ir_ops::eval_binop(*op, &l, &r)?;
locals.insert(*dst, v);
}
MirLikeInst::Compare { dst, op, lhs, rhs } => {
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
// Phase 27.8: ops box の eval_compare() を使用
let l = read_var(locals, *lhs)?;
let r = read_var(locals, *rhs)?;
feat(joinir): Phase 27.8-1~3 — Ops Box導入 + Toggle対応完了 ## Phase 27.8-1: JoinIR 命令意味箱(Ops Box)作成 ✅ **新規ファイル**: `src/mir/join_ir_ops.rs` - `eval_binop()`: Add, Sub, Mul, Div, Or, And の評価ロジック一元化 - `eval_compare()`: Lt, Le, Gt, Ge, Eq, Ne の比較ロジック一元化 - エラー処理: `JoinIrOpError` 型で型安全 - 完全テストカバレッジ: 13個のユニットテスト **効果**: - BinOp/Compare の評価ロジックを一箇所に集約 - 再利用可能な API で将来の拡張が容易 - テスタビリティ向上 ## Phase 27.8-2: join_ir_runner.rs の Ops Box 統合 ✅ **変更**: `src/mir/join_ir_runner.rs` - BinOp/Compare の実装を ops box に完全移譲(約70行削減) - `JoinValue` / `JoinIrOpError` を ops box から再エクスポート - 後方互換性維持: `JoinRuntimeError = JoinIrOpError` **効果**: - コード重複削減(約70行) - 実装の一貫性保証(ops box の単一実装を使用) ## Phase 27.8-3: MIR→JoinIR Toggle 対応 ✅ **変更**: `src/mir/join_ir.rs` - `lower_skip_ws_to_joinir()`: トグル対応ディスパッチャー - `lower_skip_ws_handwritten()`: 既存実装をリネーム(Phase 27.1-27.7) - `lower_skip_ws_from_mir()`: MIR自動解析版スタブ(Phase 27.8-4 で実装予定) **環境変数制御**: ```bash # 手書き版(デフォルト) ./target/release/hakorune program.hako # MIR自動解析版(Phase 27.8-4 実装予定) NYASH_JOINIR_LOWER_FROM_MIR=1 ./target/release/hakorune program.hako ``` **効果**: - 段階的な移行が可能(既存動作を完全に維持) - A/B テストによる検証が容易 ## 変更ファイル - `src/mir/join_ir_ops.rs` (新規): Ops Box 実装 - `src/mir/join_ir_runner.rs`: Ops Box 使用に変更 - `src/mir/join_ir.rs`: Toggle 対応ディスパッチャー追加 - `src/mir/mod.rs`: join_ir_ops モジュール追加 ## コンパイル結果 ✅ 0 errors, 18 warnings(既存警告のみ) ✅ ビルド成功 ## 次のステップ **Phase 27.8-4**: `lower_skip_ws_from_mir()` 本実装 - MirQuery を使った MIR 解析 - パターンマッチング(init, header, break checks, body) - JoinIR 自動生成(entry function + loop_step function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:47:00 +09:00
let v = crate::mir::join_ir_ops::eval_compare(*op, &l, &r)?;
locals.insert(*dst, v);
}
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
// S-5.2-improved: BoxCall → VM execute_box_call ラッパー経由
// - 制御フロー: JoinIR Runner が担当
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
// - Box/Plugin 実装: Rust VM に完全委譲VM 2号機を避ける
// - VM の完全な BoxCall 意味論を使用:
// * Void guards (Void.length() → 0)
// * PluginBox サポート (FileBox, NetBox)
// * InstanceBox policy checks
// * object_fields handling
// * Method re-routing (toString→str)
MirLikeInst::BoxCall {
dst,
box_name: _, // box_name は VM が内部で判定するため不要
method,
args,
} => {
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
// First argument is the receiver (box instance)
if args.is_empty() {
return Err(JoinRuntimeError::new(
"BoxCall requires at least a receiver argument",
));
}
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
// Convert receiver to VMValue
let receiver_jv = read_var(locals, args[0])?;
let receiver_vm = receiver_jv.to_vm_value();
// Convert remaining arguments to VMValue
let method_args_vm: Vec<crate::backend::VMValue> = args[1..]
.iter()
.map(|&var_id| read_var(locals, var_id).map(|jv| jv.to_vm_value()))
.collect::<Result<Vec<_>, _>>()?;
// Invoke VM's execute_box_call for complete semantics
let result_vm = vm
.execute_box_call(receiver_vm, method, method_args_vm)
feat(joinir): S-5.2-improved - VM完全意味論統合完了 Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
2025-11-24 08:37:59 +09:00
.map_err(|e| JoinRuntimeError::new(format!("BoxCall failed: {}", e)))?;
// Convert result back to JoinValue
let result_jv = crate::mir::join_ir_ops::JoinValue::from_vm_value(&result_vm)?;
// Store result if destination is specified
if let Some(dst_var) = dst {
locals.insert(*dst_var, result_jv);
}
}
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
// Phase 56: UnaryOp
MirLikeInst::UnaryOp { dst, op, operand } => {
let operand_val = read_var(locals, *operand)?;
let result = match op {
refactor(mir): loop_builder.rs モジュール化 - 6ファイルに分割 ## リファクタリング内容 ### ファイル構造変更 - `src/mir/loop_builder.rs` (1515行) 削除 - `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行) ### 新規モジュール構成 1. **mod.rs** (6,293行 → 実際は約150行) - モジュール定義とre-export - LoopBuilder構造体定義 2. **loop_form.rs** (25,988行 → 実際は約650行) - メインループlowering pipeline - デバッグ/実験フラグ集約 3. **if_lowering.rs** (15,600行 → 実際は約390行) - In-loop if lowering with JoinIR/PHI bridge - **Phase 61-2コード完全保持**: - JoinIR dry-run検証モード - PhiSpec計算とA/B比較 4. **phi_ops.rs** (12,844行 → 実際は約320行) - PHI emit helpers - LoopFormOps/PhiBuilderOps impls 5. **control.rs** (4,261行 → 実際は約107行) - break/continue capture - predecessor bookkeeping 6. **statements.rs** (1,673行 → 実際は約42行) - loop-body statement lowering entry point 7. **README.md** (752行 → 実際は約19行) - モジュール責務とサブモジュール説明 ### 設計原則 - **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離 - **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行 - **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲 ## テスト結果 - Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec) - loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## 統計 - **純削減**: -1,521行(25ファイル変更) - **loop_builder**: 1515行 → 1529行(+14行、6ファイル化) - **可読性**: 巨大単一ファイル → 責務別モジュール ## ChatGPT設計・Claude確認 大規模リファクタリングをChatGPTが実施、Claudeが検証完了。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:44:40 +09:00
crate::mir::join_ir::UnaryOp::Not => match operand_val {
JoinValue::Bool(b) => JoinValue::Bool(!b),
JoinValue::Int(i) => JoinValue::Bool(i == 0),
_ => {
return Err(JoinRuntimeError::new(format!(
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
"Cannot apply 'not' to {:?}",
operand_val
refactor(mir): loop_builder.rs モジュール化 - 6ファイルに分割 ## リファクタリング内容 ### ファイル構造変更 - `src/mir/loop_builder.rs` (1515行) 削除 - `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行) ### 新規モジュール構成 1. **mod.rs** (6,293行 → 実際は約150行) - モジュール定義とre-export - LoopBuilder構造体定義 2. **loop_form.rs** (25,988行 → 実際は約650行) - メインループlowering pipeline - デバッグ/実験フラグ集約 3. **if_lowering.rs** (15,600行 → 実際は約390行) - In-loop if lowering with JoinIR/PHI bridge - **Phase 61-2コード完全保持**: - JoinIR dry-run検証モード - PhiSpec計算とA/B比較 4. **phi_ops.rs** (12,844行 → 実際は約320行) - PHI emit helpers - LoopFormOps/PhiBuilderOps impls 5. **control.rs** (4,261行 → 実際は約107行) - break/continue capture - predecessor bookkeeping 6. **statements.rs** (1,673行 → 実際は約42行) - loop-body statement lowering entry point 7. **README.md** (752行 → 実際は約19行) - モジュール責務とサブモジュール説明 ### 設計原則 - **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離 - **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行 - **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲 ## テスト結果 - Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec) - loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## 統計 - **純削減**: -1,521行(25ファイル変更) - **loop_builder**: 1515行 → 1529行(+14行、6ファイル化) - **可読性**: 巨大単一ファイル → 責務別モジュール ## ChatGPT設計・Claude確認 大規模リファクタリングをChatGPTが実施、Claudeが検証完了。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:44:40 +09:00
)))
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
}
refactor(mir): loop_builder.rs モジュール化 - 6ファイルに分割 ## リファクタリング内容 ### ファイル構造変更 - `src/mir/loop_builder.rs` (1515行) 削除 - `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行) ### 新規モジュール構成 1. **mod.rs** (6,293行 → 実際は約150行) - モジュール定義とre-export - LoopBuilder構造体定義 2. **loop_form.rs** (25,988行 → 実際は約650行) - メインループlowering pipeline - デバッグ/実験フラグ集約 3. **if_lowering.rs** (15,600行 → 実際は約390行) - In-loop if lowering with JoinIR/PHI bridge - **Phase 61-2コード完全保持**: - JoinIR dry-run検証モード - PhiSpec計算とA/B比較 4. **phi_ops.rs** (12,844行 → 実際は約320行) - PHI emit helpers - LoopFormOps/PhiBuilderOps impls 5. **control.rs** (4,261行 → 実際は約107行) - break/continue capture - predecessor bookkeeping 6. **statements.rs** (1,673行 → 実際は約42行) - loop-body statement lowering entry point 7. **README.md** (752行 → 実際は約19行) - モジュール責務とサブモジュール説明 ### 設計原則 - **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離 - **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行 - **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲 ## テスト結果 - Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec) - loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## 統計 - **純削減**: -1,521行(25ファイル変更) - **loop_builder**: 1515行 → 1529行(+14行、6ファイル化) - **可読性**: 巨大単一ファイル → 責務別モジュール ## ChatGPT設計・Claude確認 大規模リファクタリングをChatGPTが実施、Claudeが検証完了。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:44:40 +09:00
},
crate::mir::join_ir::UnaryOp::Neg => match operand_val {
JoinValue::Int(i) => JoinValue::Int(-i),
_ => {
return Err(JoinRuntimeError::new(format!(
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
"Cannot apply '-' to {:?}",
operand_val
refactor(mir): loop_builder.rs モジュール化 - 6ファイルに分割 ## リファクタリング内容 ### ファイル構造変更 - `src/mir/loop_builder.rs` (1515行) 削除 - `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行) ### 新規モジュール構成 1. **mod.rs** (6,293行 → 実際は約150行) - モジュール定義とre-export - LoopBuilder構造体定義 2. **loop_form.rs** (25,988行 → 実際は約650行) - メインループlowering pipeline - デバッグ/実験フラグ集約 3. **if_lowering.rs** (15,600行 → 実際は約390行) - In-loop if lowering with JoinIR/PHI bridge - **Phase 61-2コード完全保持**: - JoinIR dry-run検証モード - PhiSpec計算とA/B比較 4. **phi_ops.rs** (12,844行 → 実際は約320行) - PHI emit helpers - LoopFormOps/PhiBuilderOps impls 5. **control.rs** (4,261行 → 実際は約107行) - break/continue capture - predecessor bookkeeping 6. **statements.rs** (1,673行 → 実際は約42行) - loop-body statement lowering entry point 7. **README.md** (752行 → 実際は約19行) - モジュール責務とサブモジュール説明 ### 設計原則 - **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離 - **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行 - **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲 ## テスト結果 - Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec) - loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## 統計 - **純削減**: -1,521行(25ファイル変更) - **loop_builder**: 1515行 → 1529行(+14行、6ファイル化) - **可読性**: 巨大単一ファイル → 責務別モジュール ## ChatGPT設計・Claude確認 大規模リファクタリングをChatGPTが実施、Claudeが検証完了。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:44:40 +09:00
)))
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
}
refactor(mir): loop_builder.rs モジュール化 - 6ファイルに分割 ## リファクタリング内容 ### ファイル構造変更 - `src/mir/loop_builder.rs` (1515行) 削除 - `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行) ### 新規モジュール構成 1. **mod.rs** (6,293行 → 実際は約150行) - モジュール定義とre-export - LoopBuilder構造体定義 2. **loop_form.rs** (25,988行 → 実際は約650行) - メインループlowering pipeline - デバッグ/実験フラグ集約 3. **if_lowering.rs** (15,600行 → 実際は約390行) - In-loop if lowering with JoinIR/PHI bridge - **Phase 61-2コード完全保持**: - JoinIR dry-run検証モード - PhiSpec計算とA/B比較 4. **phi_ops.rs** (12,844行 → 実際は約320行) - PHI emit helpers - LoopFormOps/PhiBuilderOps impls 5. **control.rs** (4,261行 → 実際は約107行) - break/continue capture - predecessor bookkeeping 6. **statements.rs** (1,673行 → 実際は約42行) - loop-body statement lowering entry point 7. **README.md** (752行 → 実際は約19行) - モジュール責務とサブモジュール説明 ### 設計原則 - **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離 - **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行 - **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲 ## テスト結果 - Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec) - loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## 統計 - **純削減**: -1,521行(25ファイル変更) - **loop_builder**: 1515行 → 1529行(+14行、6ファイル化) - **可読性**: 巨大単一ファイル → 責務別モジュール ## ChatGPT設計・Claude確認 大規模リファクタリングをChatGPTが実施、Claudeが検証完了。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:44:40 +09:00
},
feat(joinir): Phase 56 ArrayExtBox.filter JoinIR lowering完全実装 ## Summary ArrayExtBox.filter/2 の JoinIR Frontend lowering を完全実装し、 ConditionalMethodCall 命令を導入して filter パターンに対応。 56 JoinIR テスト全て PASS(退行なし)。 ## Technical Changes ### 1. ConditionalMethodCall 命令追加 - **新規命令**: `if pred(v) { acc.push(v) }` パターン用 - **構造**: cond が true なら method 実行、false なら no-op - **MIR 変換**: 4ブロック構造 (cond→then/else→merge) ### 2. AST JSON 拡張 - Break/Continue/FunctionCall に "type" フィールド追加 - ArrayLiteral/MapLiteral に "type" フィールド追加 - JoinIR Frontend 互換性向上 ### 3. Expression Handler 拡張 - Unary 演算子(not, 負号)サポート - Call(変数関数呼び出し)を MethodCall に変換 ### 4. Loop Pattern Binding 修正 - `BoundExpr::Variable("n")` 問題修正 - `MethodCall { receiver: "arr", method: "size" }` に変更 - external_refs (arr, pred) を step 関数に伝播 ### 5. If Statement Handler 拡張 - 条件付き側効果パターン(ケース4)追加 - MethodCall/Method 形式の statement を ConditionalMethodCall に変換 ## Files Modified (10 files, +456/-45 lines) - ast_json.rs: AST JSON "type" フィールド追加 - loop_frontend_binding.rs: n バインディング修正 - control_flow.rs: external_refs params 追加 - loop_patterns.rs: external_refs step 関数伝播 - expr.rs: Unary, Call handler 追加 - stmt_handlers.rs: ConditionalMethodCall パターン追加 - mod.rs: ConditionalMethodCall, UnaryOp 定義 - json.rs: ConditionalMethodCall, UnaryOp シリアライズ - join_ir_runner.rs: ConditionalMethodCall, UnaryOp スタブ - convert.rs: ConditionalMethodCall → MIR 変換 ## Test Results - 56 JoinIR tests: ✅ PASSED - Regression: ❌ None - ArrayExtBox.filter/2: ✅ JoinIR lowering 成功 ## Milestone JoinIR 2ループ完走達成: - ✅ JsonTokenizer.print_tokens/0 - ✅ ArrayExtBox.filter/2 (NEW!) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:51:43 +09:00
};
locals.insert(*dst, result);
}
}
Ok(())
}
fn read_var(locals: &HashMap<VarId, JoinValue>, var: VarId) -> Result<JoinValue, JoinRuntimeError> {
locals
.get(&var)
.cloned()
.ok_or_else(|| JoinRuntimeError::new(format!("Variable {:?} not bound", var)))
}
fn materialize_args(
args: &[VarId],
locals: &HashMap<VarId, JoinValue>,
) -> Result<Vec<JoinValue>, JoinRuntimeError> {
args.iter().map(|v| read_var(locals, *v)).collect()
}
fn as_bool(value: &JoinValue) -> Result<bool, JoinRuntimeError> {
match value {
JoinValue::Bool(b) => Ok(*b),
JoinValue::Int(i) => Ok(*i != 0),
JoinValue::Unit => Ok(false),
other => Err(JoinRuntimeError::new(format!(
"Expected bool-compatible value, got {:?}",
other
))),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::backend::mir_interpreter::MirInterpreter;
use crate::mir::join_ir::{ConstValue, JoinFunction, JoinModule};
use crate::mir::ValueId;
#[test]
fn test_select_true() {
// let result = if true { 1 } else { 2 }
// expected: result == 1
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then = ValueId(2);
let v_else = ValueId(3);
let v_result = ValueId(4);
// const v1 = true
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Bool(true),
}));
// const v2 = 1
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then,
value: ConstValue::Integer(1),
}));
// const v3 = 2
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else,
value: ConstValue::Integer(2),
}));
// select v4 = v1 ? v2 : v3
func.body.push(JoinInst::Select {
dst: v_result,
cond: v_cond,
then_val: v_then,
else_val: v_else,
});
// return v4
func.body.push(JoinInst::Ret {
value: Some(v_result),
});
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(1));
}
#[test]
fn test_select_false() {
// let result = if false { 1 } else { 2 }
// expected: result == 2
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then = ValueId(2);
let v_else = ValueId(3);
let v_result = ValueId(4);
// const v1 = false
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Bool(false),
}));
// const v2 = 1
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then,
value: ConstValue::Integer(1),
}));
// const v3 = 2
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else,
value: ConstValue::Integer(2),
}));
// select v4 = v1 ? v2 : v3
func.body.push(JoinInst::Select {
dst: v_result,
cond: v_cond,
then_val: v_then,
else_val: v_else,
});
// return v4
func.body.push(JoinInst::Ret {
value: Some(v_result),
});
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(2));
}
#[test]
fn test_select_int_cond() {
// cond=Int(0) → false、Int(1) → true
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then = ValueId(2);
let v_else = ValueId(3);
let v_result = ValueId(4);
// const v1 = 0 (treated as false)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Integer(0),
}));
// const v2 = 100
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then,
value: ConstValue::Integer(100),
}));
// const v3 = 200
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else,
value: ConstValue::Integer(200),
}));
// select v4 = v1 ? v2 : v3
func.body.push(JoinInst::Select {
dst: v_result,
cond: v_cond,
then_val: v_then,
else_val: v_else,
});
// return v4
func.body.push(JoinInst::Ret {
value: Some(v_result),
});
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(200)); // 0 is false, so should select else
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-6: IfMerge instruction tests
#[test]
fn test_if_merge_true() {
// if true { x=1; y=2 } else { x=3; y=4 }
// expected: x=1, y=2
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then_x = ValueId(2);
let v_then_y = ValueId(3);
let v_else_x = ValueId(4);
let v_else_y = ValueId(5);
let v_result_x = ValueId(6);
let v_result_y = ValueId(7);
// const v1 = true
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Bool(true),
}));
// const v2 = 1 (then x)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_x,
value: ConstValue::Integer(1),
}));
// const v3 = 2 (then y)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_y,
value: ConstValue::Integer(2),
}));
// const v4 = 3 (else x)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_x,
value: ConstValue::Integer(3),
}));
// const v5 = 4 (else y)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_y,
value: ConstValue::Integer(4),
}));
// if_merge v1 { v6=v2; v7=v3 } else { v6=v4; v7=v5 }
func.body.push(JoinInst::IfMerge {
cond: v_cond,
merges: vec![
crate::mir::join_ir::MergePair {
dst: v_result_x,
then_val: v_then_x,
else_val: v_else_x,
},
crate::mir::join_ir::MergePair {
dst: v_result_y,
then_val: v_then_y,
else_val: v_else_y,
},
],
k_next: None,
});
// return v6 + v7
let v_sum = ValueId(8);
func.body.push(JoinInst::Compute(MirLikeInst::BinOp {
dst: v_sum,
op: crate::mir::join_ir::BinOpKind::Add,
lhs: v_result_x,
rhs: v_result_y,
}));
func.body.push(JoinInst::Ret { value: Some(v_sum) });
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(3)); // 1 + 2 = 3
}
#[test]
fn test_if_merge_false() {
// if false { x=1; y=2 } else { x=3; y=4 }
// expected: x=3, y=4
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then_x = ValueId(2);
let v_then_y = ValueId(3);
let v_else_x = ValueId(4);
let v_else_y = ValueId(5);
let v_result_x = ValueId(6);
let v_result_y = ValueId(7);
// const v1 = false
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Bool(false),
}));
// const v2 = 1 (then x)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_x,
value: ConstValue::Integer(1),
}));
// const v3 = 2 (then y)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_y,
value: ConstValue::Integer(2),
}));
// const v4 = 3 (else x)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_x,
value: ConstValue::Integer(3),
}));
// const v5 = 4 (else y)
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_y,
value: ConstValue::Integer(4),
}));
// if_merge v1 { v6=v2; v7=v3 } else { v6=v4; v7=v5 }
func.body.push(JoinInst::IfMerge {
cond: v_cond,
merges: vec![
crate::mir::join_ir::MergePair {
dst: v_result_x,
then_val: v_then_x,
else_val: v_else_x,
},
crate::mir::join_ir::MergePair {
dst: v_result_y,
then_val: v_then_y,
else_val: v_else_y,
},
],
k_next: None,
});
// return v6 + v7
let v_sum = ValueId(8);
func.body.push(JoinInst::Compute(MirLikeInst::BinOp {
dst: v_sum,
op: crate::mir::join_ir::BinOpKind::Add,
lhs: v_result_x,
rhs: v_result_y,
}));
func.body.push(JoinInst::Ret { value: Some(v_sum) });
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(7)); // 3 + 4 = 7
}
#[test]
fn test_if_merge_multiple() {
// if true { x=10; y=20; z=30 } else { x=1; y=2; z=3 }
// expected: x=10, y=20, z=30 → sum=60
let mut module = JoinModule::new();
let mut func = JoinFunction::new(JoinFuncId::new(0), "test_func".to_string(), vec![]);
let v_cond = ValueId(1);
let v_then_x = ValueId(2);
let v_then_y = ValueId(3);
let v_then_z = ValueId(4);
let v_else_x = ValueId(5);
let v_else_y = ValueId(6);
let v_else_z = ValueId(7);
let v_result_x = ValueId(8);
let v_result_y = ValueId(9);
let v_result_z = ValueId(10);
// const v1 = true
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_cond,
value: ConstValue::Bool(true),
}));
// then values
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_x,
value: ConstValue::Integer(10),
}));
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_y,
value: ConstValue::Integer(20),
}));
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_then_z,
value: ConstValue::Integer(30),
}));
// else values
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_x,
value: ConstValue::Integer(1),
}));
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_y,
value: ConstValue::Integer(2),
}));
func.body.push(JoinInst::Compute(MirLikeInst::Const {
dst: v_else_z,
value: ConstValue::Integer(3),
}));
// if_merge with 3 variables
func.body.push(JoinInst::IfMerge {
cond: v_cond,
merges: vec![
crate::mir::join_ir::MergePair {
dst: v_result_x,
then_val: v_then_x,
else_val: v_else_x,
},
crate::mir::join_ir::MergePair {
dst: v_result_y,
then_val: v_then_y,
else_val: v_else_y,
},
crate::mir::join_ir::MergePair {
dst: v_result_z,
then_val: v_then_z,
else_val: v_else_z,
},
],
k_next: None,
});
// return x + y + z
let v_sum_xy = ValueId(11);
func.body.push(JoinInst::Compute(MirLikeInst::BinOp {
dst: v_sum_xy,
op: crate::mir::join_ir::BinOpKind::Add,
lhs: v_result_x,
rhs: v_result_y,
}));
let v_sum_xyz = ValueId(12);
func.body.push(JoinInst::Compute(MirLikeInst::BinOp {
dst: v_sum_xyz,
op: crate::mir::join_ir::BinOpKind::Add,
lhs: v_sum_xy,
rhs: v_result_z,
}));
func.body.push(JoinInst::Ret {
value: Some(v_sum_xyz),
});
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
module.add_function(func);
let mut vm = MirInterpreter::new();
let result = run_joinir_function(&mut vm, &module, JoinFuncId::new(0), &[]).unwrap();
assert_eq!(result, JoinValue::Int(60)); // 10 + 20 + 30 = 60
}
}