1use crate::global::operators::AssignmentOperator;
2use crate::global::type_instruction_codes::TypeMutabilityCode;
3use crate::stdlib::string::String;
4use crate::stdlib::vec::Vec;
5use crate::values::core_values::decimal::Decimal;
6use crate::values::core_values::endpoint::EndpointParsingError;
7use crate::values::core_values::integer::Integer;
8use crate::values::core_values::{
9 decimal::utils::decimal_to_string, endpoint::Endpoint,
10};
11use binrw::{BinRead, BinWrite};
12use core::fmt::Display;
13use core::prelude::rust_2024::*;
14use datex_core::values::pointer::PointerAddress;
15use serde::{Deserialize, Serialize};
16
17#[derive(Clone, Debug, PartialEq)]
18pub enum Instruction {
19 RegularInstruction(RegularInstruction),
21 TypeInstruction(TypeInstruction),
23}
24
25impl Display for Instruction {
26 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27 match self {
28 Instruction::RegularInstruction(instr) => {
29 core::write!(f, "{}", instr)
30 }
31 Instruction::TypeInstruction(instr) => {
32 core::write!(f, "TYPE_INSTRUCTION {}", instr)
33 }
34 }
35 }
36}
37
38impl From<RegularInstruction> for Instruction {
39 fn from(instruction: RegularInstruction) -> Self {
40 Instruction::RegularInstruction(instruction)
41 }
42}
43
44impl From<TypeInstruction> for Instruction {
45 fn from(instruction: TypeInstruction) -> Self {
46 Instruction::TypeInstruction(instruction)
47 }
48}
49
50#[derive(Clone, Debug, PartialEq)]
51pub enum RegularInstruction {
52 Int8(Int8Data),
54 Int16(Int16Data),
55 Int32(Int32Data),
56 Int64(Int64Data),
57 Int128(Int128Data),
58
59 UInt8(UInt8Data),
61 UInt16(UInt16Data),
62 UInt32(UInt32Data),
63 UInt64(UInt64Data),
64 UInt128(UInt128Data),
65
66 BigInteger(IntegerData),
68
69 Integer(IntegerData),
71
72 Endpoint(Endpoint),
73
74 DecimalF32(Float32Data),
75 DecimalF64(Float64Data),
76 DecimalAsInt16(FloatAsInt16Data),
77 DecimalAsInt32(FloatAsInt32Data),
78 BigDecimal(DecimalData),
79 Decimal(DecimalData),
81
82 RemoteExecution(InstructionBlockData),
83
84 ShortText(ShortTextData),
85 Text(TextData),
86 True,
87 False,
88 Null,
89 Statements(StatementsData),
90 ShortStatements(StatementsData),
91 UnboundedStatements,
92 UnboundedStatementsEnd(bool),
93 List(ListData),
94 ShortList(ListData),
95 Map(MapData),
96 ShortMap(MapData),
97
98 KeyValueDynamic,
99 KeyValueShortText(ShortTextData),
100
101 Add,
103 Subtract,
104 Multiply,
105 Divide,
106
107 UnaryMinus,
110 UnaryPlus,
112 BitwiseNot,
113
114 Apply(ApplyData),
115
116 GetPropertyText(ShortTextData),
117 SetPropertyText(ShortTextData),
118 SetPropertyDynamic,
119
120 GetPropertyIndex(UInt32Data),
121 SetPropertyIndex(UInt32Data),
122 GetPropertyDynamic,
123
124 Is,
126 Matches,
127 StructuralEqual,
128 Equal,
129 NotStructuralEqual,
130 NotEqual,
131
132 AddAssign(SlotAddress),
134 SubtractAssign(SlotAddress),
135 MultiplyAssign(SlotAddress),
136 DivideAssign(SlotAddress),
137
138 CreateRef,
139 CreateRefMut,
140
141 GetRef(RawFullPointerAddress),
143 GetLocalRef(RawLocalPointerAddress),
144 GetInternalRef(RawInternalPointerAddress),
145
146 GetOrCreateRef(GetOrCreateRefData),
148 GetOrCreateRefMut(GetOrCreateRefData),
150
151 AllocateSlot(SlotAddress),
152 GetSlot(SlotAddress),
153 DropSlot(SlotAddress),
154 SetSlot(SlotAddress),
155
156 GetInternalSlot(SlotAddress),
157
158 SetReferenceValue(AssignmentOperator),
159 Deref,
160
161 TypedValue,
162 TypeExpression,
163}
164
165impl Display for RegularInstruction {
166 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
167 match self {
168 RegularInstruction::Int8(data) => {
169 core::write!(f, "INT_8 {}", data.0)
170 }
171 RegularInstruction::Int16(data) => {
172 core::write!(f, "INT_16 {}", data.0)
173 }
174 RegularInstruction::Int32(data) => {
175 core::write!(f, "INT_32 {}", data.0)
176 }
177 RegularInstruction::Int64(data) => {
178 core::write!(f, "INT_64 {}", data.0)
179 }
180 RegularInstruction::Int128(data) => {
181 core::write!(f, "INT_128 {}", data.0)
182 }
183
184 RegularInstruction::UInt8(data) => {
185 core::write!(f, "UINT_8 {}", data.0)
186 }
187 RegularInstruction::UInt16(data) => {
188 core::write!(f, "UINT_16 {}", data.0)
189 }
190 RegularInstruction::UInt32(data) => {
191 core::write!(f, "UINT_32 {}", data.0)
192 }
193 RegularInstruction::UInt64(data) => {
194 core::write!(f, "UINT_64 {}", data.0)
195 }
196 RegularInstruction::UInt128(data) => {
197 core::write!(f, "UINT_128 {}", data.0)
198 }
199
200 RegularInstruction::Apply(count) => {
201 core::write!(f, "APPLY {}", count.arg_count)
202 }
203
204 RegularInstruction::BigInteger(data) => {
205 core::write!(f, "BIG_INTEGER {}", data.0)
206 }
207 RegularInstruction::Integer(data) => {
208 core::write!(f, "INTEGER {}", data.0)
209 }
210 RegularInstruction::Endpoint(data) => {
211 core::write!(f, "ENDPOINT {data}")
212 }
213
214 RegularInstruction::DecimalAsInt16(data) => {
215 core::write!(f, "DECIMAL_AS_INT_16 {}", data.0)
216 }
217 RegularInstruction::DecimalAsInt32(data) => {
218 core::write!(f, "DECIMAL_AS_INT_32 {}", data.0)
219 }
220 RegularInstruction::DecimalF32(data) => {
221 core::write!(
222 f,
223 "DECIMAL_F32 {}",
224 decimal_to_string(data.0, false)
225 )
226 }
227 RegularInstruction::DecimalF64(data) => {
228 core::write!(
229 f,
230 "DECIMAL_F64 {}",
231 decimal_to_string(data.0, false)
232 )
233 }
234 RegularInstruction::BigDecimal(data) => {
235 core::write!(f, "DECIMAL_BIG {}", data.0)
236 }
237 RegularInstruction::Decimal(data) => {
238 core::write!(f, "DECIMAL {}", data.0)
239 }
240 RegularInstruction::ShortText(data) => {
241 core::write!(f, "SHORT_TEXT {}", data.0)
242 }
243 RegularInstruction::Text(data) => {
244 core::write!(f, "TEXT {}", data.0)
245 }
246 RegularInstruction::True => core::write!(f, "TRUE"),
247 RegularInstruction::False => core::write!(f, "FALSE"),
248 RegularInstruction::Null => core::write!(f, "NULL"),
249 RegularInstruction::Statements(data) => {
250 core::write!(f, "STATEMENTS {}", data.statements_count)
251 }
252 RegularInstruction::ShortStatements(data) => {
253 core::write!(f, "SHORT_STATEMENTS {}", data.statements_count)
254 }
255 RegularInstruction::UnboundedStatements => {
256 core::write!(f, "UNBOUNDED_STATEMENTS")
257 }
258 RegularInstruction::UnboundedStatementsEnd(_) => {
259 core::write!(f, "STATEMENTS_END")
260 }
261 RegularInstruction::List(data) => {
262 core::write!(f, "LIST {}", data.element_count)
263 }
264 RegularInstruction::ShortList(data) => {
265 core::write!(f, "SHORT_LIST {}", data.element_count)
266 }
267 RegularInstruction::Map(data) => {
268 core::write!(f, "MAP {}", data.element_count)
269 }
270 RegularInstruction::ShortMap(data) => {
271 core::write!(f, "SHORT_MAP {}", data.element_count)
272 }
273 RegularInstruction::KeyValueDynamic => {
274 core::write!(f, "KEY_VALUE_DYNAMIC")
275 }
276 RegularInstruction::KeyValueShortText(data) => {
277 core::write!(f, "KEY_VALUE_SHORT_TEXT {}", data.0)
278 }
279 RegularInstruction::Add => core::write!(f, "ADD"),
281 RegularInstruction::Subtract => core::write!(f, "SUBTRACT"),
282 RegularInstruction::Multiply => core::write!(f, "MULTIPLY"),
283 RegularInstruction::Divide => core::write!(f, "DIVIDE"),
284
285 RegularInstruction::StructuralEqual => {
287 core::write!(f, "STRUCTURAL_EQUAL")
288 }
289 RegularInstruction::Equal => core::write!(f, "EQUAL"),
290 RegularInstruction::NotStructuralEqual => {
291 core::write!(f, "NOT_STRUCTURAL_EQUAL")
292 }
293 RegularInstruction::NotEqual => core::write!(f, "NOT_EQUAL"),
294 RegularInstruction::Is => core::write!(f, "IS"),
295 RegularInstruction::Matches => core::write!(f, "MATCHES"),
296
297 RegularInstruction::AllocateSlot(address) => {
298 core::write!(f, "ALLOCATE_SLOT {}", address.0)
299 }
300 RegularInstruction::GetSlot(address) => {
301 core::write!(f, "GET_SLOT {}", address.0)
302 }
303 RegularInstruction::GetInternalSlot(address) => {
304 core::write!(f, "GET_INTERNAL_SLOT {}", address.0)
305 }
306 RegularInstruction::DropSlot(address) => {
307 core::write!(f, "DROP_SLOT {}", address.0)
308 }
309 RegularInstruction::SetSlot(address) => {
310 core::write!(f, "SET_SLOT {}", address.0)
311 }
312 RegularInstruction::SetReferenceValue(operator) => {
313 core::write!(f, "SET_REFERENCE_VALUE ({})", operator)
314 }
315 RegularInstruction::Deref => core::write!(f, "DEREF"),
316 RegularInstruction::GetRef(address) => {
317 core::write!(
318 f,
319 "GET_REF [{}:{}]",
320 address.endpoint().expect("Invalid endpoint"),
321 hex::encode(address.id)
322 )
323 }
324 RegularInstruction::GetLocalRef(address) => {
325 core::write!(
326 f,
327 "GET_LOCAL_REF [origin_id: {}]",
328 hex::encode(address.id)
329 )
330 }
331 RegularInstruction::GetInternalRef(address) => {
332 core::write!(
333 f,
334 "GET_INTERNAL_REF [internal_id: {}]",
335 hex::encode(address.id)
336 )
337 }
338 RegularInstruction::CreateRef => core::write!(f, "CREATE_REF"),
339 RegularInstruction::CreateRefMut => {
340 core::write!(f, "CREATE_REF_MUT")
341 }
342 RegularInstruction::GetOrCreateRef(data) => {
343 core::write!(
344 f,
345 "GET_OR_CREATE_REF [{}, block_size: {}]",
346 hex::encode(data.address.id),
347 data.create_block_size
348 )
349 }
350 RegularInstruction::GetOrCreateRefMut(data) => {
351 core::write!(
352 f,
353 "GET_OR_CREATE_REF_MUT [{}, block_size: {}]",
354 hex::encode(data.address.id),
355 data.create_block_size
356 )
357 }
358 RegularInstruction::RemoteExecution(block) => {
359 core::write!(
360 f,
361 "REMOTE_EXECUTION (length: {}, injected_slot_count: {})",
362 block.length,
363 block.injected_slot_count
364 )
365 }
366 RegularInstruction::AddAssign(address) => {
367 core::write!(f, "ADD_ASSIGN {}", address.0)
368 }
369 RegularInstruction::SubtractAssign(address) => {
370 core::write!(f, "SUBTRACT_ASSIGN {}", address.0)
371 }
372 RegularInstruction::MultiplyAssign(address) => {
373 core::write!(f, "MULTIPLY_ASSIGN {}", address.0)
374 }
375 RegularInstruction::DivideAssign(address) => {
376 core::write!(f, "DIVIDE_ASSIGN {}", address.0)
377 }
378 RegularInstruction::UnaryMinus => core::write!(f, "-"),
379 RegularInstruction::UnaryPlus => core::write!(f, "+"),
380 RegularInstruction::BitwiseNot => core::write!(f, "BITWISE_NOT"),
381 RegularInstruction::TypedValue => core::write!(f, "TYPED_VALUE"),
382 RegularInstruction::TypeExpression => {
383 core::write!(f, "TYPE_EXPRESSION")
384 }
385 RegularInstruction::GetPropertyIndex(uint_32_data) => {
386 core::write!(f, "GET_PROPERTY_INDEX {}", uint_32_data.0)
387 }
388 RegularInstruction::SetPropertyIndex(uint_32_data) => {
389 core::write!(f, "SET_PROPERTY_INDEX {}", uint_32_data.0)
390 }
391 RegularInstruction::GetPropertyText(short_text_data) => {
392 core::write!(f, "GET_PROPERTY_TEXT {}", short_text_data.0)
393 }
394 RegularInstruction::SetPropertyText(short_text_data) => {
395 core::write!(f, "SET_PROPERTY_TEXT {}", short_text_data.0)
396 }
397 RegularInstruction::GetPropertyDynamic => {
398 core::write!(f, "GET_PROPERTY_DYNAMIC")
399 }
400 RegularInstruction::SetPropertyDynamic => {
401 core::write!(f, "SET_PROPERTY_DYNAMIC")
402 }
403 }
404 }
405}
406
407#[derive(Clone, Debug, PartialEq)]
408pub enum TypeInstruction {
409 ImplType(ImplTypeData),
410 TypeReference(TypeReferenceData),
411 LiteralText(TextData),
412 LiteralInteger(IntegerData),
413 List(ListData),
414 }
416
417impl Display for TypeInstruction {
418 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
419 match self {
420 TypeInstruction::LiteralText(data) => {
421 core::write!(f, "LITERAL_TEXT {}", data.0)
422 }
423 TypeInstruction::LiteralInteger(data) => {
424 core::write!(f, "LITERAL_INTEGER {}", data.0)
425 }
426 TypeInstruction::List(data) => {
427 core::write!(f, "LIST {}", data.element_count)
428 }
429 TypeInstruction::TypeReference(reference_data) => {
430 core::write!(
431 f,
432 "TYPE_REFERENCE mutability: {}, address: {}",
433 reference_data.metadata.mutability,
434 PointerAddress::from(&reference_data.address)
435 )
436 }
437 TypeInstruction::ImplType(data) => {
438 core::write!(f, "IMPL_TYPE ({} impls)", data.impl_count)
439 }
440 }
441 }
442}
443
444#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
445#[brw(little)]
446pub struct Int8Data(pub i8);
447
448#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
449#[brw(little)]
450pub struct Int16Data(pub i16);
451
452#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
453#[brw(little)]
454pub struct Int32Data(pub i32);
455
456#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
457#[brw(little)]
458pub struct Int64Data(pub i64);
459
460#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
461#[brw(little)]
462pub struct Int128Data(pub i128);
463
464#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
465#[brw(little)]
466pub struct UInt8Data(pub u8);
467
468#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
469#[brw(little)]
470pub struct UInt16Data(pub u16);
471
472#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
473#[brw(little)]
474pub struct UInt32Data(pub u32);
475
476#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
477#[brw(little)]
478pub struct UInt64Data(pub u64);
479
480#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
481#[brw(little)]
482pub struct UInt128Data(pub u128);
483
484#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
485#[brw(little)]
486pub struct Float32Data(pub f32);
487
488#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
489#[brw(little)]
490pub struct Float64Data(pub f64);
491
492#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
493#[brw(little)]
494pub struct FloatAsInt16Data(pub i16);
495
496#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
497#[brw(little)]
498pub struct FloatAsInt32Data(pub i32);
499
500#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
501#[brw(little)]
502pub struct DecimalData(pub Decimal);
503
504#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
505#[brw(little)]
506pub struct IntegerData(pub Integer);
507
508#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
509#[brw(little)]
510pub struct ShortTextDataRaw {
511 pub length: u8,
512 #[br(count = length)]
513 pub text: Vec<u8>,
514}
515
516#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
517#[brw(little)]
518pub struct TextDataRaw {
519 pub length: u32,
520 #[br(count = length)]
521 pub text: Vec<u8>,
522}
523
524#[derive(Clone, Debug, PartialEq)]
525pub struct ShortTextData(pub String);
526
527#[derive(Clone, Debug, PartialEq)]
528pub struct TextData(pub String);
529
530#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
531#[brw(little)]
532pub struct ShortListData {
533 pub element_count: u8,
534}
535
536#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
537#[brw(little)]
538pub struct StatementsData {
539 pub statements_count: u32,
540 #[br(map = |x: u8| x != 0)]
541 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
542 pub terminated: bool,
543}
544
545#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
546#[brw(little)]
547pub struct UnboundedStatementsData {
548 #[br(map = |x: u8| x != 0)]
549 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
550 pub terminated: bool,
551}
552
553#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
554#[brw(little)]
555pub struct ShortStatementsData {
556 pub statements_count: u8,
557 #[br(map = |x: u8| x != 0)]
558 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
559 pub terminated: bool,
560}
561
562#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
563#[brw(little)]
564pub struct ListData {
565 pub element_count: u32,
566}
567
568#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
569#[brw(little)]
570pub struct ShortMapData {
571 pub element_count: u8,
572}
573
574#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
575#[brw(little)]
576pub struct MapData {
577 pub element_count: u32,
578}
579
580#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
581#[brw(little)]
582pub struct InstructionCloseAndStore {
583 pub instruction: Int8Data,
584}
585
586#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
587#[brw(little)]
588pub struct SlotAddress(pub u32);
589
590#[derive(
591 BinRead, BinWrite, Clone, Debug, PartialEq, Serialize, Deserialize,
592)]
593#[brw(little)]
594pub struct RawFullPointerAddress {
595 pub id: [u8; 26],
596}
597impl RawFullPointerAddress {
598 pub fn endpoint(&self) -> Result<Endpoint, EndpointParsingError> {
599 let mut endpoint = [0u8; 21];
600 endpoint.copy_from_slice(&self.id[0..21]);
601 Endpoint::from_slice(endpoint)
602 }
603}
604
605#[derive(Debug, Clone, PartialEq)]
606pub struct PointerAddressConversionError;
607
608impl TryFrom<PointerAddress> for RawFullPointerAddress {
609 type Error = PointerAddressConversionError;
610 fn try_from(ptr: PointerAddress) -> Result<Self, Self::Error> {
611 match ptr {
612 PointerAddress::Remote(bytes) => {
613 Ok(RawFullPointerAddress { id: bytes })
614 }
615 _ => Err(PointerAddressConversionError),
616 }
617 }
618}
619
620#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
621#[brw(little)]
622pub struct RawLocalPointerAddress {
623 pub id: [u8; 5],
624}
625
626#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
627#[brw(little)]
628pub struct RawInternalPointerAddress {
629 pub id: [u8; 3],
630}
631
632#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
633#[brw(little)]
634pub enum RawPointerAddress {
635 #[br(magic = 120u8)] Full(RawFullPointerAddress),
637 #[br(magic = 121u8)] Internal(RawInternalPointerAddress),
639 #[br(magic = 122u8)] Local(RawLocalPointerAddress),
641}
642
643#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
644#[brw(little)]
645pub struct GetOrCreateRefData {
646 pub address: RawFullPointerAddress,
647 pub create_block_size: u64,
648}
649
650#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
651#[brw(little)]
652pub struct InstructionBlockData {
653 pub length: u32,
654 pub injected_slot_count: u32,
655 #[br(count = injected_slot_count)]
656 pub injected_slots: Vec<u32>,
657 #[br(count = length)]
658 pub body: Vec<u8>,
659}
660
661#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
662#[brw(little)]
663pub struct ApplyData {
664 pub arg_count: u16,
665}
666
667#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
668#[brw(little)]
669pub struct ImplTypeData {
670 pub metadata: TypeMetadata,
671 pub impl_count: u8,
672 #[br(count = impl_count)]
673 pub impls: Vec<RawPointerAddress>,
674}
675
676#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
677#[brw(little)]
678pub struct TypeReferenceData {
679 pub metadata: TypeMetadata,
680 pub address: RawPointerAddress,
681}
682
683#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
684#[brw(little)]
685pub struct TypeMetadata {
686 pub mutability: TypeMutabilityCode,
687}