123 lines
3.2 KiB
Rust
123 lines
3.2 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::backend::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(),
|
|
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"),
|
|
}
|
|
}
|