mers_lib/program/run/
tuple.rs1use std::{collections::VecDeque, sync::Arc};
2
3use crate::{
4 data::{self, reference::ReferenceT, tuple::TupleT, Data, MersType, Type},
5 errors::{CheckError, EColor, SourceRange},
6};
7
8use super::MersStatement;
9
10#[derive(Debug)]
11pub struct Tuple {
12 pub pos_in_src: SourceRange,
13 pub elems: Vec<Box<dyn MersStatement>>,
14}
15impl MersStatement for Tuple {
16 fn check_custom(
17 &self,
18 info: &mut super::CheckInfo,
19 init_to: Option<&Type>,
20 ) -> Result<data::Type, super::CheckError> {
21 let mut it = if let Some(init_to) = init_to {
22 let mut vec = (0..self.elems.len())
23 .map(|_| Type::empty())
24 .collect::<VecDeque<_>>();
25 let print_is_part_of = init_to.types.len() > 1;
26 for (t, init_to_ref) in init_to
27 .types
28 .iter()
29 .filter_map(|t| t.as_any().downcast_ref::<ReferenceT>())
30 .flat_map(|r| r.0.types.iter().map(|t| (t, true)))
31 .chain(
32 init_to
33 .types
34 .iter()
35 .filter(|t| !t.as_any().is::<ReferenceT>())
36 .map(|t| (t, false)),
37 )
38 {
39 if let Some(t) = t.as_any().downcast_ref::<TupleT>() {
40 if t.0.len() == self.elems.len() {
41 for (i, e) in t.0.iter().enumerate() {
42 if init_to_ref {
43 vec[i].add(Arc::new(ReferenceT(e.clone())));
44 } else {
45 vec[i].add_all(e);
46 }
47 }
48 } else {
49 return Err(CheckError::new().msg(vec![
50 ("can't init a ".to_owned(), None),
51 ("tuple".to_owned(), Some(EColor::InitTo)),
52 (" with type ".to_owned(), None),
53 (t.simplified_as_string(info), Some(EColor::InitFrom)),
54 (
55 if print_is_part_of {
56 ", which is part of ".to_owned()
57 } else {
58 String::new()
59 },
60 None,
61 ),
62 if print_is_part_of {
63 (init_to.simplified_as_string(info), Some(EColor::InitFrom))
64 } else {
65 (String::new(), None)
66 },
67 (
68 format!(
69 " - only tuples with the same length ({}) can be assigned",
70 self.elems.len()
71 ),
72 None,
73 ),
74 ]));
75 }
76 } else {
77 return Err(CheckError::new().msg(vec![
78 ("can't init a ".to_owned(), None),
79 ("tuple".to_owned(), Some(EColor::InitTo)),
80 (" with type ".to_owned(), None),
81 (t.simplified_as_string(info), Some(EColor::InitFrom)),
82 (
83 if print_is_part_of {
84 ", which is part of ".to_owned()
85 } else {
86 String::new()
87 },
88 None,
89 ),
90 if print_is_part_of {
91 (init_to.simplified_as_string(info), Some(EColor::InitFrom))
92 } else {
93 (String::new(), None)
94 },
95 (" - only tuples can be assigned to tuples".to_owned(), None),
96 ]));
97 }
98 }
99 Some(vec)
100 } else {
101 None
102 };
103 Ok(Type::new(data::tuple::TupleT(
104 self.elems
105 .iter()
106 .map(|v| {
107 v.check(
108 info,
109 if let Some(it) = &mut it {
110 Some(it.pop_front().unwrap())
111 } else {
112 None
113 }
114 .as_ref(),
115 )
116 })
117 .collect::<Result<_, _>>()?,
118 )))
119 }
120 fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
121 Ok(Data::new(data::tuple::Tuple::from(
122 self.elems
123 .iter()
124 .map(|s| Ok(s.run(info)?))
125 .collect::<Result<Vec<_>, CheckError>>()?,
126 )))
127 }
128 fn has_scope(&self) -> bool {
129 false
130 }
131 fn source_range(&self) -> SourceRange {
132 self.pos_in_src.clone()
133 }
134 fn inner_statements(&self) -> Vec<&dyn MersStatement> {
135 self.elems.iter().map(|s| s.as_ref()).collect()
136 }
137 fn as_any(&self) -> &dyn std::any::Any {
138 self
139 }
140}