num_parser2/operators/
mod.rs

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
11// Implement operators for values. The values should be converted
12// to the highest complex type of the operands.
13
14/// Convert values to a valid value and apply the operation.
15fn 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    // Retrieve the highest complexity, so we will try to convert the output value back to that type
27    let highest_complexity = ValueType::highest_complexity(vec![&lhs.to_type(), &rhs.to_type()]);
28
29    // Convert to vectors
30    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        // Convert the values to the right type
91        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                // a^b = e^(b*ln(a))
226                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        // Only accepts bools and vectors
313        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}