1use crate::data::position::Position;
2use crate::data::{
3 data::{init_child_context, init_child_scope, Data},
4 literal,
5 literal::ContentType,
6 primitive::{
7 Primitive, PrimitiveBoolean, PrimitiveClosure, PrimitiveInt, PrimitiveNull,
8 PrimitiveString, PrimitiveType, Right,
9 },
10 tokens::TYPES,
11 ArgsType, Interval, Literal, MemoryType, Message, MessageData, MSG,
12};
13use crate::error_format::*;
14use crate::interpreter::variable_handler::resolve_csml_object::{
15 exec_closure, insert_args_in_scope_memory, insert_memories_in_scope_memory,
16};
17use phf::phf_map;
18use rand::seq::SliceRandom;
19use rand::Rng;
20use serde::{Deserialize, Serialize};
21use serde_json::json;
22use std::cmp::Ordering;
23use std::usize;
24use std::{collections::HashMap, sync::mpsc};
25
26type PrimitiveMethod = fn(
31 array: &mut PrimitiveArray,
32 args: &HashMap<String, Literal>,
33 additional_info: &Option<HashMap<String, Literal>>,
34 interval: Interval,
35 data: &mut Data,
36 msg_data: &mut MessageData,
37 sender: &Option<mpsc::Sender<MSG>>,
38) -> Result<Literal, ErrorInfo>;
39
40const FUNCTIONS: phf::Map<&'static str, (PrimitiveMethod, Right)> = phf_map! {
41 "is_number" => (PrimitiveArray::is_number as PrimitiveMethod, Right::Read),
42 "is_int" => (PrimitiveArray::is_int as PrimitiveMethod, Right::Read),
43 "is_float" => (PrimitiveArray::is_float as PrimitiveMethod, Right::Read),
44 "type_of" => (PrimitiveArray::type_of as PrimitiveMethod, Right::Read),
45 "get_info" => (PrimitiveArray::get_info as PrimitiveMethod, Right::Read),
46 "is_error" => (PrimitiveArray::is_error as PrimitiveMethod, Right::Read),
47 "to_string" => (PrimitiveArray::to_string as PrimitiveMethod, Right::Read),
48
49 "init" => (PrimitiveArray::init as PrimitiveMethod, Right::Read),
50 "find" => (PrimitiveArray::find as PrimitiveMethod, Right::Read),
51 "is_empty" => (PrimitiveArray::is_empty as PrimitiveMethod, Right::Read),
52 "insert_at" => (PrimitiveArray::insert_at as PrimitiveMethod, Right::Write),
53 "index_of" => (PrimitiveArray::index_of as PrimitiveMethod, Right::Read),
54 "join" => (PrimitiveArray::join as PrimitiveMethod, Right::Read),
55 "length" => (PrimitiveArray::length as PrimitiveMethod, Right::Read),
56 "one_of" => (PrimitiveArray::one_of as PrimitiveMethod, Right::Read),
57 "push" => (PrimitiveArray::push as PrimitiveMethod, Right::Write),
58 "pop" => (PrimitiveArray::pop as PrimitiveMethod, Right::Write),
59 "remove_at" => (PrimitiveArray::remove_at as PrimitiveMethod, Right::Write),
60 "slice" => (PrimitiveArray::slice as PrimitiveMethod, Right::Read),
61 "shuffle" => (PrimitiveArray::shuffle as PrimitiveMethod, Right::Write),
62 "map" => (PrimitiveArray::map as PrimitiveMethod, Right::Read),
63 "filter" => (PrimitiveArray::filter as PrimitiveMethod, Right::Read),
64 "reduce" => (PrimitiveArray::reduce as PrimitiveMethod, Right::Read),
65 "reverse" => (PrimitiveArray::reverse as PrimitiveMethod, Right::Read),
66 "append" => (PrimitiveArray::append as PrimitiveMethod, Right::Read),
67 "flatten" => (PrimitiveArray::flatten as PrimitiveMethod, Right::Read),
68};
69
70#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
71pub struct PrimitiveArray {
72 pub value: Vec<Literal>,
73}
74
75fn check_index(
80 index: i64,
81 length: i64,
82 flow_name: &str,
83 interval: Interval,
84) -> Result<(), ErrorInfo> {
85 if index.is_negative() {
86 return Err(gen_error_info(
87 Position::new(interval, flow_name),
88 ERROR_ARRAY_NEGATIVE.to_owned(),
89 ));
90 }
91
92 if index > length {
93 return Err(gen_error_info(
94 Position::new(interval, flow_name),
95 ERROR_ARRAY_INDEX.to_owned(),
96 ));
97 }
98
99 Ok(())
100}
101
102impl PrimitiveArray {
103 fn is_number(
104 _array: &mut PrimitiveArray,
105 args: &HashMap<String, Literal>,
106 _additional_info: &Option<HashMap<String, Literal>>,
107 interval: Interval,
108 data: &mut Data,
109 _msg_data: &mut MessageData,
110 _sender: &Option<mpsc::Sender<MSG>>,
111 ) -> Result<Literal, ErrorInfo> {
112 let usage = "is_number() => boolean";
113
114 if !args.is_empty() {
115 return Err(gen_error_info(
116 Position::new(interval, &data.context.flow),
117 format!("usage: {}", usage),
118 ));
119 }
120
121 Ok(PrimitiveBoolean::get_literal(false, interval))
122 }
123
124 fn is_int(
125 _array: &mut PrimitiveArray,
126 args: &HashMap<String, Literal>,
127 _additional_info: &Option<HashMap<String, Literal>>,
128 interval: Interval,
129 data: &mut Data,
130 _msg_data: &mut MessageData,
131 _sender: &Option<mpsc::Sender<MSG>>,
132 ) -> Result<Literal, ErrorInfo> {
133 let usage = "is_int() => boolean";
134
135 if !args.is_empty() {
136 return Err(gen_error_info(
137 Position::new(interval, &data.context.flow),
138 format!("usage: {}", usage),
139 ));
140 }
141
142 Ok(PrimitiveBoolean::get_literal(false, interval))
143 }
144
145 fn is_float(
146 _array: &mut PrimitiveArray,
147 args: &HashMap<String, Literal>,
148 _additional_info: &Option<HashMap<String, Literal>>,
149 interval: Interval,
150 data: &mut Data,
151 _msg_data: &mut MessageData,
152 _sender: &Option<mpsc::Sender<MSG>>,
153 ) -> Result<Literal, ErrorInfo> {
154 let usage = "is_float() => boolean";
155
156 if !args.is_empty() {
157 return Err(gen_error_info(
158 Position::new(interval, &data.context.flow),
159 format!("usage: {}", usage),
160 ));
161 }
162
163 Ok(PrimitiveBoolean::get_literal(false, interval))
164 }
165
166 fn type_of(
167 _array: &mut PrimitiveArray,
168 args: &HashMap<String, Literal>,
169 _additional_info: &Option<HashMap<String, Literal>>,
170 interval: Interval,
171 data: &mut Data,
172 _msg_data: &mut MessageData,
173 _sender: &Option<mpsc::Sender<MSG>>,
174 ) -> Result<Literal, ErrorInfo> {
175 let usage = "type_of() => string";
176
177 if !args.is_empty() {
178 return Err(gen_error_info(
179 Position::new(interval, &data.context.flow),
180 format!("usage: {}", usage),
181 ));
182 }
183
184 Ok(PrimitiveString::get_literal("array", interval))
185 }
186
187 fn get_info(
188 _array: &mut PrimitiveArray,
189 args: &HashMap<String, Literal>,
190 additional_info: &Option<HashMap<String, Literal>>,
191 interval: Interval,
192 data: &mut Data,
193 _msg_data: &mut MessageData,
194 _sender: &Option<mpsc::Sender<MSG>>,
195 ) -> Result<Literal, ErrorInfo> {
196 literal::get_info(args, additional_info, interval, data)
197 }
198
199 fn is_error(
200 _array: &mut PrimitiveArray,
201 _args: &HashMap<String, Literal>,
202 additional_info: &Option<HashMap<String, Literal>>,
203 interval: Interval,
204 _data: &mut Data,
205 _msg_data: &mut MessageData,
206 _sender: &Option<mpsc::Sender<MSG>>,
207 ) -> Result<Literal, ErrorInfo> {
208 match additional_info {
209 Some(map) if map.contains_key("error") => {
210 Ok(PrimitiveBoolean::get_literal(true, interval))
211 }
212 _ => Ok(PrimitiveBoolean::get_literal(false, interval)),
213 }
214 }
215
216 fn to_string(
217 array: &mut PrimitiveArray,
218 args: &HashMap<String, Literal>,
219 _additional_info: &Option<HashMap<String, Literal>>,
220 interval: Interval,
221 data: &mut Data,
222 _msg_data: &mut MessageData,
223 _sender: &Option<mpsc::Sender<MSG>>,
224 ) -> Result<Literal, ErrorInfo> {
225 let usage = "to_string() => string";
226
227 if !args.is_empty() {
228 return Err(gen_error_info(
229 Position::new(interval, &data.context.flow),
230 format!("usage: {}", usage),
231 ));
232 }
233
234 Ok(PrimitiveString::get_literal(&array.to_string(), interval))
235 }
236}
237
238impl PrimitiveArray {
239 fn init(
240 _array: &mut PrimitiveArray,
241 args: &HashMap<String, Literal>,
242 _additional_info: &Option<HashMap<String, Literal>>,
243 interval: Interval,
244 data: &mut Data,
245 _msg_data: &mut MessageData,
246 _sender: &Option<mpsc::Sender<MSG>>,
247 ) -> Result<Literal, ErrorInfo> {
248 let usage = "init(capacity: Int) => [Literal]";
249
250 if args.len() != 1 {
251 return Err(gen_error_info(
252 Position::new(interval, &data.context.flow),
253 format!("usage: {}", usage),
254 ));
255 }
256
257 let capacity = match args.get("arg0") {
258 Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
259 *Literal::get_value::<i64>(
260 &res.primitive,
261 &data.context.flow,
262 interval,
263 ERROR_ARRAY_INSERT_AT.to_owned(),
264 )? as usize
265 }
266 _ => {
267 return Err(gen_error_info(
268 Position::new(interval, &data.context.flow),
269 ERROR_ARRAY_INSERT_AT.to_owned(),
270 ));
271 }
272 };
273
274 let mut vec = Vec::with_capacity(capacity);
275 for _ in 0..capacity {
276 vec.push(PrimitiveNull::get_literal(interval));
277 }
278
279 Ok(PrimitiveArray::get_literal(&vec, interval))
280 }
281
282 fn find(
283 array: &mut PrimitiveArray,
284 args: &HashMap<String, Literal>,
285 _additional_info: &Option<HashMap<String, Literal>>,
286 interval: Interval,
287 data: &mut Data,
288 _msg_data: &mut MessageData,
289 _sender: &Option<mpsc::Sender<MSG>>,
290 ) -> Result<Literal, ErrorInfo> {
291 let usage = "find(value: primitive) => array";
292
293 if array.value.len() + args.len() == usize::MAX {
294 return Err(gen_error_info(
295 Position::new(interval, &data.context.flow),
296 format!("{} {}", ERROR_ARRAY_OVERFLOW, usize::MAX),
297 ));
298 }
299
300 let value = match args.get("arg0") {
301 Some(res) => res,
302 _ => {
303 return Err(gen_error_info(
304 Position::new(interval, &data.context.flow),
305 format!("usage: {}", usage),
306 ));
307 }
308 };
309
310 let mut vector = Vec::new();
311
312 for literal in array.value.iter() {
313 if literal == value {
314 vector.push(literal.to_owned());
315 }
316 }
317
318 if !vector.is_empty() {
319 return Ok(PrimitiveArray::get_literal(&vector, interval));
320 }
321
322 Ok(PrimitiveArray::get_literal(&[], interval))
323 }
324
325 fn is_empty(
326 array: &mut PrimitiveArray,
327 args: &HashMap<String, Literal>,
328 _additional_info: &Option<HashMap<String, Literal>>,
329 interval: Interval,
330 data: &mut Data,
331 _msg_data: &mut MessageData,
332 _sender: &Option<mpsc::Sender<MSG>>,
333 ) -> Result<Literal, ErrorInfo> {
334 let usage = "is_empty() => boolean";
335
336 if !args.is_empty() {
337 return Err(gen_error_info(
338 Position::new(interval, &data.context.flow),
339 format!("usage: {}", usage),
340 ));
341 }
342
343 let result = array.value.is_empty();
344
345 Ok(PrimitiveBoolean::get_literal(result, interval))
346 }
347
348 fn insert_at(
349 array: &mut PrimitiveArray,
350 args: &HashMap<String, Literal>,
351 _additional_info: &Option<HashMap<String, Literal>>,
352 interval: Interval,
353 data: &mut Data,
354 _msg_data: &mut MessageData,
355 _sender: &Option<mpsc::Sender<MSG>>,
356 ) -> Result<Literal, ErrorInfo> {
357 let usage = "insert_at(index: int, value: primitive) => null";
358
359 if args.len() != 2 {
360 return Err(gen_error_info(
361 Position::new(interval, &data.context.flow),
362 format!("usage: {}", usage),
363 ));
364 }
365
366 let index = match args.get("arg0") {
367 Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
368 Literal::get_value::<i64>(
369 &res.primitive,
370 &data.context.flow,
371 interval,
372 ERROR_ARRAY_INSERT_AT.to_owned(),
373 )?
374 }
375 _ => {
376 return Err(gen_error_info(
377 Position::new(interval, &data.context.flow),
378 ERROR_ARRAY_INSERT_AT.to_owned(),
379 ));
380 }
381 };
382
383 let value = match args.get("arg1") {
384 Some(res) => res,
385 _ => {
386 return Err(gen_error_info(
387 Position::new(interval, &data.context.flow),
388 format!("usage: {}", usage),
389 ));
390 }
391 };
392
393 check_index(
394 *index,
395 array.value.len() as i64,
396 &data.context.flow,
397 interval,
398 )?;
399
400 array.value.insert(*index as usize, value.clone());
401
402 Ok(PrimitiveNull::get_literal(interval))
403 }
404
405 fn index_of(
406 array: &mut PrimitiveArray,
407 args: &HashMap<String, Literal>,
408 _additional_info: &Option<HashMap<String, Literal>>,
409 interval: Interval,
410 data: &mut Data,
411 _msg_data: &mut MessageData,
412 _sender: &Option<mpsc::Sender<MSG>>,
413 ) -> Result<Literal, ErrorInfo> {
414 let usage = "index_of(value: primitive) => int";
415
416 if args.len() != 1 {
417 return Err(gen_error_info(
418 Position::new(interval, &data.context.flow),
419 format!("usage: {}", usage),
420 ));
421 }
422
423 let value = match args.get("arg0") {
424 Some(res) => res,
425 None => {
426 return Err(gen_error_info(
427 Position::new(interval, &data.context.flow),
428 format!("usage: {}", usage),
429 ));
430 }
431 };
432
433 for (index, literal) in array.value.iter().enumerate() {
434 if literal == value {
435 return Ok(PrimitiveInt::get_literal(index as i64, interval));
436 }
437 }
438
439 Ok(PrimitiveInt::get_literal(-1, interval))
440 }
441
442 fn join(
443 array: &mut PrimitiveArray,
444 args: &HashMap<String, Literal>,
445 _additional_info: &Option<HashMap<String, Literal>>,
446 interval: Interval,
447 data: &mut Data,
448 _msg_data: &mut MessageData,
449 _sender: &Option<mpsc::Sender<MSG>>,
450 ) -> Result<Literal, ErrorInfo> {
451 let usage = "join(separator: string) => string";
452
453 if args.len() != 1 {
454 return Err(gen_error_info(
455 Position::new(interval, &data.context.flow),
456 format!("usage: {}", usage),
457 ));
458 }
459
460 let separator = match args.get("arg0") {
461 Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveString => {
462 Literal::get_value::<String>(
463 &res.primitive,
464 &data.context.flow,
465 interval,
466 ERROR_ARRAY_JOIN.to_owned(),
467 )?
468 }
469 _ => {
470 return Err(gen_error_info(
471 Position::new(interval, &data.context.flow),
472 ERROR_ARRAY_JOIN.to_owned(),
473 ));
474 }
475 };
476
477 let length = array.value.len();
478 let mut result = String::new();
479
480 for (index, string) in array.value.iter().enumerate() {
481 result.push_str(&string.primitive.to_string());
482
483 if index + 1 != length {
484 result.push_str(separator);
485 }
486 }
487
488 Ok(PrimitiveString::get_literal(&result, interval))
489 }
490
491 fn length(
492 array: &mut PrimitiveArray,
493 args: &HashMap<String, Literal>,
494 _additional_info: &Option<HashMap<String, Literal>>,
495 interval: Interval,
496 data: &mut Data,
497 _msg_data: &mut MessageData,
498 _sender: &Option<mpsc::Sender<MSG>>,
499 ) -> Result<Literal, ErrorInfo> {
500 let usage = "length() => int";
501
502 if !args.is_empty() {
503 return Err(gen_error_info(
504 Position::new(interval, &data.context.flow),
505 format!("usage: {}", usage),
506 ));
507 }
508
509 let result = array.value.len();
510
511 Ok(PrimitiveInt::get_literal(result as i64, interval))
512 }
513
514 fn one_of(
515 array: &mut PrimitiveArray,
516 args: &HashMap<String, Literal>,
517 _additional_info: &Option<HashMap<String, Literal>>,
518 interval: Interval,
519 data: &mut Data,
520 _msg_data: &mut MessageData,
521 _sender: &Option<mpsc::Sender<MSG>>,
522 ) -> Result<Literal, ErrorInfo> {
523 let usage = "one_of() => primitive";
524
525 if !args.is_empty() {
526 return Err(gen_error_info(
527 Position::new(interval, &data.context.flow),
528 format!("usage: {}", usage),
529 ));
530 }
531
532 if let Some(res) = array
533 .value
534 .get(rand::thread_rng().gen_range(0..array.value.len()))
535 {
536 return Ok(res.to_owned());
537 }
538
539 Ok(PrimitiveNull::get_literal(interval))
540 }
541
542 fn push(
543 array: &mut PrimitiveArray,
544 args: &HashMap<String, Literal>,
545 _additional_info: &Option<HashMap<String, Literal>>,
546 interval: Interval,
547 data: &mut Data,
548 _msg_data: &mut MessageData,
549 _sender: &Option<mpsc::Sender<MSG>>,
550 ) -> Result<Literal, ErrorInfo> {
551 let usage = "push(value: primitive) => null";
552
553 if args.len() != 1 {
554 return Err(gen_error_info(
555 Position::new(interval, &data.context.flow),
556 format!("usage: {}", usage),
557 ));
558 }
559
560 let value = match args.get("arg0") {
561 Some(res) => res,
562 None => {
563 return Err(gen_error_info(
564 Position::new(interval, &data.context.flow),
565 format!("usage: {}", usage),
566 ));
567 }
568 };
569
570 if array.value.len() + args.len() == usize::MAX {
571 return Err(gen_error_info(
572 Position::new(interval, &data.context.flow),
573 format!("{} {}", ERROR_ARRAY_OVERFLOW, usize::MAX,),
574 ));
575 }
576
577 array.value.push(value.to_owned());
578
579 Ok(PrimitiveNull::get_literal(interval))
580 }
581
582 fn pop(
583 array: &mut PrimitiveArray,
584 args: &HashMap<String, Literal>,
585 _additional_info: &Option<HashMap<String, Literal>>,
586 interval: Interval,
587 data: &mut Data,
588 _msg_data: &mut MessageData,
589 _sender: &Option<mpsc::Sender<MSG>>,
590 ) -> Result<Literal, ErrorInfo> {
591 let usage = "pop() => primitive";
592
593 if !args.is_empty() {
594 return Err(gen_error_info(
595 Position::new(interval, &data.context.flow),
596 format!("usage: {}", usage),
597 ));
598 }
599
600 match array.value.pop() {
601 Some(literal) => Ok(literal),
602 None => Err(gen_error_info(
603 Position::new(interval, &data.context.flow),
604 ERROR_ARRAY_POP.to_owned(),
605 )),
606 }
607 }
608
609 fn remove_at(
610 array: &mut PrimitiveArray,
611 args: &HashMap<String, Literal>,
612 _additional_info: &Option<HashMap<String, Literal>>,
613 interval: Interval,
614 data: &mut Data,
615 _msg_data: &mut MessageData,
616 _sender: &Option<mpsc::Sender<MSG>>,
617 ) -> Result<Literal, ErrorInfo> {
618 let usage = "remove_at(index: int) => primitive";
619
620 if args.len() != 1 {
621 return Err(gen_error_info(
622 Position::new(interval, &data.context.flow),
623 format!("usage: {}", usage),
624 ));
625 }
626
627 let index = match args.get("arg0") {
628 Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
629 Literal::get_value::<i64>(
630 &res.primitive,
631 &data.context.flow,
632 interval,
633 ERROR_ARRAY_REMOVE_AT.to_owned(),
634 )?
635 }
636 _ => {
637 return Err(gen_error_info(
638 Position::new(interval, &data.context.flow),
639 ERROR_ARRAY_REMOVE_AT.to_owned(),
640 ));
641 }
642 };
643
644 check_index(
645 *index,
646 array.value.len() as i64,
647 &data.context.flow,
648 interval,
649 )?;
650
651 Ok(array.value.remove(*index as usize))
652 }
653
654 fn shuffle(
655 array: &mut PrimitiveArray,
656 args: &HashMap<String, Literal>,
657 _additional_info: &Option<HashMap<String, Literal>>,
658 interval: Interval,
659 data: &mut Data,
660 _msg_data: &mut MessageData,
661 _sender: &Option<mpsc::Sender<MSG>>,
662 ) -> Result<Literal, ErrorInfo> {
663 let usage = "shuffle() => array";
664
665 if !args.is_empty() {
666 return Err(gen_error_info(
667 Position::new(interval, &data.context.flow),
668 format!("usage: {}", usage),
669 ));
670 }
671
672 let mut vector = array.value.to_owned();
673
674 vector.shuffle(&mut rand::thread_rng());
675
676 Ok(PrimitiveArray::get_literal(&vector, interval))
677 }
678
679 fn slice(
680 array: &mut PrimitiveArray,
681 args: &HashMap<String, Literal>,
682 _additional_info: &Option<HashMap<String, Literal>>,
683 interval: Interval,
684 data: &mut Data,
685 _msg_data: &mut MessageData,
686 _sender: &Option<mpsc::Sender<MSG>>,
687 ) -> Result<Literal, ErrorInfo> {
688 let usage = "slice(start: Integer, end: Optional<Integer>) => [Literal]";
689 let len = array.value.len();
690
691 match args.len() {
692 1 => match args.get("arg0") {
693 Some(literal) => {
694 let mut int_start = Literal::get_value::<i64>(
695 &literal.primitive,
696 &data.context.flow,
697 literal.interval,
698 ERROR_SLICE_ARG_INT.to_owned(),
699 )?
700 .to_owned();
701
702 if int_start < 0 {
703 int_start = len as i64 + int_start;
704 }
705
706 let start = match int_start {
707 value if value >= 0 && (value as usize) < len => value as usize,
708 _ => {
709 return Err(gen_error_info(
710 Position::new(interval, &data.context.flow),
711 ERROR_SLICE_ARG_LEN.to_owned(),
712 ))
713 }
714 };
715
716 let value = array.value[start..]
717 .iter()
718 .cloned()
719 .collect::<Vec<Literal>>();
720
721 Ok(PrimitiveArray::get_literal(&value, interval))
722 }
723 _ => Err(gen_error_info(
724 Position::new(interval, &data.context.flow),
725 ERROR_SLICE_ARG_INT.to_owned(),
726 )),
727 },
728 2 => match (args.get("arg0"), args.get("arg1")) {
729 (Some(literal_start), Some(literal_end)) => {
730 let mut int_start = Literal::get_value::<i64>(
731 &literal_start.primitive,
732 &data.context.flow,
733 literal_start.interval,
734 ERROR_SLICE_ARG_INT.to_owned(),
735 )?
736 .to_owned();
737 let mut int_end = Literal::get_value::<i64>(
738 &literal_end.primitive,
739 &data.context.flow,
740 literal_end.interval,
741 ERROR_SLICE_ARG_INT.to_owned(),
742 )?
743 .to_owned();
744
745 if int_start < 0 {
746 int_start = len as i64 + int_start;
747 }
748
749 if int_end.is_negative() {
750 int_end = len as i64 + int_end;
751 }
752 if int_end < int_start {
753 return Err(gen_error_info(
754 Position::new(interval, &data.context.flow),
755 ERROR_SLICE_ARG2.to_owned(),
756 ));
757 }
758
759 let (start, end) = match (int_start, int_end) {
760 (start, end)
761 if int_start >= 0
762 && end >= 0
763 && (start as usize) < len
764 && (end as usize) <= len =>
765 {
766 (start as usize, end as usize)
767 }
768 _ => {
769 return Err(gen_error_info(
770 Position::new(interval, &data.context.flow),
771 ERROR_SLICE_ARG_LEN.to_owned(),
772 ))
773 }
774 };
775 let value = array.value[start..end]
776 .iter()
777 .cloned()
778 .collect::<Vec<Literal>>();
779
780 Ok(PrimitiveArray::get_literal(&value, interval))
781 }
782 _ => Err(gen_error_info(
783 Position::new(interval, &data.context.flow),
784 ERROR_SLICE_ARG_INT.to_owned(),
785 )),
786 },
787 _ => Err(gen_error_info(
788 Position::new(interval, &data.context.flow),
789 format!("usage: {}", usage),
790 )),
791 }
792 }
793
794 fn reverse(
795 array: &mut PrimitiveArray,
796 args: &HashMap<String, Literal>,
797 _additional_info: &Option<HashMap<String, Literal>>,
798 interval: Interval,
799 data: &mut Data,
800 _msg_data: &mut MessageData,
801 _sender: &Option<mpsc::Sender<MSG>>,
802 ) -> Result<Literal, ErrorInfo> {
803 let usage = "reverse() => [Literal]";
804
805 if !args.is_empty() {
806 return Err(gen_error_info(
807 Position::new(interval, &data.context.flow),
808 format!("usage: {}", usage),
809 ));
810 }
811
812 let mut reversed_list = array.value.clone();
813 reversed_list.reverse();
814
815 Ok(PrimitiveArray::get_literal(&reversed_list, interval))
816 }
817
818 fn append(
819 array: &mut PrimitiveArray,
820 args: &HashMap<String, Literal>,
821 _additional_info: &Option<HashMap<String, Literal>>,
822 interval: Interval,
823 data: &mut Data,
824 _msg_data: &mut MessageData,
825 _sender: &Option<mpsc::Sender<MSG>>,
826 ) -> Result<Literal, ErrorInfo> {
827 let usage = "append(other_array: [Literal]) => [Literal]";
828
829 if args.len() != 1 {
830 return Err(gen_error_info(
831 Position::new(interval, &data.context.flow),
832 format!("usage: {}", usage),
833 ));
834 }
835
836 let mut other_array: Vec<Literal> = match args.get("arg0") {
837 Some(res) if res.content_type == "array" => {
838 let value = Literal::get_value::<Vec<Literal>>(
839 &res.primitive,
840 &data.context.flow,
841 interval,
842 ERROR_ARRAY_INSERT_AT.to_owned(),
843 )?;
844
845 (*value).clone().to_vec()
846 }
847 _ => {
848 return Err(gen_error_info(
849 Position::new(interval, &data.context.flow),
850 ERROR_ARRAY_INSERT_AT.to_owned(),
851 ));
852 }
853 };
854
855 let mut new_array = array.value.clone();
856
857 new_array.append(&mut other_array);
858
859 Ok(PrimitiveArray::get_literal(&new_array, interval))
860 }
861
862 fn flatten(
863 array: &mut PrimitiveArray,
864 args: &HashMap<String, Literal>,
865 _additional_info: &Option<HashMap<String, Literal>>,
866 interval: Interval,
867 data: &mut Data,
868 _msg_data: &mut MessageData,
869 _sender: &Option<mpsc::Sender<MSG>>,
870 ) -> Result<Literal, ErrorInfo> {
871 let usage = "flatten() => [Literal]";
872
873 if args.len() != 0 {
874 return Err(gen_error_info(
875 Position::new(interval, &data.context.flow),
876 format!("usage: {}", usage),
877 ));
878 }
879
880 let mut new_array = vec![];
881
882 for lit in array.value.iter() {
883 if lit.content_type == "array" {
884 let value = Literal::get_value::<Vec<Literal>>(
885 &lit.primitive,
886 &data.context.flow,
887 interval,
888 ERROR_ARRAY_INSERT_AT.to_owned(),
889 )?;
890 for elem in value.iter() {
891 new_array.push(elem.to_owned())
892 }
893 } else {
894 new_array.push(lit.to_owned())
895 }
896 }
897
898 Ok(PrimitiveArray::get_literal(&new_array, interval))
899 }
900}
901
902impl PrimitiveArray {
903 fn map(
904 array: &mut PrimitiveArray,
905 args: &HashMap<String, Literal>,
906 _additional_info: &Option<HashMap<String, Literal>>,
907 interval: Interval,
908 data: &mut Data,
909 msg_data: &mut MessageData,
910 sender: &Option<mpsc::Sender<MSG>>,
911 ) -> Result<Literal, ErrorInfo> {
912 let usage = "map(fn) expect one argument of type [Closure]";
913
914 match args.get("arg0") {
915 Some(lit) => {
916 let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
917 &lit.primitive,
918 &data.context.flow,
919 interval,
920 format!("usage: {}", usage),
921 )?;
922
923 let mut vec = vec![];
924 let mut context = init_child_context(&data);
925 let mut step_count = data.step_count.clone();
926 let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
927
928 if let Some(memories) = closure.enclosed_variables.clone() {
929 insert_memories_in_scope_memory(
930 &mut new_scope_data,
931 memories,
932 msg_data,
933 sender,
934 );
935 }
936
937 for (index, value) in array.value.iter().enumerate() {
938 let mut map = HashMap::new();
939 map.insert("arg0".to_owned(), value.to_owned());
940 if closure.args.len() >= 2 {
941 map.insert(
942 "arg1".to_owned(),
943 PrimitiveInt::get_literal(index as i64, interval),
944 );
945 }
946
947 let args = ArgsType::Normal(map);
948 insert_args_in_scope_memory(
949 &mut new_scope_data,
950 &closure.args,
951 &args,
952 msg_data,
953 sender,
954 );
955
956 let result = exec_closure(
957 &closure.func,
958 &closure.args,
959 args,
960 interval,
961 &mut new_scope_data,
962 msg_data,
963 sender,
964 )?;
965 vec.push(result);
966 }
967
968 Ok(PrimitiveArray::get_literal(&vec, interval))
969 }
970 None => Err(gen_error_info(
971 Position::new(interval, &data.context.flow),
972 format!("usage: {}", usage),
973 )),
974 }
975 }
976
977 fn filter(
978 array: &mut PrimitiveArray,
979 args: &HashMap<String, Literal>,
980 _additional_info: &Option<HashMap<String, Literal>>,
981 interval: Interval,
982 data: &mut Data,
983 msg_data: &mut MessageData,
984 sender: &Option<mpsc::Sender<MSG>>,
985 ) -> Result<Literal, ErrorInfo> {
986 let usage = "filter(fn) expect one argument of type [Closure]";
987
988 match args.get("arg0") {
989 Some(lit) => {
990 let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
991 &lit.primitive,
992 &data.context.flow,
993 interval,
994 format!("usage: {}", usage),
995 )?;
996
997 let mut vec = vec![];
998
999 let mut context = init_child_context(&data);
1000 let mut step_count = data.step_count.clone();
1001 let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
1002
1003 if let Some(memories) = closure.enclosed_variables.clone() {
1004 insert_memories_in_scope_memory(
1005 &mut new_scope_data,
1006 memories,
1007 msg_data,
1008 sender,
1009 );
1010 }
1011
1012 for (index, value) in array.value.iter().enumerate() {
1013 let mut map = HashMap::new();
1014 map.insert("arg0".to_owned(), value.to_owned());
1015 if closure.args.len() >= 2 {
1016 map.insert(
1017 "arg1".to_owned(),
1018 PrimitiveInt::get_literal(index as i64, interval),
1019 );
1020 }
1021
1022 let args = ArgsType::Normal(map);
1023
1024 insert_args_in_scope_memory(
1025 &mut new_scope_data,
1026 &closure.args,
1027 &args,
1028 msg_data,
1029 sender,
1030 );
1031
1032 let result = exec_closure(
1033 &closure.func,
1034 &closure.args,
1035 args,
1036 interval,
1037 &mut new_scope_data,
1038 msg_data,
1039 sender,
1040 )?;
1041
1042 if result.primitive.as_bool() {
1043 vec.push(value.clone());
1044 }
1045 }
1046
1047 Ok(PrimitiveArray::get_literal(&vec, interval))
1048 }
1049 None => Err(gen_error_info(
1050 Position::new(interval, &data.context.flow),
1051 format!("usage: {}", usage),
1052 )),
1053 }
1054 }
1055
1056 fn reduce(
1057 array: &mut PrimitiveArray,
1058 args: &HashMap<String, Literal>,
1059 _additional_info: &Option<HashMap<String, Literal>>,
1060 interval: Interval,
1061 data: &mut Data,
1062 msg_data: &mut MessageData,
1063 sender: &Option<mpsc::Sender<MSG>>,
1064 ) -> Result<Literal, ErrorInfo> {
1065 let usage = "reduce(acc, fn) expect tow arguments an initial value and 'Closure' with two arguments: an 'accumulator', and an element";
1066
1067 match (args.get("arg0"), args.get("arg1")) {
1068 (Some(acc), Some(closure)) => {
1069 let mut accumulator = acc.clone();
1070
1071 let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
1072 &closure.primitive,
1073 &data.context.flow,
1074 interval,
1075 format!("usage: {}", usage),
1076 )?;
1077
1078 let mut context = init_child_context(&data);
1079 let mut step_count = data.step_count.clone();
1080 let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
1081
1082 for (index, value) in array.value.iter().enumerate() {
1083 let mut map = HashMap::new();
1084 map.insert("arg0".to_owned(), accumulator);
1085 map.insert("arg1".to_owned(), value.to_owned());
1086
1087 if closure.args.len() >= 2 {
1088 map.insert(
1089 "arg2".to_owned(),
1090 PrimitiveInt::get_literal(index as i64, interval),
1091 );
1092 }
1093
1094 let args = ArgsType::Normal(map);
1095
1096 insert_args_in_scope_memory(
1097 &mut new_scope_data,
1098 &closure.args,
1099 &args,
1100 msg_data,
1101 sender,
1102 );
1103
1104 accumulator = exec_closure(
1105 &closure.func,
1106 &closure.args,
1107 args,
1108 interval,
1109 &mut new_scope_data,
1110 msg_data,
1111 sender,
1112 )?;
1113 }
1114
1115 Ok(accumulator)
1116 }
1117 _ => Err(gen_error_info(
1118 Position::new(interval, &data.context.flow),
1119 format!("usage: {}", usage),
1120 )),
1121 }
1122 }
1123}
1124
1125impl PrimitiveArray {
1130 pub fn new(value: &[Literal]) -> Self {
1131 Self {
1132 value: value.to_owned(),
1133 }
1134 }
1135
1136 pub fn get_literal(vector: &[Literal], interval: Interval) -> Literal {
1137 let primitive = Box::new(PrimitiveArray::new(vector));
1138
1139 Literal {
1140 content_type: "array".to_owned(),
1141 primitive,
1142 additional_info: None,
1143 secure_variable: false,
1144 interval,
1145 }
1146 }
1147}
1148
1149#[typetag::serde]
1154impl Primitive for PrimitiveArray {
1155 fn is_eq(&self, other: &dyn Primitive) -> bool {
1156 if let Some(other) = other.as_any().downcast_ref::<Self>() {
1157 return self.value == other.value;
1158 }
1159
1160 false
1161 }
1162
1163 fn is_cmp(&self, other: &dyn Primitive) -> Option<Ordering> {
1164 if let Some(other) = other.as_any().downcast_ref::<Self>() {
1165 return self.value.partial_cmp(&other.value);
1166 }
1167
1168 None
1169 }
1170
1171 fn do_add(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1172 Err(format!(
1173 "{} {:?} + {:?}",
1174 ERROR_ILLEGAL_OPERATION,
1175 self.get_type(),
1176 other.get_type()
1177 ))
1178 }
1179
1180 fn do_sub(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1181 Err(format!(
1182 "{} {:?} - {:?}",
1183 ERROR_ILLEGAL_OPERATION,
1184 self.get_type(),
1185 other.get_type()
1186 ))
1187 }
1188
1189 fn do_div(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1190 Err(format!(
1191 "{} {:?} / {:?}",
1192 ERROR_ILLEGAL_OPERATION,
1193 self.get_type(),
1194 other.get_type()
1195 ))
1196 }
1197
1198 fn do_mul(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1199 Err(format!(
1200 "{} {:?} * {:?}",
1201 ERROR_ILLEGAL_OPERATION,
1202 self.get_type(),
1203 other.get_type()
1204 ))
1205 }
1206
1207 fn do_rem(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1208 Err(format!(
1209 "{} {:?} % {:?}",
1210 ERROR_ILLEGAL_OPERATION,
1211 self.get_type(),
1212 other.get_type()
1213 ))
1214 }
1215
1216 fn as_debug(&self) -> &dyn std::fmt::Debug {
1217 self
1218 }
1219
1220 fn as_any(&self) -> &dyn std::any::Any {
1221 self
1222 }
1223
1224 fn get_type(&self) -> PrimitiveType {
1225 PrimitiveType::PrimitiveArray
1226 }
1227
1228 fn as_box_clone(&self) -> Box<dyn Primitive> {
1229 Box::new((*self).clone())
1230 }
1231
1232 fn to_json(&self) -> serde_json::Value {
1233 let mut vector: Vec<serde_json::Value> = Vec::new();
1234
1235 for literal in self.value.iter() {
1236 let value = literal.primitive.to_json();
1237
1238 if !TYPES.contains(&&(*literal.content_type)) {
1239 let mut map = serde_json::Map::new();
1240 map.insert(
1241 "content_type".to_owned(),
1242 serde_json::json!(literal.content_type),
1243 );
1244 map.insert("content".to_owned(), value);
1245
1246 vector.push(serde_json::json!(map));
1247 } else {
1248 vector.push(value);
1249 }
1250 }
1251
1252 serde_json::Value::Array(vector)
1253 }
1254
1255 fn format_mem(&self, _content_type: &str, first: bool) -> serde_json::Value {
1256 let mut vector: Vec<serde_json::Value> = Vec::new();
1257
1258 for literal in self.value.iter() {
1259 let content_type = &literal.content_type;
1260 let value = literal.primitive.format_mem(content_type, first);
1261 vector.push(value);
1262 }
1263
1264 serde_json::Value::Array(vector)
1265 }
1266
1267 fn to_string(&self) -> String {
1268 self.to_json().to_string()
1269 }
1270
1271 fn as_bool(&self) -> bool {
1272 true
1273 }
1274
1275 fn get_value(&self) -> &dyn std::any::Any {
1276 &self.value
1277 }
1278
1279 fn get_mut_value(&mut self) -> &mut dyn std::any::Any {
1280 &mut self.value
1281 }
1282
1283 fn to_msg(&self, content_type: String) -> Message {
1284 let vec = self.value.iter().fold(vec![], |mut acc, v| {
1285 acc.push(v.primitive.to_json());
1286 acc
1287 });
1288 Message {
1289 content_type,
1290 content: json!(vec),
1291 }
1292 }
1293
1294 fn do_exec(
1295 &mut self,
1296 name: &str,
1297 args: &HashMap<String, Literal>,
1298 mem_type: &MemoryType,
1299 additional_info: &Option<HashMap<String, Literal>>,
1300 interval: Interval,
1301 _content_type: &ContentType,
1302 data: &mut Data,
1303 msg_data: &mut MessageData,
1304 sender: &Option<mpsc::Sender<MSG>>,
1305 ) -> Result<(Literal, Right), ErrorInfo> {
1306 if let Some((f, right)) = FUNCTIONS.get(name) {
1307 if *mem_type == MemoryType::Constant && *right == Right::Write {
1308 return Err(gen_error_info(
1309 Position::new(interval, &data.context.flow),
1310 format!("{}", ERROR_CONSTANT_MUTABLE_FUNCTION),
1311 ));
1312 } else {
1313 let res = f(
1314 self,
1315 args,
1316 additional_info,
1317 interval,
1318 data,
1319 msg_data,
1320 sender,
1321 )?;
1322
1323 return Ok((res, *right));
1324 }
1325 }
1326
1327 Err(gen_error_info(
1328 Position::new(interval, &data.context.flow),
1329 format!("[{}] {}", name, ERROR_ARRAY_UNKNOWN_METHOD),
1330 ))
1331 }
1332}