1use core::fmt::Display;
2
3use sandpit::TraceLeaf;
4
5pub type Reg = u8;
6
7#[derive(TraceLeaf, Debug, Copy, Clone)]
8pub enum ByteCode {
9 Noop,
10 Swap { r1: Reg, r2: Reg },
11 Copy { dest: Reg, src: Reg },
12 Print { src: Reg },
13 Read { dest: Reg },
14 LoadGlobal { dest: Reg, sym: Reg },
15 StoreGlobal { src: Reg, sym: Reg },
16 MemLoad { dest: Reg, store: Reg, key: Reg },
17 MemStore { store: Reg, key: Reg, src: Reg },
18 NewList { dest: Reg },
19 NewMap { dest: Reg },
20 LoadBool { dest: Reg, val: bool },
21 LoadNull { dest: Reg },
22 LoadInt { dest: Reg, val: i16 },
23 LoadSym { dest: Reg, val: u16 },
24 LoadLocal { dest: Reg, id: u16 },
25 LoadUpvalue { dest: Reg, id: u16 },
26 StoreUpvalue { func: Reg, src: Reg },
27 Equality { dest: Reg, lhs: Reg, rhs: Reg },
28 Inequality { dest: Reg, lhs: Reg, rhs: Reg },
29 Gt { dest: Reg, lhs: Reg, rhs: Reg },
30 Gte { dest: Reg, lhs: Reg, rhs: Reg },
31 Lt { dest: Reg, lhs: Reg, rhs: Reg },
32 Lte { dest: Reg, lhs: Reg, rhs: Reg },
33 Div { dest: Reg, lhs: Reg, rhs: Reg },
34 Mult { dest: Reg, lhs: Reg, rhs: Reg },
35 Add { dest: Reg, lhs: Reg, rhs: Reg },
36 Sub { dest: Reg, lhs: Reg, rhs: Reg },
37 Modulo { dest: Reg, lhs: Reg, rhs: Reg },
38 StoreArg { src: Reg },
39 Call { dest: Reg, src: Reg },
40 Return { src: Reg },
41 Jump { offset: i16 },
42 Jnt { src: Reg, offset: i16 },
43 Jit { src: Reg, offset: i16 },
44 Import { dest: Reg, path: Reg },
45 Push { store: Reg, src: Reg },
46 Pop { dest: Reg, src: Reg },
47 Len { dest: Reg, src: Reg },
48 Clone { dest: Reg, src: Reg },
49 Type { dest: Reg, src: Reg },
50 Delete { dest: Reg, store: Reg, key: Reg },
51 Bind { dest: Reg, func: Reg, arg: Reg },
52 BitFlip { dest: Reg, src: Reg },
53 BitXor { dest: Reg, lhs: Reg, rhs: Reg },
54 BitOr { dest: Reg, lhs: Reg, rhs: Reg },
55 BitAnd { dest: Reg, lhs: Reg, rhs: Reg },
56 BitShift { dest: Reg, lhs: Reg, rhs: Reg }
57}
58
59impl Display for ByteCode {
60 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
61 match self {
62 ByteCode::Jump { offset } => write!(f, "JMP {offset}"),
63 ByteCode::Jnt { src, offset } => write!(f, "JNT {offset}, {src}"),
64 ByteCode::Jit { src, offset } => write!(f, "JIT {offset}, {src}"),
65 ByteCode::StoreArg { src } => write!(f, "ARG {src }"),
66 ByteCode::Call { dest, src } => write!(f, "CALL {dest}, {src }"),
67 ByteCode::Return { src } => write!(f, "RTN {src }"),
68 ByteCode::LoadBool { dest, val } => write!(f, "BOOL {dest}, {val}"),
69 ByteCode::LoadInt { dest, val } => write!(f, "INT {dest}, {val}"),
70 ByteCode::LoadSym { dest, val } => write!(f, "SYM {dest}, #{val}"),
71 ByteCode::LoadLocal { dest, id } => write!(f, "LOC {dest}, {id}"),
72 ByteCode::LoadNull { dest } => write!(f, "LDN {dest}"),
73 ByteCode::LoadUpvalue { dest, id } => write!(f, "LDUV {dest}, {id}"),
74 ByteCode::StoreUpvalue { func, src } => write!(f, "STUV {func}, {src}"),
75 ByteCode::Print { src } => write!(f, "OUT {src }"),
76 ByteCode::Read { dest } => write!(f, "READ {dest}"),
77 ByteCode::Lt { dest, lhs, rhs } => write!(f, "LT {dest}, {lhs}, {rhs}"),
78 ByteCode::Lte { dest, lhs, rhs } => write!(f, "LTE {dest}, {lhs}, {rhs}"),
79 ByteCode::Gt { dest, lhs, rhs } => write!(f, "GT {dest}, {lhs}, {rhs}"),
80 ByteCode::Gte { dest, lhs, rhs } => write!(f, "GTE {dest}, {lhs}, {rhs}"),
81 ByteCode::Inequality { dest, lhs, rhs } => write!(f, "NEQ {dest}, {lhs}, {rhs}"),
82 ByteCode::Equality { dest, lhs, rhs } => write!(f, "EQ {dest}, {lhs}, {rhs}"),
83 ByteCode::Mult { dest, lhs, rhs } => write!(f, "MULT {dest}, {lhs}, {rhs}"),
84 ByteCode::Div { dest, lhs, rhs } => write!(f, "DIV {dest}, {lhs}, {rhs}"),
85 ByteCode::Add { dest, lhs, rhs } => write!(f, "ADD {dest}, {lhs}, {rhs}"),
86 ByteCode::Sub { dest, lhs, rhs } => write!(f, "SUB {dest}, {lhs}, {rhs}"),
87 ByteCode::Modulo { dest, lhs, rhs } => write!(f, "MOD {dest}, {lhs}, {rhs}"),
88 ByteCode::Copy { dest, src } => write!(f, "COPY {dest}, {src}"),
89 ByteCode::Swap { r1, r2 } => write!(f, "SWAP {r1 }, {r2 }"),
90 ByteCode::NewList { dest } => write!(f, "LIST {dest}"),
91 ByteCode::NewMap { dest } => write!(f, "MAP {dest}"),
92 ByteCode::MemLoad { dest, store, key } => write!(f, "MEML {dest}, {store}[{key}]"),
93 ByteCode::MemStore { store, key, src } => write!(f, "MEMS {store}[{key}], {src}"),
94 ByteCode::Push { store, src } => write!(f, "PUSH {store}, {src}"),
95 ByteCode::Pop { dest, src } => write!(f, "POP {dest}, {src}"),
96 ByteCode::Len { dest, src } => write!(f, "LEN {dest}, {src}"),
97 ByteCode::Clone { dest, src } => write!(f, "CLONE {dest}, {src}"),
98 ByteCode::Type { dest, src } => write!(f, "TYPE {dest}, {src}"),
99 ByteCode::Delete { dest, store, key } => write!(f, "DEL {dest}, {store}[{key}]"),
100 ByteCode::Bind { dest, func, arg } => write!(f, "BIND {dest}, {func}, {arg}]"),
101 ByteCode::LoadGlobal { dest, sym } => write!(f, "LDGB {dest}, #{sym}"),
102 ByteCode::StoreGlobal { sym, src } => write!(f, "STGB {src}, #{sym}"),
103 ByteCode::Import { dest, path } => write!(f, "IMPO {dest}, {path}"),
104 ByteCode::BitFlip { dest, src } => write!(f, "FLIP {dest}, {src}"),
105 ByteCode::BitXor { dest, lhs, rhs } => write!(f, "XOR {dest}, {lhs}, {rhs}"),
106 ByteCode::BitOr { dest, lhs, rhs } => write!(f, "OR {dest}, {lhs}, {rhs}"),
107 ByteCode::BitAnd { dest, lhs, rhs } => write!(f, "AND {dest}, {lhs}, {rhs}"),
108 ByteCode::BitShift { dest, lhs, rhs } => write!(f, "SHIF {dest}, {lhs}, {rhs}"),
109 ByteCode::Noop => write!(f, "NOOP"),
110 }
111 }
112}