Files
hakorune/src/tests/joinir_frontend_if_select.rs
nyash-codex 447bbec998 refactor(joinir): Split ast_lowerer and join_ir_vm_bridge into modules
ast_lowerer.rs → ast_lowerer/ (10 files):
- mod.rs: public surface + entry dispatch
- context.rs: ExtractCtx helpers
- expr.rs: expression-to-JoinIR extraction
- if_return.rs: simple if→Select lowering
- loop_patterns.rs: loop variants (simple/break/continue)
- read_quoted.rs: read_quoted_from lowering (Phase 45-46)
- nested_if.rs: NestedIfMerge lowering
- analysis.rs: loop if-var analysis + metadata helpers
- tests.rs: frontend lowering tests
- README.md: module documentation

join_ir_vm_bridge.rs → join_ir_vm_bridge/ (5 files):
- mod.rs: public surface + shared helpers
- convert.rs: JoinIR→MIR lowering
- runner.rs: VM execution entry (run_joinir_via_vm)
- meta.rs: experimental metadata-aware hooks
- tests.rs: bridge-specific unit tests
- README.md: module documentation

Benefits:
- Clear separation of concerns per pattern
- Easier navigation and maintenance
- Each file has single responsibility
- README documents module boundaries

Co-authored-by: ChatGPT <noreply@openai.com>

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 17:42:19 +09:00

131 lines
4.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! JoinIR Frontend — IfSelect A/B Test (Phase 34-2)
//!
//! Route A: 既存経路AST→MIR→PHI→VM
//! Route B: 新経路AST→JoinIR→MIR'→VM
use crate::mir::join_ir_ops::JoinValue;
use crate::tests::helpers::joinir_frontend::JoinIrFrontendTestRunner;
/// Phase 34-2: IfSelect simple pattern の A/B テスト
///
/// 入力: `fixtures/joinir_if_select_simple.program.json`
/// パターン: `if cond { return 10 } else { return 20 }`
/// 期待: Route A と Route B の結果が一致
#[test]
fn joinir_frontend_if_select_simple_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/joinir_if_select_simple.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(vec![JoinValue::Int(1)], JoinValue::Int(10)),
(vec![JoinValue::Int(0)], JoinValue::Int(20)),
])
.expect("Test cases failed");
}
/// Phase 34-3: IfSelect local pattern の A/B テスト
///
/// 入力: `fixtures/joinir_if_select_local.program.json`
/// パターン: `if cond { x=10 } else { x=20 }; return x` (意味論的)
/// 期待: simple と同じ JoinIR 出力Select ベース)
#[test]
fn joinir_frontend_if_select_local_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/joinir_if_select_local.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(vec![JoinValue::Int(1)], JoinValue::Int(10)),
(vec![JoinValue::Int(0)], JoinValue::Int(20)),
])
.expect("Test cases failed");
}
/// Phase 34-6: JsonShapeToMap._read_value_from_pair/1 の完全実装テスト
///
/// 入力: `fixtures/json_shape_read_value.program.json`
/// パターン: `if at { return v.substring(0, at) } else { return v }`
/// 期待: 本物の substring 呼び出しが JoinIR MethodCall → MIR BoxCall で実行される
#[test]
fn joinir_frontend_json_shape_read_value_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/json_shape_read_value.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(
vec![JoinValue::Str("hello".to_string()), JoinValue::Int(3)],
JoinValue::Str("hel".to_string()),
),
(
vec![JoinValue::Str("world".to_string()), JoinValue::Int(0)],
JoinValue::Str("world".to_string()),
),
])
.expect("Test cases failed");
}
/// Phase 34-7: tiny while loop の A/B テスト
///
/// 入力: `fixtures/loop_frontend_simple.program.json`
/// パターン: `local i = 0; local acc = 0; loop(i < n) { acc = acc + 1; i = i + 1; } return acc`
/// 期待: Case-A な JoinIR (entry → loop_step → return) が生成され、正しく実行される
#[test]
fn joinir_frontend_loop_simple_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/loop_frontend_simple.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(vec![JoinValue::Int(0)], JoinValue::Int(0)),
(vec![JoinValue::Int(3)], JoinValue::Int(3)),
(vec![JoinValue::Int(5)], JoinValue::Int(5)),
])
.expect("Test cases failed");
}
/// Phase 34-8: Break pattern の A/B テスト
///
/// 入力: `fixtures/loop_frontend_break.program.json`
/// パターン: `loop { if i >= n { break }; acc = acc + i; i = i + 1 }`
/// 期待: n=5 → acc=10 (0+1+2+3+4)
#[test]
fn joinir_frontend_loop_break_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/loop_frontend_break.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(vec![JoinValue::Int(0)], JoinValue::Int(0)), // n=0 → 0
(vec![JoinValue::Int(5)], JoinValue::Int(10)), // n=5 → 10 (0+1+2+3+4)
(vec![JoinValue::Int(3)], JoinValue::Int(3)), // n=3 → 3 (0+1+2)
])
.expect("Test cases failed");
}
/// Phase 34-8: Continue pattern の A/B テスト
///
/// 入力: `fixtures/loop_frontend_continue.program.json`
/// パターン: `loop { i = i + 1; if i == 3 { continue }; acc = acc + i }`
/// 期待: n=5 → acc=12 (1+2+4+5, i==3 スキップ)
#[test]
fn joinir_frontend_loop_continue_ab_test() {
JoinIrFrontendTestRunner::from_fixture(
"docs/private/roadmap2/phases/phase-34-joinir-frontend/fixtures/loop_frontend_continue.program.json"
)
.lower()
.expect("Failed to lower fixture")
.run_cases(&[
(vec![JoinValue::Int(0)], JoinValue::Int(0)), // n=0 → 0
(vec![JoinValue::Int(5)], JoinValue::Int(12)), // n=5 → 12 (1+2+4+5)
(vec![JoinValue::Int(2)], JoinValue::Int(3)), // n=2 → 3 (1+2)
])
.expect("Test cases failed");
}