2026-01-29 15:45:48 +00:00

94 lines
2.2 KiB
Rust

use prometeu_compiler::compiler;
use prometeu_bytecode::pbc::parse_pbc;
use prometeu_bytecode::disasm::disasm;
use std::fs;
use tempfile::tempdir;
#[test]
fn test_golden_bytecode_snapshot() {
let dir = tempdir().unwrap();
let project_dir = dir.path();
fs::write(
project_dir.join("prometeu.json"),
r#"{
"script_fe": "pbs",
"entry": "main.pbs"
}"#,
).unwrap();
let code = r#"
declare contract Gfx host {}
fn helper(val: int): int {
return val * 2;
}
fn main() {
Gfx.clear(0);
let x = 10;
if (x > 5) {
let y = helper(x);
}
let buf = alloc int;
mutate buf as b {
let current = b + 1;
}
}
"#;
fs::write(project_dir.join("main.pbs"), code).unwrap();
let unit = compiler::compile(project_dir).expect("Failed to compile");
let pbc = parse_pbc(&unit.rom).expect("Failed to parse PBC");
let instrs = disasm(&pbc.rom).expect("Failed to disassemble");
let mut disasm_text = String::new();
for instr in instrs {
let operands_str = instr.operands.iter()
.map(|o| format!("{:?}", o))
.collect::<Vec<_>>()
.join(" ");
let line = if operands_str.is_empty() {
format!("{:04X} {:?}\n", instr.pc, instr.opcode)
} else {
format!("{:04X} {:?} {}\n", instr.pc, instr.opcode, operands_str.trim())
};
disasm_text.push_str(&line);
}
let expected_disasm = r#"0000 GetLocal U32(0)
0006 PushConst U32(1)
000C Mul
000E Ret
0010 PushConst U32(2)
0016 Syscall U32(4097)
001C PushConst U32(3)
0022 SetLocal U32(0)
0028 GetLocal U32(0)
002E PushConst U32(4)
0034 Gt
0036 JmpIfFalse U32(94)
003C Jmp U32(66)
0042 GetLocal U32(0)
0048 Call U32(0) U32(1)
0052 SetLocal U32(1)
0058 Jmp U32(100)
005E Jmp U32(100)
0064 Alloc
0066 SetLocal U32(1)
006C GetLocal U32(1)
0072 LoadRef U32(0)
0078 SetLocal U32(2)
007E GetLocal U32(2)
0084 PushConst U32(5)
008A Add
008C SetLocal U32(3)
0092 GetLocal U32(2)
0098 StoreRef U32(0)
009E Ret
"#;
assert_eq!(disasm_text, expected_disasm);
}