mers_lib/program/run/
tuple.rs

1use 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}