1use crate::{
2 core_compiler::type_compiler::{
3 append_type, append_type_definition, append_type_metadata,
4 append_type_space_instruction_code,
5 },
6 global::{
7 instruction_codes::InstructionCode,
8 protocol_structures::instructions::TypeMetadataBin,
9 type_instruction_codes::TypeInstructionCode,
10 },
11 libs::core::{CoreLibPointerId, get_core_lib_type_definition},
12 shared_values::shared_container::SharedContainerMutability,
13 types::definition::TypeDefinition,
14 utils::buffers::{
15 append_f32, append_f64, append_i8, append_i16, append_i32, append_i64,
16 append_i128, append_u8, append_u16, append_u32, append_u64,
17 append_u128,
18 },
19 values::{
20 core_value::CoreValue,
21 core_values::{
22 decimal::{Decimal, typed_decimal::TypedDecimal},
23 endpoint::Endpoint,
24 integer::{Integer, typed_integer::TypedInteger},
25 },
26 value::Value,
27 value_container::ValueContainer,
28 },
29};
30use binrw::{BinWrite, io::Cursor};
31
32use crate::{
33 prelude::*,
34 shared_values::{
35 pointer::PointerReferenceMutability,
36 pointer_address::{PointerAddress, ReferencedPointerAddress},
37 },
38 values::core_values::r#type::TypeMetadata,
39};
40
41pub fn compile_value_container(value_container: &ValueContainer) -> Vec<u8> {
43 let mut buffer = Vec::with_capacity(256);
44 append_value_container(&mut buffer, value_container);
45
46 buffer
47}
48
49pub fn append_value_container(
50 buffer: &mut Vec<u8>,
51 value_container: &ValueContainer,
52) {
53 match value_container {
54 ValueContainer::Local(value) => append_value(buffer, value),
55 ValueContainer::Shared(reference) => {
56 if reference.mutability() == SharedContainerMutability::Mutable {
59 append_instruction_code(
60 buffer,
61 InstructionCode::CREATE_SHARED_MUT,
62 );
63 } else {
64 append_instruction_code(buffer, InstructionCode::CREATE_SHARED);
65 }
66 append_value(buffer, &reference.collapse_to_value().borrow())
69 }
70 }
71}
72
73pub fn append_value(buffer: &mut Vec<u8>, value: &Value) {
74 if !value.has_default_type() {
76 append_type_cast(buffer, &value.actual_type);
77 }
78 match &value.inner {
79 CoreValue::Type(_ty) => {
80 core::todo!("#439 Type value not supported in CompilationContext");
81 }
82 CoreValue::Callable(_callable) => {
83 core::todo!(
84 "#632 Callable value not supported in CompilationContext"
85 );
86 }
87 CoreValue::Integer(integer) => {
88 append_integer(buffer, integer);
93 }
94 CoreValue::TypedInteger(integer) => {
95 append_encoded_integer(buffer, integer);
96 }
97
98 CoreValue::Endpoint(endpoint) => append_endpoint(buffer, endpoint),
99 CoreValue::Decimal(decimal) => append_decimal(buffer, decimal),
100 CoreValue::TypedDecimal(val) => append_encoded_decimal(buffer, val),
101 CoreValue::Boolean(val) => append_boolean(buffer, val.0),
102 CoreValue::Null => {
103 append_instruction_code(buffer, InstructionCode::NULL)
104 }
105 CoreValue::Text(val) => {
106 append_text(buffer, &val.0);
107 }
108 CoreValue::List(val) => {
109 match val.len() {
111 0..=255 => {
112 append_instruction_code(
113 buffer,
114 InstructionCode::SHORT_LIST,
115 );
116 append_u8(buffer, val.len() as u8);
117 }
118 _ => {
119 append_instruction_code(buffer, InstructionCode::LIST);
120 append_u32(buffer, val.len());
121 }
122 }
123
124 for item in val {
125 append_value_container(buffer, item);
126 }
127 }
128 CoreValue::Map(val) => {
129 match val.size() {
131 0..=255 => {
132 append_instruction_code(buffer, InstructionCode::SHORT_MAP);
133 append_u8(buffer, val.size() as u8);
134 }
135 _ => {
136 append_instruction_code(buffer, InstructionCode::MAP);
137 append_u32(buffer, val.size() as u32); }
139 }
140 for (key, value) in val.iter() {
141 append_key_value_pair(
142 buffer,
143 &ValueContainer::from(key),
144 value,
145 );
146 }
147 }
148 CoreValue::Range(range) => {
149 append_instruction_code(buffer, InstructionCode::RANGE);
150 append_value_container(buffer, &range.start);
151 append_value_container(buffer, &range.end);
152 }
153 }
154}
155
156pub fn append_type_cast(buffer: &mut Vec<u8>, ty: &TypeDefinition) {
157 append_instruction_code(buffer, InstructionCode::TYPED_VALUE);
158 let instruction_code = TypeInstructionCode::from(ty);
160 append_type_space_instruction_code(buffer, instruction_code);
161
162 let metadata = TypeMetadataBin::from(&TypeMetadata::default());
164 append_type_metadata(buffer, metadata);
165
166 append_type_definition(buffer, ty);
168}
169
170pub fn append_text(buffer: &mut Vec<u8>, string: &str) {
171 let bytes = string.as_bytes();
172 let len = bytes.len();
173
174 if len < 256 {
175 append_instruction_code(buffer, InstructionCode::SHORT_TEXT);
176 append_u8(buffer, len as u8);
177 } else {
178 append_instruction_code(buffer, InstructionCode::TEXT);
179 append_u32(buffer, len as u32);
180 }
181
182 buffer.extend_from_slice(bytes);
183}
184
185pub fn append_boolean(buffer: &mut Vec<u8>, boolean: bool) {
186 if boolean {
187 append_instruction_code(buffer, InstructionCode::TRUE);
188 } else {
189 append_instruction_code(buffer, InstructionCode::FALSE);
190 }
191}
192
193pub fn append_decimal(buffer: &mut Vec<u8>, decimal: &Decimal) {
194 append_instruction_code(buffer, InstructionCode::DECIMAL);
195 append_big_decimal(buffer, decimal);
196}
197
198pub fn append_big_decimal(buffer: &mut Vec<u8>, decimal: &Decimal) {
199 let original_length = buffer.len();
201 let mut buffer_writer = Cursor::new(&mut *buffer);
202 buffer_writer.set_position(original_length as u64);
204 decimal
205 .write_le(&mut buffer_writer)
206 .expect("Failed to write big decimal");
207}
208
209pub fn append_endpoint(buffer: &mut Vec<u8>, endpoint: &Endpoint) {
210 append_instruction_code(buffer, InstructionCode::ENDPOINT);
211 buffer.extend_from_slice(&endpoint.to_slice());
212}
213
214pub fn append_typed_integer(buffer: &mut Vec<u8>, integer: &TypedInteger) {
216 append_type_cast(
217 buffer,
218 &get_core_lib_type_definition(CoreLibPointerId::from(integer)),
219 );
220 append_encoded_integer(buffer, integer);
221}
222
223pub fn append_integer(buffer: &mut Vec<u8>, integer: &Integer) {
225 append_instruction_code(buffer, InstructionCode::INT);
226 append_big_integer(buffer, integer);
227}
228
229pub fn append_encoded_integer(buffer: &mut Vec<u8>, integer: &TypedInteger) {
231 match integer {
232 TypedInteger::I8(val) => {
233 append_instruction_code(buffer, InstructionCode::INT_8);
234 append_i8(buffer, *val);
235 }
236 TypedInteger::I16(val) => {
237 append_instruction_code(buffer, InstructionCode::INT_16);
238 append_i16(buffer, *val);
239 }
240 TypedInteger::I32(val) => {
241 append_instruction_code(buffer, InstructionCode::INT_32);
242 append_i32(buffer, *val);
243 }
244 TypedInteger::I64(val) => {
245 append_instruction_code(buffer, InstructionCode::INT_64);
246 append_i64(buffer, *val);
247 }
248 TypedInteger::I128(val) => {
249 append_instruction_code(buffer, InstructionCode::INT_128);
250 append_i128(buffer, *val);
251 }
252 TypedInteger::U8(val) => {
253 append_instruction_code(buffer, InstructionCode::UINT_8);
254 append_u8(buffer, *val);
255 }
256 TypedInteger::U16(val) => {
257 append_instruction_code(buffer, InstructionCode::UINT_16);
258 append_u16(buffer, *val);
259 }
260 TypedInteger::U32(val) => {
261 append_instruction_code(buffer, InstructionCode::UINT_32);
262 append_u32(buffer, *val);
263 }
264 TypedInteger::U64(val) => {
265 append_instruction_code(buffer, InstructionCode::UINT_64);
266 append_u64(buffer, *val);
267 }
268 TypedInteger::U128(val) => {
269 append_instruction_code(buffer, InstructionCode::UINT_128);
270 append_u128(buffer, *val);
271 }
272 TypedInteger::IBig(val) => {
273 append_instruction_code(buffer, InstructionCode::INT_BIG);
274 append_big_integer(buffer, val);
275 }
276 }
277}
278
279pub fn append_encoded_decimal(buffer: &mut Vec<u8>, decimal: &TypedDecimal) {
280 fn append_f32_or_f64(buffer: &mut Vec<u8>, decimal: &TypedDecimal) {
281 match decimal {
282 TypedDecimal::F32(val) => {
283 append_float32(buffer, val.into_inner());
284 }
285 TypedDecimal::F64(val) => {
286 append_float64(buffer, val.into_inner());
287 }
288 TypedDecimal::Decimal(val) => {
289 append_instruction_code(buffer, InstructionCode::DECIMAL_BIG);
290 append_big_decimal(buffer, val);
291 }
292 }
293 }
294
295 append_f32_or_f64(buffer, decimal);
296
297 }
317
318pub fn append_float32(buffer: &mut Vec<u8>, float32: f32) {
319 append_instruction_code(buffer, InstructionCode::DECIMAL_F32);
320 append_f32(buffer, float32);
321}
322pub fn append_float64(buffer: &mut Vec<u8>, float64: f64) {
323 append_instruction_code(buffer, InstructionCode::DECIMAL_F64);
324 append_f64(buffer, float64);
325}
326
327pub fn append_big_integer(buffer: &mut Vec<u8>, integer: &Integer) {
328 let original_length = buffer.len();
331 let mut buffer_writer = Cursor::new(&mut *buffer);
332 buffer_writer.set_position(original_length as u64);
334 integer
335 .write_le(&mut buffer_writer)
336 .expect("Failed to write big integer");
337}
338
339pub fn append_typed_decimal(buffer: &mut Vec<u8>, decimal: &TypedDecimal) {
340 append_type_cast(
341 buffer,
342 &get_core_lib_type_definition(CoreLibPointerId::from(decimal)),
343 );
344 append_encoded_decimal(buffer, decimal);
345}
346
347pub fn append_float_as_i16(buffer: &mut Vec<u8>, int: i16) {
348 append_instruction_code(buffer, InstructionCode::DECIMAL_AS_INT_16);
349 append_i16(buffer, int);
350}
351pub fn append_float_as_i32(buffer: &mut Vec<u8>, int: i32) {
352 append_instruction_code(buffer, InstructionCode::DECIMAL_AS_INT_32);
353 append_i32(buffer, int);
354}
355
356pub fn append_get_ref(
357 buffer: &mut Vec<u8>,
358 address: &PointerAddress,
359 mutability: &PointerReferenceMutability,
360) {
361 match address {
362 PointerAddress::Referenced(ReferencedPointerAddress::Internal(id)) => {
363 append_get_internal_ref(buffer, id);
364 }
365 PointerAddress::Owned(local_address) => {
366 append_instruction_code(
367 buffer,
368 InstructionCode::GET_LOCAL_SHARED_REF,
369 );
370 buffer.extend_from_slice(&local_address.address);
371 }
372 PointerAddress::Referenced(ReferencedPointerAddress::Remote(id)) => {
373 append_instruction_code(
374 buffer,
375 match mutability {
376 PointerReferenceMutability::Immutable => {
377 InstructionCode::GET_REMOTE_SHARED_REF
378 }
379 PointerReferenceMutability::Mutable => {
380 InstructionCode::GET_REMOTE_SHARED_REF_MUT
381 }
382 },
383 );
384 buffer.extend_from_slice(id);
385 }
386 }
387}
388
389pub fn append_get_internal_ref(buffer: &mut Vec<u8>, id: &[u8; 3]) {
390 append_instruction_code(buffer, InstructionCode::GET_INTERNAL_SHARED_REF);
391 buffer.extend_from_slice(id);
392}
393
394pub fn append_key_value_pair(
395 buffer: &mut Vec<u8>,
396 key: &ValueContainer,
397 value: &ValueContainer,
398) {
399 match key {
401 ValueContainer::Local(Value {
403 inner: CoreValue::Text(text),
404 ..
405 }) => {
406 append_key_string(buffer, &text.0);
407 }
408 _ => {
409 append_instruction_code(buffer, InstructionCode::KEY_VALUE_DYNAMIC);
410 append_value_container(buffer, key);
411 }
412 }
413 append_value_container(buffer, value);
415}
416
417pub fn append_key_string(buffer: &mut Vec<u8>, key_string: &str) {
418 let bytes = key_string.as_bytes();
419 let len = bytes.len();
420
421 if len < 256 {
422 append_instruction_code(buffer, InstructionCode::KEY_VALUE_SHORT_TEXT);
423 append_u8(buffer, len as u8);
424 buffer.extend_from_slice(bytes);
425 } else {
426 append_instruction_code(buffer, InstructionCode::KEY_VALUE_DYNAMIC);
427 append_text(buffer, key_string);
428 }
429}
430
431pub fn append_instruction_code(buffer: &mut Vec<u8>, code: InstructionCode) {
432 append_u8(buffer, code as u8);
433}