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