1use crate::{
2 out::{ErrorType, EvalResult},
3 value::{valuetype::ValueType, Value},
4};
5use std::ops::Add;
6use std::ops::Not;
7use std::ops::Sub;
8use std::ops::Mul;
9use std::ops::Div;
10
11fn convert_and_apply<T>(
16 lhs: &Value,
17 rhs: &Value,
18 operation: &mut T,
19 operation_name: &'static str,
20 target_value_type: ValueType,
21 inverse: bool,
22) -> EvalResult<Value>
23where
24 T: FnMut(Value, Value) -> EvalResult<Value>,
25{
26 let highest_complexity = ValueType::highest_complexity(vec![&lhs.to_type(), &rhs.to_type()]);
28
29 let lhs_as_vector = lhs.as_vector();
31 let rhs_as_vector = rhs.as_vector();
32
33 fn apply_to_vector_and_number<T>(
34 v: &Vec<Value>,
35 n: &Value,
36 inverse: bool,
37 operation: &mut T,
38 operation_name: &'static str,
39 target_value_type: ValueType,
40 ) -> EvalResult<Vec<Value>>
41 where
42 T: FnMut(Value, Value) -> EvalResult<Value>,
43 {
44 let mut out_v = vec![];
45
46 for item in v {
47 out_v.push(convert_and_apply(
48 item,
49 n,
50 operation,
51 operation_name,
52 target_value_type,
53 inverse,
54 )?);
55 }
56
57 Ok(out_v)
58 }
59
60 fn apply_to_vectors<T>(
61 lv: &Vec<Value>,
62 rv: &Vec<Value>,
63 inverse: bool,
64 operation: &mut T,
65 operation_name: &'static str,
66 target_value_type: ValueType,
67 ) -> EvalResult<Vec<Value>>
68 where
69 T: FnMut(Value, Value) -> EvalResult<Value>,
70 {
71 let joined = lv.iter().zip(rv.iter());
72
73 let mut out_v = vec![];
74
75 for (l_item, r_item) in joined {
76 out_v.push(convert_and_apply(
77 l_item,
78 r_item,
79 operation,
80 operation_name,
81 target_value_type,
82 inverse,
83 )?);
84 }
85
86 Ok(out_v)
87 }
88
89 if lhs_as_vector.len() == 1 && rhs_as_vector.len() == 1 {
90 let lhs_converted = lhs.as_type(&target_value_type)?;
92 let rhs_converted = rhs.as_type(&target_value_type)?;
93
94 if inverse {
95 Ok(operation(rhs_converted, lhs_converted)?.try_as_type(highest_complexity))
96 } else {
97 Ok(operation(lhs_converted, rhs_converted)?.try_as_type(highest_complexity))
98 }
99 } else if lhs_as_vector.len() == 1 {
100 Ok(Value::Vector(apply_to_vector_and_number(
101 &rhs_as_vector,
102 lhs,
103 !inverse,
104 operation,
105 operation_name,
106 target_value_type,
107 )?))
108 } else if rhs_as_vector.len() == 1 {
109 Ok(Value::Vector(apply_to_vector_and_number(
110 &lhs_as_vector,
111 rhs,
112 inverse,
113 operation,
114 operation_name,
115 target_value_type,
116 )?))
117 } else if lhs_as_vector.len() == rhs_as_vector.len() {
118 if inverse {
119 Ok(Value::Vector(apply_to_vectors(
120 &rhs_as_vector,
121 &lhs_as_vector,
122 inverse,
123 operation,
124 operation_name,
125 target_value_type,
126 )?))
127 } else {
128 Ok(Value::Vector(apply_to_vectors(
129 &lhs_as_vector,
130 &rhs_as_vector,
131 inverse,
132 operation,
133 operation_name,
134 target_value_type,
135 )?))
136 }
137 } else {
138 Err(ErrorType::MismatchedArrayLengths {
139 first: lhs_as_vector.len(),
140 second: rhs_as_vector.len(),
141 operation_name,
142 })
143 }
144}
145
146impl Add<Self> for Value {
147 type Output = EvalResult<Self>;
148 fn add(self, rhs: Self) -> EvalResult<Self> {
149 convert_and_apply(
150 &self,
151 &rhs,
152 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? + rhs.as_complex()?)),
153 "Sum",
154 ValueType::ComplexType,
155 false,
156 )
157 }
158}
159
160impl Sub<Self> for Value {
161 type Output = EvalResult<Self>;
162
163 fn sub(self, rhs: Self) -> EvalResult<Self> {
164 convert_and_apply(
165 &self,
166 &rhs,
167 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? - rhs.as_complex()?)),
168 "Subtraction",
169 ValueType::ComplexType,
170 false,
171 )
172 }
173}
174
175impl Mul<Self> for Value {
176 type Output = EvalResult<Self>;
177 fn mul(self, rhs: Self) -> EvalResult<Self> {
178 convert_and_apply(
179 &self,
180 &rhs,
181 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? * rhs.as_complex()?)),
182 "Multiplication",
183 ValueType::ComplexType,
184 false,
185 )
186 }
187}
188
189impl Div<Self> for Value {
190 type Output = EvalResult<Self>;
191
192 fn div(self, rhs: Self) -> EvalResult<Self> {
193 convert_and_apply(
194 &self,
195 &rhs,
196 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? / rhs.as_complex()?)),
197 "Division",
198 ValueType::ComplexType,
199 false,
200 )
201 }
202}
203
204impl Value {
205 pub fn negate(self) -> EvalResult<Self> {
206 let zero = Value::Int(0);
207 convert_and_apply(
208 &zero,
209 &self,
210 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? - rhs.as_complex()?)),
211 "Negation",
212 ValueType::ComplexType,
213 false,
214 )
215 }
216
217 pub fn exponentiation(self, rhs: Self) -> EvalResult<Self> {
218 convert_and_apply(
219 &self,
220 &rhs,
221 &mut |lhs, rhs| {
222 let lhs_as_complex = lhs.as_complex()?;
223 let rhs_as_complex = rhs.as_complex()?;
224
225 Ok(Value::Complex((rhs_as_complex * lhs_as_complex.ln()).exp()))
227 },
228 "Exponentiation",
229 ValueType::ComplexType,
230 false,
231 )
232 }
233
234 pub fn modulo(self, rhs: Self) -> EvalResult<Self> {
235 convert_and_apply(
236 &self,
237 &rhs,
238 &mut |lhs, rhs| Ok(Value::Complex(lhs.as_complex()? % rhs.as_complex()?)),
239 "Modulo",
240 ValueType::ComplexType,
241 false,
242 )
243 }
244
245 pub fn less_than(self, rhs: Self) -> EvalResult<Self> {
246 convert_and_apply(
247 &self,
248 &rhs,
249 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_float()? < rhs.as_float()?)),
250 "Less than",
251 ValueType::FloatType,
252 false,
253 )
254 }
255
256 pub fn greater_than(self, rhs: Self) -> EvalResult<Self> {
257 convert_and_apply(
258 &self,
259 &rhs,
260 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_float()? > rhs.as_float()?)),
261 "Greater than",
262 ValueType::FloatType,
263 false,
264 )
265 }
266
267 pub fn less_or_equal_to(self, rhs: Self) -> EvalResult<Self> {
268 convert_and_apply(
269 &self,
270 &rhs,
271 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_float()? <= rhs.as_float()?)),
272 "Less or equal to",
273 ValueType::FloatType,
274 false,
275 )
276 }
277
278 pub fn greater_or_equal_to(self, rhs: Self) -> EvalResult<Self> {
279 convert_and_apply(
280 &self,
281 &rhs,
282 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_float()? >= rhs.as_float()?)),
283 "Greater or equal to",
284 ValueType::FloatType,
285 false,
286 )
287 }
288
289 pub fn logical_and(self, rhs: Self) -> EvalResult<Self> {
290 convert_and_apply(
291 &self,
292 &rhs,
293 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_bool()? && rhs.as_bool()?)),
294 "Logical AND",
295 ValueType::BoolType,
296 false,
297 )
298 }
299
300 pub fn logical_or(self, rhs: Self) -> EvalResult<Self> {
301 convert_and_apply(
302 &self,
303 &rhs,
304 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_bool()? || rhs.as_bool()?)),
305 "Logical OR",
306 ValueType::BoolType,
307 false,
308 )
309 }
310
311 pub fn equal_to(self, rhs: Self) -> EvalResult<Self> {
312 fn is_vector_true(values: &Vec<Value>) -> EvalResult<bool> {
314 for elem in values {
315 match elem {
316 Value::Vector(vec) => {
317 if !is_vector_true(vec)? {
318 return Ok(false);
319 }
320 }
321 Value::Bool(val) => {
322 if !val {
323 return Ok(false);
324 }
325 }
326 other => {
327 return Err(ErrorType::InternalError {
328 message: format!("unexpected type during comparison: {}", other),
329 })
330 }
331 }
332 }
333 Ok(true)
334 }
335
336 match convert_and_apply(
337 &self,
338 &rhs,
339 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_complex()? == rhs.as_complex()?)),
340 "Equal to",
341 ValueType::ComplexType,
342 false,
343 )? {
344 Self::Vector(vec) => Ok(Value::Bool(is_vector_true(&vec)?)),
345 other => Ok(other),
346 }
347 }
348
349 pub fn not_equal_to(self, rhs: Self) -> EvalResult<Self> {
350 self.equal_to(rhs)?.not()
351 }
352
353 pub fn not(self) -> EvalResult<Self> {
354 convert_and_apply(
355 &self,
356 &Value::Bool(true),
357 &mut |lhs, rhs| Ok(Value::Bool(lhs.as_bool()? != rhs.as_bool()?)),
358 "Not",
359 ValueType::BoolType,
360 false,
361 )
362 }
363}