Nilton Constantino ced7ff0607
pr 10
2026-01-28 18:58:31 +00:00

125 lines
3.3 KiB
Rust

use prometeu_compiler::ir::*;
use prometeu_compiler::ir_core::ids::{ConstId, FunctionId};
use prometeu_compiler::ir_core::const_pool::{ConstPool, ConstantValue};
use serde_json;
#[test]
fn test_vm_ir_serialization() {
let mut const_pool = ConstPool::new();
const_pool.insert(ConstantValue::String("Hello VM".to_string()));
let module = Module {
name: "test_module".to_string(),
const_pool,
functions: vec![Function {
id: FunctionId(1),
name: "main".to_string(),
params: vec![],
return_type: Type::Null,
body: vec![
Instruction::new(InstrKind::PushConst(ConstId(0)), None),
Instruction::new(InstrKind::Call { func_id: FunctionId(2), arg_count: 1 }, None),
Instruction::new(InstrKind::Ret, None),
],
}],
globals: vec![],
};
let json = serde_json::to_string_pretty(&module).unwrap();
// Snapshot check
let expected = r#"{
"name": "test_module",
"const_pool": {
"constants": [
{
"String": "Hello VM"
}
]
},
"functions": [
{
"id": 1,
"name": "main",
"params": [],
"return_type": "Null",
"body": [
{
"kind": {
"PushConst": 0
},
"span": null
},
{
"kind": {
"Call": {
"func_id": 2,
"arg_count": 1
}
},
"span": null
},
{
"kind": "Ret",
"span": null
}
]
}
],
"globals": []
}"#;
assert_eq!(json, expected);
}
#[test]
fn test_lowering_smoke() {
use prometeu_compiler::ir_core;
use prometeu_compiler::lowering::lower_program;
let mut const_pool = ir_core::ConstPool::new();
const_pool.insert(ir_core::ConstantValue::Int(42));
let program = ir_core::Program {
const_pool,
modules: vec![ir_core::Module {
name: "test_core".to_string(),
functions: vec![ir_core::Function {
id: FunctionId(10),
name: "start".to_string(),
params: vec![],
return_type: ir_core::Type::Void,
blocks: vec![ir_core::Block {
id: 0,
instrs: vec![
ir_core::Instr::PushConst(ConstId(0)),
],
terminator: ir_core::Terminator::Return,
}],
}],
}],
};
let vm_module = lower_program(&program).expect("Lowering failed");
assert_eq!(vm_module.name, "test_core");
assert_eq!(vm_module.functions.len(), 1);
let func = &vm_module.functions[0];
assert_eq!(func.name, "start");
assert_eq!(func.id, FunctionId(10));
// Check if instructions were lowered (label + pushconst + ret)
assert_eq!(func.body.len(), 3);
match &func.body[0].kind {
InstrKind::Label(Label(l)) => assert!(l.contains("block_0")),
_ => panic!("Expected label"),
}
match &func.body[1].kind {
InstrKind::PushConst(id) => assert_eq!(id.0, 0),
_ => panic!("Expected PushConst"),
}
match &func.body[2].kind {
InstrKind::Ret => (),
_ => panic!("Expected Ret"),
}
}