90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
use prometeu_compiler::ir_core;
|
|
use prometeu_compiler::ir_core::*;
|
|
use prometeu_compiler::lowering::lower_program;
|
|
use prometeu_compiler::ir::*;
|
|
|
|
#[test]
|
|
fn test_full_lowering() {
|
|
let mut const_pool = ConstPool::new();
|
|
const_pool.insert(ConstantValue::Int(100)); // ConstId(0)
|
|
|
|
let program = Program {
|
|
const_pool,
|
|
modules: vec![ir_core::Module {
|
|
name: "test_mod".to_string(),
|
|
functions: vec![ir_core::Function {
|
|
id: FunctionId(1),
|
|
name: "main".to_string(),
|
|
params: vec![],
|
|
return_type: ir_core::Type::Void,
|
|
blocks: vec![
|
|
Block {
|
|
id: 0,
|
|
instrs: vec![
|
|
Instr::PushConst(ConstId(0)),
|
|
Instr::Call(FunctionId(2), 1),
|
|
],
|
|
terminator: Terminator::Jump(1),
|
|
},
|
|
Block {
|
|
id: 1,
|
|
instrs: vec![
|
|
Instr::Syscall(42),
|
|
],
|
|
terminator: Terminator::Return,
|
|
},
|
|
],
|
|
}],
|
|
}],
|
|
};
|
|
|
|
let vm_module = lower_program(&program).expect("Lowering failed");
|
|
|
|
assert_eq!(vm_module.name, "test_mod");
|
|
let func = &vm_module.functions[0];
|
|
assert_eq!(func.name, "main");
|
|
|
|
// Instructions expected:
|
|
// 0: Label block_0
|
|
// 1: PushConst 0
|
|
// 2: Call { func_id: 2, arg_count: 1 }
|
|
// 3: Jmp block_1
|
|
// 4: Label block_1
|
|
// 5: Syscall 42
|
|
// 6: Ret
|
|
|
|
assert_eq!(func.body.len(), 7);
|
|
|
|
match &func.body[0].kind {
|
|
InstrKind::Label(Label(l)) => assert_eq!(l, "block_0"),
|
|
_ => panic!("Expected label block_0"),
|
|
}
|
|
match &func.body[1].kind {
|
|
InstrKind::PushConst(id) => assert_eq!(id.0, 0),
|
|
_ => panic!("Expected PushConst 0"),
|
|
}
|
|
match &func.body[2].kind {
|
|
InstrKind::Call { func_id, arg_count } => {
|
|
assert_eq!(func_id.0, 2);
|
|
assert_eq!(*arg_count, 1);
|
|
}
|
|
_ => panic!("Expected Call"),
|
|
}
|
|
match &func.body[3].kind {
|
|
InstrKind::Jmp(Label(l)) => assert_eq!(l, "block_1"),
|
|
_ => panic!("Expected Jmp block_1"),
|
|
}
|
|
match &func.body[4].kind {
|
|
InstrKind::Label(Label(l)) => assert_eq!(l, "block_1"),
|
|
_ => panic!("Expected label block_1"),
|
|
}
|
|
match &func.body[5].kind {
|
|
InstrKind::Syscall(id) => assert_eq!(*id, 42),
|
|
_ => panic!("Expected Syscall 42"),
|
|
}
|
|
match &func.body[6].kind {
|
|
InstrKind::Ret => (),
|
|
_ => panic!("Expected Ret"),
|
|
}
|
|
}
|