1use crate::ast::assignment_operation::AssignmentOperator;
2use crate::values::core_values::decimal::Decimal;
3use crate::values::core_values::integer::Integer;
4use crate::values::core_values::{
5 decimal::utils::decimal_to_string, endpoint::Endpoint,
6};
7use binrw::{BinRead, BinWrite};
8use std::fmt::Display;
9
10#[derive(Clone, Debug, PartialEq)]
11pub enum Instruction {
12 Int8(Int8Data),
14 Int16(Int16Data),
15 Int32(Int32Data),
16 Int64(Int64Data),
17 Int128(Int128Data),
18
19 UInt8(UInt8Data),
21 UInt16(UInt16Data),
22 UInt32(UInt32Data),
23 UInt64(UInt64Data),
24 UInt128(UInt128Data),
25
26 BigInteger(IntegerData),
28
29 Endpoint(Endpoint),
30
31 DecimalF32(Float32Data),
32 DecimalF64(Float64Data),
33 DecimalAsInt16(FloatAsInt16Data),
34 DecimalAsInt32(FloatAsInt32Data),
35 Decimal(DecimalData),
36
37 ExecutionBlock(ExecutionBlockData),
38 RemoteExecution,
39
40 ShortText(ShortTextData),
41 Text(TextData),
42 True,
43 False,
44 Null,
45 ScopeStart,
46 ListStart,
47 MapStart,
48 StructStart,
49 ScopeEnd,
50 KeyValueDynamic,
51 KeyValueShortText(ShortTextData),
52 CloseAndStore,
53
54 Add,
56 Subtract,
57 Multiply,
58 Divide,
59
60 UnaryMinus,
63 UnaryPlus,
65 BitwiseNot,
66
67 Apply(ApplyData),
68
69 Is,
71 Matches,
72 StructuralEqual,
73 Equal,
74 NotStructuralEqual,
75 NotEqual,
76
77 AddAssign(SlotAddress),
79 SubtractAssign(SlotAddress),
80 MultiplyAssign(SlotAddress),
81 DivideAssign(SlotAddress),
82
83 CreateRef,
84 CreateRefMut,
85 CreateRefFinal,
86
87 GetRef(RawFullPointerAddress),
89 GetLocalRef(RawLocalPointerAddress),
90 GetInternalRef(RawInternalPointerAddress),
91
92 GetOrCreateRef(GetOrCreateRefData),
94 GetOrCreateRefMut(GetOrCreateRefData),
96
97 AllocateSlot(SlotAddress),
98 GetSlot(SlotAddress),
99 DropSlot(SlotAddress),
100 SetSlot(SlotAddress),
101
102 AssignToReference(AssignmentOperator),
103 Deref,
104
105 TypeInstructions(Vec<TypeInstruction>),
106 TypeExpression(Vec<TypeInstruction>),
107}
108
109impl Display for Instruction {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 match self {
112 Instruction::Int8(data) => write!(f, "INT_8 {}", data.0),
113 Instruction::Int16(data) => write!(f, "INT_16 {}", data.0),
114 Instruction::Int32(data) => write!(f, "INT_32 {}", data.0),
115 Instruction::Int64(data) => write!(f, "INT_64 {}", data.0),
116 Instruction::Int128(data) => write!(f, "INT_128 {}", data.0),
117
118 Instruction::UInt8(data) => write!(f, "UINT_8 {}", data.0),
119 Instruction::UInt16(data) => write!(f, "UINT_16 {}", data.0),
120 Instruction::UInt32(data) => write!(f, "UINT_32 {}", data.0),
121 Instruction::UInt64(data) => write!(f, "UINT_64 {}", data.0),
122 Instruction::UInt128(data) => write!(f, "UINT_128 {}", data.0),
123
124 Instruction::Apply(count) => write!(f, "APPLY {}", count.arg_count),
125
126 Instruction::BigInteger(data) => {
127 write!(f, "BIG_INTEGER {}", data.0)
128 }
129 Instruction::Endpoint(data) => {
130 write!(f, "ENDPOINT {data}")
131 }
132
133 Instruction::DecimalAsInt16(data) => {
134 write!(f, "DECIMAL_AS_INT_16 {}", data.0)
135 }
136 Instruction::DecimalAsInt32(data) => {
137 write!(f, "DECIMAL_AS_INT_32 {}", data.0)
138 }
139 Instruction::DecimalF32(data) => {
140 write!(f, "DECIMAL_F32 {}", decimal_to_string(data.0, false))
141 }
142 Instruction::DecimalF64(data) => {
143 write!(f, "DECIMAL_F64 {}", decimal_to_string(data.0, false))
144 }
145 Instruction::Decimal(data) => {
146 write!(f, "DECIMAL_BIG {}", data.0)
147 }
148 Instruction::ShortText(data) => write!(f, "SHORT_TEXT {}", data.0),
149 Instruction::Text(data) => write!(f, "TEXT {}", data.0),
150 Instruction::True => write!(f, "TRUE"),
151 Instruction::False => write!(f, "FALSE"),
152 Instruction::Null => write!(f, "NULL"),
153 Instruction::ScopeStart => write!(f, "SCOPE_START"),
154 Instruction::ListStart => write!(f, "LIST_START"),
155 Instruction::MapStart => write!(f, "MAP_START"),
156 Instruction::StructStart => write!(f, "STRUCT_START"),
157 Instruction::ScopeEnd => write!(f, "SCOPE_END"),
158 Instruction::KeyValueDynamic => write!(f, "KEY_VALUE_DYNAMIC"),
159 Instruction::KeyValueShortText(data) => {
160 write!(f, "KEY_VALUE_SHORT_TEXT {}", data.0)
161 }
162 Instruction::CloseAndStore => write!(f, "CLOSE_AND_STORE"),
163
164 Instruction::Add => write!(f, "ADD"),
166 Instruction::Subtract => write!(f, "SUBTRACT"),
167 Instruction::Multiply => write!(f, "MULTIPLY"),
168 Instruction::Divide => write!(f, "DIVIDE"),
169
170 Instruction::StructuralEqual => write!(f, "STRUCTURAL_EQUAL"),
172 Instruction::Equal => write!(f, "EQUAL"),
173 Instruction::NotStructuralEqual => {
174 write!(f, "NOT_STRUCTURAL_EQUAL")
175 }
176 Instruction::NotEqual => write!(f, "NOT_EQUAL"),
177 Instruction::Is => write!(f, "IS"),
178 Instruction::Matches => write!(f, "MATCHES"),
179
180 Instruction::AllocateSlot(address) => {
181 write!(f, "ALLOCATE_SLOT {}", address.0)
182 }
183 Instruction::GetSlot(address) => {
184 write!(f, "GET_SLOT {}", address.0)
185 }
186 Instruction::DropSlot(address) => {
187 write!(f, "DROP_SLOT {}", address.0)
188 }
189 Instruction::SetSlot(address) => {
190 write!(f, "SET_SLOT {}", address.0)
191 }
192 Instruction::AssignToReference(operator) => {
193 write!(f, "ASSIGN_REFERENCE ({})", operator)
194 }
195 Instruction::Deref => write!(f, "DEREF"),
196 Instruction::GetRef(address) => {
197 write!(
198 f,
199 "GET_REF [{}:{}]",
200 address.endpoint,
201 hex::encode(address.id)
202 )
203 }
204 Instruction::GetLocalRef(address) => {
205 write!(
206 f,
207 "GET_LOCAL_REF [origin_id: {}]",
208 hex::encode(address.id)
209 )
210 }
211 Instruction::GetInternalRef(address) => {
212 write!(
213 f,
214 "GET_INTERNAL_REF [internal_id: {}]",
215 hex::encode(address.id)
216 )
217 }
218 Instruction::CreateRef => write!(f, "CREATE_REF"),
219 Instruction::CreateRefMut => write!(f, "CREATE_REF_MUT"),
220 Instruction::CreateRefFinal => write!(f, "CREATE_REF_FINAL"),
221 Instruction::GetOrCreateRef(data) => {
222 write!(
223 f,
224 "GET_OR_CREATE_REF [{}:{}, block_size: {}]",
225 data.address.endpoint,
226 hex::encode(data.address.id),
227 data.create_block_size
228 )
229 }
230 Instruction::GetOrCreateRefMut(data) => {
231 write!(
232 f,
233 "GET_OR_CREATE_REF_MUT [{}:{}, block_size: {}]",
234 data.address.endpoint,
235 hex::encode(data.address.id),
236 data.create_block_size
237 )
238 }
239 Instruction::ExecutionBlock(block) => {
240 write!(
241 f,
242 "EXECUTION_BLOCK (length: {}, injected_slot_count: {})",
243 block.length, block.injected_slot_count
244 )
245 }
246 Instruction::RemoteExecution => write!(f, "REMOTE_EXECUTION"),
247 Instruction::AddAssign(address) => {
248 write!(f, "ADD_ASSIGN {}", address.0)
249 }
250 Instruction::SubtractAssign(address) => {
251 write!(f, "SUBTRACT_ASSIGN {}", address.0)
252 }
253 Instruction::MultiplyAssign(address) => {
254 write!(f, "MULTIPLY_ASSIGN {}", address.0)
255 }
256 Instruction::DivideAssign(address) => {
257 write!(f, "DIVIDE_ASSIGN {}", address.0)
258 }
259 Instruction::TypeInstructions(instr) => {
260 let instr_strings: Vec<String> =
261 instr.iter().map(|i| i.to_string()).collect();
262 write!(f, "TYPE_INSTRUCTIONS [{}]", instr_strings.join(", "))
263 }
264 Instruction::TypeExpression(instr) => {
265 let instr_strings: Vec<String> =
266 instr.iter().map(|i| i.to_string()).collect();
267 write!(f, "TYPE_EXPRESSION [{}]", instr_strings.join(", "))
268 }
269 Instruction::UnaryMinus => write!(f, "-"),
270 Instruction::UnaryPlus => write!(f, "+"),
271 Instruction::BitwiseNot => write!(f, "BITWISE_NOT"),
272 }
273 }
274}
275
276#[derive(Clone, Debug, PartialEq)]
277pub enum TypeInstruction {
278 LiteralText(TextData),
279 LiteralInteger(IntegerData),
280 ListStart,
281 ScopeEnd,
282}
283
284impl Display for TypeInstruction {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 match self {
287 TypeInstruction::LiteralText(data) => {
288 write!(f, "LITERAL_TEXT {}", data.0)
289 }
290 TypeInstruction::LiteralInteger(data) => {
291 write!(f, "LITERAL_INTEGER {}", data.0)
292 }
293 TypeInstruction::ListStart => write!(f, "LIST_START"),
294 TypeInstruction::ScopeEnd => write!(f, "SCOPE_END"),
295 }
296 }
297}
298
299#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
300#[brw(little)]
301pub struct Int8Data(pub i8);
302
303#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
304#[brw(little)]
305pub struct Int16Data(pub i16);
306
307#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
308#[brw(little)]
309pub struct Int32Data(pub i32);
310
311#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
312#[brw(little)]
313pub struct Int64Data(pub i64);
314
315#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
316#[brw(little)]
317pub struct Int128Data(pub i128);
318
319#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
320#[brw(little)]
321pub struct UInt8Data(pub u8);
322
323#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
324#[brw(little)]
325pub struct UInt16Data(pub u16);
326
327#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
328#[brw(little)]
329pub struct UInt32Data(pub u32);
330
331#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
332#[brw(little)]
333pub struct UInt64Data(pub u64);
334
335#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
336#[brw(little)]
337pub struct UInt128Data(pub u128);
338
339#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
340#[brw(little)]
341pub struct Float32Data(pub f32);
342
343#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
344#[brw(little)]
345pub struct Float64Data(pub f64);
346
347#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
348#[brw(little)]
349pub struct FloatAsInt16Data(pub i16);
350
351#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
352#[brw(little)]
353pub struct FloatAsInt32Data(pub i32);
354
355#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
356#[brw(little)]
357pub struct DecimalData(pub Decimal);
358
359#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
360#[brw(little)]
361pub struct IntegerData(pub Integer);
362
363#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
364#[brw(little)]
365pub struct ShortTextDataRaw {
366 pub length: u8,
367 #[br(count = length)]
368 pub text: Vec<u8>,
369}
370
371#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
372#[brw(little)]
373pub struct TextDataRaw {
374 pub length: u32,
375 #[br(count = length)]
376 pub text: Vec<u8>,
377}
378
379#[derive(Clone, Debug, PartialEq)]
380pub struct ShortTextData(pub String);
381
382#[derive(Clone, Debug, PartialEq)]
383pub struct TextData(pub String);
384
385#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
386#[brw(little)]
387pub struct InstructionCloseAndStore {
388 pub instruction: Int8Data,
389}
390
391#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
392#[brw(little)]
393pub struct SlotAddress(pub u32);
394
395#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
396#[brw(little)]
397pub struct RawFullPointerAddress {
398 pub endpoint: Endpoint,
399 pub id: [u8; 5],
400}
401
402#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
403#[brw(little)]
404pub struct RawLocalPointerAddress {
405 pub id: [u8; 5],
406}
407
408#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
409#[brw(little)]
410pub struct RawInternalPointerAddress {
411 pub id: [u8; 3],
412}
413
414#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
415#[brw(little)]
416pub struct GetOrCreateRefData {
417 pub address: RawFullPointerAddress,
418 pub create_block_size: u64,
419}
420
421#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
422#[brw(little)]
423pub struct ExecutionBlockData {
424 pub length: u32,
425 pub injected_slot_count: u32,
426 #[br(count = injected_slot_count)]
427 pub injected_slots: Vec<u32>,
428 #[br(count = length)]
429 pub body: Vec<u8>,
430}
431
432#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
433#[brw(little)]
434pub struct ApplyData {
435 pub arg_count: u16,
436}