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"), } }