datex_core/global/protocol_structures/
instructions.rs

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    // signed integers
13    Int8(Int8Data),
14    Int16(Int16Data),
15    Int32(Int32Data),
16    Int64(Int64Data),
17    Int128(Int128Data),
18
19    // unsigned integers
20    UInt8(UInt8Data),
21    UInt16(UInt16Data),
22    UInt32(UInt32Data),
23    UInt64(UInt64Data),
24    UInt128(UInt128Data),
25
26    // big integers
27    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    // binary operator
55    Add,
56    Subtract,
57    Multiply,
58    Divide,
59
60    // unary operator
61    // TODO #432 add missing unary operators
62    UnaryMinus,
63    // TODO #433: Do we need this for op overloading or can we avoid?
64    UnaryPlus,
65    BitwiseNot,
66
67    Apply(ApplyData),
68
69    // comparison operator
70    Is,
71    Matches,
72    StructuralEqual,
73    Equal,
74    NotStructuralEqual,
75    NotEqual,
76
77    // assignment operator
78    AddAssign(SlotAddress),
79    SubtractAssign(SlotAddress),
80    MultiplyAssign(SlotAddress),
81    DivideAssign(SlotAddress),
82
83    CreateRef,
84    CreateRefMut,
85    CreateRefFinal,
86
87    // &ABCDE
88    GetRef(RawFullPointerAddress),
89    GetLocalRef(RawLocalPointerAddress),
90    GetInternalRef(RawInternalPointerAddress),
91
92    // &ABCDE := ...
93    GetOrCreateRef(GetOrCreateRefData),
94    // &mut ABCDE := ...
95    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            // operations
165            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            // equality checks
171            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}