1use crate::models::{Range, State, Token, WCode, WFuncVariant, WTokens};
2use crate::parser::WParser;
3use crate::utils::{Utils, WFunc};
4use itertools::Itertools;
5
6pub trait WEval {
7 fn apply(&mut self, code: &str) -> Vec<WTokens>;
8 fn wsection_eval(&mut self, data: Vec<WCode>) -> Vec<WTokens>;
9 fn eval(&self, data: WTokens) -> WTokens;
10 fn dissolve(
11 &self,
12 code: &mut WTokens,
13 func: WFuncVariant,
14 argument_range: &std::ops::Range<usize>,
15 arr: WTokens,
16 );
17}
18
19impl WEval for State {
20 fn apply(&mut self, code: &str) -> Vec<WTokens> {
21 self.wsection_eval(self.parser(code))
22 }
23
24 fn wsection_eval(&mut self, data: Vec<WCode>) -> Vec<WTokens> {
25 let mut result: Vec<WTokens> = Vec::new();
26
27 for section in data {
28 match section.container {
29 Some(container) => {
30 let mut cases = vec![];
31
32 if let Some(container_cases) = section.cases {
33 cases.append(&mut container_cases.clone())
34 }
35
36 cases.push((vec![Token::Value(1.0)], section.default_case));
37
38 self.insert(container, cases);
39 }
40 None => result.push(self.eval(section.default_case)),
41 }
42 }
43
44 result
45 }
46
47 fn eval(&self, data: WTokens) -> WTokens {
48 let mut new_code = data;
49
50 while let Some((argument_range, func)) = new_code.first_function() {
51 if let Some((x, y)) = new_code.special_pairs("(", ")") {
52 let result = new_code[x + 1..y].to_vec();
53 new_code.splice(x..=y, self.eval(result));
54 } else {
55 let code_to_evaluate: WTokens = new_code[argument_range.clone()].to_vec();
56 self.dissolve(&mut new_code, func, &argument_range, code_to_evaluate);
57 }
58 }
59
60 new_code
61 }
62
63 fn dissolve(
64 &self,
65 code: &mut WTokens,
66 func: WFuncVariant,
67 argument_range: &std::ops::Range<usize>,
68 arr: WTokens,
69 ) {
70 match func {
71 WFuncVariant::Function(func) => {
72 let result = func(arr);
73 code.splice(argument_range.start..argument_range.end + 1, result);
74 }
75 WFuncVariant::Container(x) => {
76 let mut case: WTokens = vec![];
77 let mut container_acc: WTokens = vec![];
78
79 for container_case in self.get(&x).unwrap() {
80 let mut joined = container_case.0.clone();
81 joined.append(&mut container_case.1.clone());
82 container_acc.append(&mut joined);
83
84 let case_prefix = self.eval(self.apply(&container_case.0, &arr));
85
86 if case_prefix[0] != Token::Value(0.0) {
87 case = container_case.1.clone();
88 break;
89 }
90 }
91
92 let expanded_range = container_acc
93 .iter()
94 .filter(|x| matches!(x, Token::Parameter(_)))
95 .flat_map(|range| match range {
96 Token::Parameter(Range::Full(full)) => full.clone().collect::<Vec<_>>(),
97 Token::Parameter(Range::From(from)) => (0..=from.end).collect::<Vec<_>>(),
98 Token::Parameter(Range::To(to)) => {
99 (to.start..=arr.len() - 1).collect::<Vec<_>>()
100 }
101 _ => panic!(),
102 })
103 .unique()
104 .map(|wlang_index| arr.len() - (wlang_index + 1))
105 .sorted()
106 .rev()
107 .collect::<Vec<usize>>();
108
109 let result = self.apply(&case, &arr);
110 code.splice(argument_range.end..=argument_range.end, result);
111 for n in expanded_range {
112 code.remove(n);
113 }
114 }
115 }
116 }
117}