#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u16)] pub enum OpCode { // 6.1 Controle de Execução Nop = 0x00, Halt = 0x01, Jmp = 0x02, JmpIfFalse = 0x03, // 6.2 Pilha PushConst = 0x10, Pop = 0x11, Dup = 0x12, Swap = 0x13, // 6.3 Aritmética Add = 0x20, Sub = 0x21, Mul = 0x22, Div = 0x23, // 6.4 Comparação e Lógica Eq = 0x30, Neq = 0x31, Lt = 0x32, Gt = 0x33, And = 0x34, Or = 0x35, Not = 0x36, // 6.5 Variáveis GetGlobal = 0x40, SetGlobal = 0x41, GetLocal = 0x42, SetLocal = 0x43, // 6.6 Funções Call = 0x50, Ret = 0x51, PushScope = 0x52, PopScope = 0x53, // 6.7 Heap Alloc = 0x60, LoadRef = 0x61, StoreRef = 0x62, // 6.8 Periféricos e Sistema Syscall = 0x70, FrameSync = 0x80, } impl TryFrom for OpCode { type Error = String; fn try_from(value: u16) -> Result { match value { 0x00 => Ok(OpCode::Nop), 0x01 => Ok(OpCode::Halt), 0x02 => Ok(OpCode::Jmp), 0x03 => Ok(OpCode::JmpIfFalse), 0x10 => Ok(OpCode::PushConst), 0x11 => Ok(OpCode::Pop), 0x12 => Ok(OpCode::Dup), 0x13 => Ok(OpCode::Swap), 0x20 => Ok(OpCode::Add), 0x21 => Ok(OpCode::Sub), 0x22 => Ok(OpCode::Mul), 0x23 => Ok(OpCode::Div), 0x30 => Ok(OpCode::Eq), 0x31 => Ok(OpCode::Neq), 0x32 => Ok(OpCode::Lt), 0x33 => Ok(OpCode::Gt), 0x34 => Ok(OpCode::And), 0x35 => Ok(OpCode::Or), 0x36 => Ok(OpCode::Not), 0x40 => Ok(OpCode::GetGlobal), 0x41 => Ok(OpCode::SetGlobal), 0x42 => Ok(OpCode::GetLocal), 0x43 => Ok(OpCode::SetLocal), 0x50 => Ok(OpCode::Call), 0x51 => Ok(OpCode::Ret), 0x52 => Ok(OpCode::PushScope), 0x53 => Ok(OpCode::PopScope), 0x60 => Ok(OpCode::Alloc), 0x61 => Ok(OpCode::LoadRef), 0x62 => Ok(OpCode::StoreRef), 0x70 => Ok(OpCode::Syscall), 0x80 => Ok(OpCode::FrameSync), _ => Err(format!("Invalid OpCode: 0x{:04X}", value)), } } } impl OpCode { pub fn cycles(&self) -> u64 { match self { OpCode::Nop => 1, OpCode::Halt => 1, OpCode::Jmp => 2, OpCode::JmpIfFalse => 3, OpCode::PushConst => 2, OpCode::Pop => 1, OpCode::Dup => 1, OpCode::Swap => 1, OpCode::Add => 2, OpCode::Sub => 2, OpCode::Mul => 4, OpCode::Div => 6, OpCode::Eq => 2, OpCode::Neq => 2, OpCode::Lt => 2, OpCode::Gt => 2, OpCode::And => 2, OpCode::Or => 2, OpCode::Not => 1, OpCode::GetGlobal => 3, OpCode::SetGlobal => 3, OpCode::GetLocal => 2, OpCode::SetLocal => 2, OpCode::Call => 5, OpCode::Ret => 4, OpCode::PushScope => 3, OpCode::PopScope => 3, OpCode::Alloc => 10, OpCode::LoadRef => 3, OpCode::StoreRef => 3, OpCode::Syscall => 1, // Variável, mas vamos usar 1 como base ou definir via ID OpCode::FrameSync => 1, } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_opcode_decoding() { assert_eq!(OpCode::try_from(0x00).unwrap(), OpCode::Nop); assert_eq!(OpCode::try_from(0x10).unwrap(), OpCode::PushConst); assert_eq!(OpCode::try_from(0x20).unwrap(), OpCode::Add); assert_eq!(OpCode::try_from(0x70).unwrap(), OpCode::Syscall); assert_eq!(OpCode::try_from(0x80).unwrap(), OpCode::FrameSync); assert!(OpCode::try_from(0xFFFF).is_err()); } #[test] fn test_opcode_cycles() { assert_eq!(OpCode::Nop.cycles(), 1); assert_eq!(OpCode::Add.cycles(), 2); assert_eq!(OpCode::Mul.cycles(), 4); assert_eq!(OpCode::Div.cycles(), 6); assert_eq!(OpCode::Alloc.cycles(), 10); } }