2025-09-19 02:07:38 +09:00
|
|
|
use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span};
|
|
|
|
|
use crate::mir::{MirCompiler, MirInstruction};
|
|
|
|
|
|
|
|
|
|
fn lit_i(i: i64) -> ASTNode {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Literal {
|
|
|
|
|
value: LiteralValue::Integer(i),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}
|
2025-09-19 02:07:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bin(op: BinaryOperator, l: ASTNode, r: ASTNode) -> ASTNode {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::BinaryOp {
|
|
|
|
|
operator: op,
|
|
|
|
|
left: Box::new(l),
|
|
|
|
|
right: Box::new(r),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}
|
2025-09-19 02:07:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn nested_loop_with_multi_continue_break_edge_copy_merge() {
|
|
|
|
|
// PHI-off mode
|
|
|
|
|
std::env::set_var("NYASH_MIR_NO_PHI", "1");
|
|
|
|
|
|
|
|
|
|
// i=0; sum=0; loop(i < 10) {
|
|
|
|
|
// i = i + 1;
|
|
|
|
|
// if (i == 2 || i == 4) { continue }
|
|
|
|
|
// if (i == 7) { if (1 == 1) { break } }
|
|
|
|
|
// if ((i % 3) == 0) { continue }
|
|
|
|
|
// sum = sum + i;
|
|
|
|
|
// }
|
|
|
|
|
// return sum
|
|
|
|
|
let ast = ASTNode::Program {
|
|
|
|
|
statements: vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(lit_i(0)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "sum".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(lit_i(0)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
ASTNode::Loop {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Less,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(10),
|
|
|
|
|
)),
|
2025-09-19 02:07:38 +09:00
|
|
|
body: vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(1),
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::If {
|
|
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Or,
|
|
|
|
|
bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(2),
|
|
|
|
|
),
|
|
|
|
|
bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(4),
|
|
|
|
|
),
|
|
|
|
|
)),
|
|
|
|
|
then_body: vec![ASTNode::Continue {
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::If {
|
|
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(7),
|
|
|
|
|
)),
|
|
|
|
|
then_body: vec![ASTNode::If {
|
|
|
|
|
condition: Box::new(bin(BinaryOperator::Equal, lit_i(1), lit_i(1))),
|
|
|
|
|
then_body: vec![ASTNode::Break {
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::If {
|
|
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
bin(
|
|
|
|
|
BinaryOperator::Modulo,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(3),
|
|
|
|
|
),
|
|
|
|
|
lit_i(0),
|
|
|
|
|
)),
|
|
|
|
|
then_body: vec![ASTNode::Continue {
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "sum".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "sum".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "i".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Return {
|
|
|
|
|
value: Some(Box::new(ASTNode::Variable {
|
|
|
|
|
name: "sum".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
})),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut mc = MirCompiler::with_options(false);
|
|
|
|
|
let cr = mc.compile(ast).expect("compile");
|
|
|
|
|
let f = cr.module.functions.get("main").expect("function main");
|
|
|
|
|
|
|
|
|
|
// Locate return block/value
|
|
|
|
|
let (ret_block, out_v) = f
|
|
|
|
|
.blocks
|
|
|
|
|
.iter()
|
|
|
|
|
.find_map(|(bid, bb)| match &bb.terminator {
|
|
|
|
|
Some(MirInstruction::Return { value: Some(v) }) => Some((*bid, *v)),
|
|
|
|
|
_ => None,
|
|
|
|
|
})
|
|
|
|
|
.expect("ret block");
|
|
|
|
|
|
|
|
|
|
// In PHI-off, every predecessor of the ret block should write the merged value via edge Copy
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
let preds: Vec<_> = f
|
|
|
|
|
.blocks
|
|
|
|
|
.get(&ret_block)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.predecessors
|
|
|
|
|
.iter()
|
|
|
|
|
.copied()
|
|
|
|
|
.collect();
|
2025-09-19 02:07:38 +09:00
|
|
|
assert!(preds.len() >= 1, "ret must have at least one predecessor");
|
|
|
|
|
for p in preds {
|
|
|
|
|
let bb = f.blocks.get(&p).unwrap();
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
let has_copy = bb
|
|
|
|
|
.instructions
|
|
|
|
|
.iter()
|
|
|
|
|
.any(|inst| matches!(inst, MirInstruction::Copy { dst, .. } if *dst == out_v));
|
|
|
|
|
assert!(
|
|
|
|
|
has_copy,
|
|
|
|
|
"expected edge Copy to merged value at predecessor {:?}",
|
|
|
|
|
p
|
|
|
|
|
);
|
2025-09-19 02:07:38 +09:00
|
|
|
}
|
|
|
|
|
// ret block itself must not contain Copy to out_v
|
|
|
|
|
let merge_has_copy = f
|
|
|
|
|
.blocks
|
|
|
|
|
.get(&ret_block)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.instructions
|
|
|
|
|
.iter()
|
|
|
|
|
.any(|inst| matches!(inst, MirInstruction::Copy { dst, .. } if *dst == out_v));
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
assert!(
|
|
|
|
|
!merge_has_copy,
|
|
|
|
|
"ret/merge must not contain Copy to merged value"
|
|
|
|
|
);
|
2025-09-19 02:07:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn loop_inner_if_multilevel_edge_copy() {
|
|
|
|
|
// PHI-off
|
|
|
|
|
std::env::set_var("NYASH_MIR_NO_PHI", "1");
|
|
|
|
|
|
|
|
|
|
// j=0; acc=0; loop(j<6){ j=j+1; if(j<3){ if(j%2==0){continue} acc=acc+10 } else { if(j==5){break} acc=acc+1 } } return acc
|
|
|
|
|
let ast = ASTNode::Program {
|
|
|
|
|
statements: vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(lit_i(0)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(lit_i(0)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
ASTNode::Loop {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Less,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(6),
|
|
|
|
|
)),
|
2025-09-19 02:07:38 +09:00
|
|
|
body: vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(1),
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
ASTNode::If {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Less,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(3),
|
|
|
|
|
)),
|
2025-09-19 02:07:38 +09:00
|
|
|
then_body: vec![
|
|
|
|
|
ASTNode::If {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
bin(
|
|
|
|
|
BinaryOperator::Modulo,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(2),
|
|
|
|
|
),
|
|
|
|
|
lit_i(0),
|
|
|
|
|
)),
|
|
|
|
|
then_body: vec![ASTNode::Continue {
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
2025-09-19 02:07:38 +09:00
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(10),
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
],
|
|
|
|
|
else_body: Some(vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::If {
|
|
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Equal,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "j".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(5),
|
|
|
|
|
)),
|
|
|
|
|
then_body: vec![ASTNode::Break {
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
else_body: Some(vec![]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(1),
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
]),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Return {
|
|
|
|
|
value: Some(Box::new(ASTNode::Variable {
|
|
|
|
|
name: "acc".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
})),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut mc = MirCompiler::with_options(false);
|
|
|
|
|
let cr = mc.compile(ast).expect("compile");
|
|
|
|
|
let f = cr.module.functions.get("main").expect("function main");
|
|
|
|
|
|
|
|
|
|
// Find ret block/value
|
|
|
|
|
let (ret_block, out_v) = f
|
|
|
|
|
.blocks
|
|
|
|
|
.iter()
|
|
|
|
|
.find_map(|(bid, bb)| match &bb.terminator {
|
|
|
|
|
Some(MirInstruction::Return { value: Some(v) }) => Some((*bid, *v)),
|
|
|
|
|
_ => None,
|
|
|
|
|
})
|
|
|
|
|
.expect("ret block");
|
|
|
|
|
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
let preds: Vec<_> = f
|
|
|
|
|
.blocks
|
|
|
|
|
.get(&ret_block)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.predecessors
|
|
|
|
|
.iter()
|
|
|
|
|
.copied()
|
|
|
|
|
.collect();
|
2025-09-19 02:07:38 +09:00
|
|
|
assert!(preds.len() >= 1, "ret must have predecessors");
|
|
|
|
|
for p in preds {
|
|
|
|
|
let bb = f.blocks.get(&p).unwrap();
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
assert!(bb
|
|
|
|
|
.instructions
|
|
|
|
|
.iter()
|
|
|
|
|
.any(|inst| matches!(inst, MirInstruction::Copy { dst, .. } if *dst == out_v)));
|
2025-09-19 02:07:38 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "phi-legacy")]
|
|
|
|
|
#[test]
|
|
|
|
|
#[ignore]
|
|
|
|
|
fn phi_on_loop_has_phi_in_header() {
|
|
|
|
|
// PHI-on (explicit)
|
|
|
|
|
std::env::set_var("NYASH_MIR_NO_PHI", "0");
|
|
|
|
|
|
|
|
|
|
// x=0; loop(x<3){ x=x+1 } return x
|
|
|
|
|
let ast = ASTNode::Program {
|
|
|
|
|
statements: vec![
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "x".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(lit_i(0)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
2025-09-19 02:07:38 +09:00
|
|
|
ASTNode::Loop {
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
condition: Box::new(bin(
|
|
|
|
|
BinaryOperator::Less,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "x".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(3),
|
|
|
|
|
)),
|
|
|
|
|
body: vec![ASTNode::Assignment {
|
|
|
|
|
target: Box::new(ASTNode::Variable {
|
|
|
|
|
name: "x".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}),
|
|
|
|
|
value: Box::new(bin(
|
|
|
|
|
BinaryOperator::Add,
|
|
|
|
|
ASTNode::Variable {
|
|
|
|
|
name: "x".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
lit_i(1),
|
|
|
|
|
)),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
}],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
ASTNode::Return {
|
|
|
|
|
value: Some(Box::new(ASTNode::Variable {
|
|
|
|
|
name: "x".into(),
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
})),
|
2025-09-19 02:07:38 +09:00
|
|
|
span: Span::unknown(),
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
span: Span::unknown(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut mc = MirCompiler::with_options(false);
|
|
|
|
|
let cr = mc.compile(ast).expect("compile");
|
|
|
|
|
let f = cr.module.functions.get("main").expect("function main");
|
|
|
|
|
|
|
|
|
|
// Find any block with Phi(s) — loop header should have them in PHI-on.
|
|
|
|
|
let phi_blocks: Vec<_> = f
|
|
|
|
|
.blocks
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|(_bid, bb)| bb.phi_instructions().count() > 0)
|
|
|
|
|
.map(|(bid, _)| *bid)
|
|
|
|
|
.collect();
|
|
|
|
|
|
refactor(tests): Reorganize test files into module directories
- Split join_ir_vm_bridge_dispatch.rs into module directory
- Reorganize test files into categorical directories:
- exec_parity/, flow/, if_no_phi/, joinir/, macro_tests/
- mir/, parser/, sugar/, vm/, vtable/
- Fix compilation errors after refactoring:
- BinaryOperator::LessThan → Less, Mod → Modulo
- Add VM re-export in backend::vm module
- Fix BinaryOp import to use public API
- Add callee: None for MirInstruction::Call
- Fix VMValue type mismatch with proper downcast
- Resolve borrow checker issues in vtable tests
- Mark 2 tests using internal APIs as #[ignore]
JoinIR tests: 50 passed, 0 failed, 20 ignored
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:28:20 +09:00
|
|
|
assert!(
|
|
|
|
|
!phi_blocks.is_empty(),
|
|
|
|
|
"expected at least one Phi block in PHI-on"
|
|
|
|
|
);
|
2025-09-19 02:07:38 +09:00
|
|
|
|
|
|
|
|
// Spot-check: each Phi should have at least 2 inputs (preheader + latch) in a loop
|
|
|
|
|
for bid in phi_blocks.into_iter() {
|
|
|
|
|
let bb = f.blocks.get(&bid).unwrap();
|
|
|
|
|
for inst in bb.phi_instructions() {
|
|
|
|
|
if let MirInstruction::Phi { inputs, .. } = inst {
|
|
|
|
|
assert!(inputs.len() >= 2, "Phi should have at least 2 inputs");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|