swamp_vm_types/
opcode.rs

1use std::fmt::{Display, Formatter};
2
3#[repr(u8)]
4pub enum OpCode {
5    Hlt, // Return to the host
6
7    // Operators
8    // i32
9    AddI32,
10    MulI32,
11    NegI32,
12
13    // Fixed
14    AddF32,
15    MulF32,
16    NegF32,
17
18    // Comparisons
19    LtI32,
20
21    // Conditional branching
22    Bnz,
23    Bz,
24    // Unconditional branching
25    Jmp,
26
27    // Call, frame and return
28    Call, // Introduce CallLong if needed
29    Enter,
30    Ret,
31
32    // Frame copy
33    Mov,
34    MovLp,
35
36    // Load immediate into frame
37    Ld8,
38    Ld16,
39    Ld32,
40
41    LdConst, // Load from constant memory
42
43    // Indirect operations (using pointer)
44    //St32x,
45    //Stx,
46    //Ldx,
47
48    // Allocate heap
49    //Alloc,
50    //     LtU16,
51    VecFromSlice,
52    VecPush,
53    VecIterInit,
54    VecIterNext,
55    VecIterNextPair,
56    Nop,
57
58    // Intrinsic more advanced opcodes
59
60    // Collection intrinsics
61    MapNewFromPairs,
62    MapRemove,
63    MapIterInit,
64    MapIterNext,
65    MapIterNextPair,
66
67    // String
68    StringFromConstantSlice,
69    StringAppend,
70
71    // others
72    Eq8Imm,
73    Tst8,
74    GtI32,
75    HostCall, // calls back into host
76    StringLen,
77}
78
79impl Display for OpCode {
80    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81        match self {
82            Self::Hlt => write!(f, "hlt"), // Halt execution
83
84            // Load
85            Self::Ld8 => write!(f, "ld8"),
86            Self::Ld16 => write!(f, "ld16"),
87            Self::Ld32 => write!(f, "ld32"),
88
89            Self::LdConst => write!(f, "ldconst"),
90
91            // Move data
92            Self::Mov => write!(f, "mov"),     // Move data
93            Self::MovLp => write!(f, "movlp"), // Move data
94
95            Self::AddI32 => write!(f, "sadd32"), // Signed Add
96            Self::MulI32 => write!(f, "smul32"), // Signed Add
97            Self::NegI32 => write!(f, "sneg32"), // Signed negate
98
99            Self::AddF32 => write!(f, "fadd"), // Signed Add
100            Self::MulF32 => write!(f, "fmul"), // Signed Add
101            Self::NegF32 => write!(f, "fneg"), // Signed negate
102
103            // Functions
104            Self::Call => write!(f, "call"),     // Call function
105            Self::Enter => write!(f, "enter"),   // Function prologue
106            Self::Ret => write!(f, "ret"),       // Return from function
107            Self::HostCall => write!(f, "host"), // Call host function
108
109            // Branches
110            Self::Jmp => write!(f, "jmp"), // Unconditional jump
111            Self::Bz => write!(f, "bz"),   // Branch if Zero (False)
112            Self::Bnz => write!(f, "bnz"), // Branch if Not Zero (True)
113
114            // Comparisons
115            Self::LtI32 => write!(f, "slt32"), // signed Less Than
116            Self::GtI32 => write!(f, "sgt32"), // Set Less Than
117            Self::Eq8Imm => write!(f, "eq8"),
118            Self::Tst8 => write!(f, "tst8"),
119
120            // Vec
121            Self::VecPush => write!(f, "vec_push"),
122            Self::VecFromSlice => write!(f, "vec_from_slice"),
123            Self::VecIterInit => write!(f, "vec_iter_init"),
124            Self::VecIterNext => write!(f, "vec_iter_next"),
125            Self::VecIterNextPair => write!(f, "vec_iter_next_pair"),
126
127            // Map
128            Self::MapNewFromPairs => write!(f, "map_new_from_pairs"),
129            Self::MapRemove => write!(f, "map_remove"),
130            Self::MapIterInit => write!(f, "map_iter_init"),
131            Self::MapIterNext => write!(f, "map_iter_next"),
132            Self::MapIterNextPair => write!(f, "map_iter_next_pair"),
133
134            // Map
135            Self::StringFromConstantSlice => write!(f, "str_from_const"),
136            Self::StringAppend => write!(f, "str_append"),
137            Self::StringLen => write!(f, "str_len"),
138
139            Self::Nop => write!(f, "nop"),
140        }
141    }
142}
143
144// Add this to your OpCode implementation
145impl From<u8> for OpCode {
146    fn from(value: u8) -> Self {
147        // Safety: This assumes the u8 value corresponds to a valid OpCode variant
148        // For production code, consider using TryFrom instead to validate the value
149        unsafe { std::mem::transmute(value) }
150    }
151}