Skip to main content

rl_lang/interpreter/stdlib/array/
arr_max.rs

1use crate::{
2    ast::statements::TypeAnnotation,
3    interpreter::{evaluator::Evaluator, values::Value},
4    utils::{errors::Error, span::Span},
5};
6
7pub fn std_arr_max(eval: &mut Evaluator, array: Value, span: Span) -> Result<Value, Error> {
8    match array {
9        Value::Values { items, items_type } => match items_type {
10            TypeAnnotation::Int => {
11                let max = items
12                    .into_iter()
13                    .filter_map(|v| {
14                        if let Value::Integer(i) = v {
15                            Some(i)
16                        } else {
17                            None
18                        }
19                    })
20                    .max()
21                    .ok_or_else(|| eval.err("arr_max() called on empty array".to_string(), span))?;
22                Ok(Value::Integer(max))
23            }
24            TypeAnnotation::Float => {
25                let max = items
26                    .into_iter()
27                    .filter_map(|v| {
28                        if let Value::Float(f) = v {
29                            Some(f)
30                        } else {
31                            None
32                        }
33                    })
34                    .max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
35                    .ok_or_else(|| eval.err("arr_max() called on empty array".to_string(), span))?;
36                Ok(Value::Float(max))
37            }
38            _ => Err(eval.err(
39                "arr_max() accepts only int or float arrays".to_string(),
40                span,
41            )),
42        },
43        _ => Err(eval.err("arr_max() accepts only arrays".to_string(), span)),
44    }
45}