Skip to main content

rl_lang/interpreter/stdlib/array/
arr_map.rs

1use crate::{
2    interpreter::{evaluator::Evaluator, values::Value},
3    utils::{errors::Error, span::Span},
4};
5
6pub fn std_arr_map(
7    eval: &mut Evaluator,
8    array: Value,
9    function: Value,
10    span: Span,
11) -> Result<Value, Error> {
12    let (items_type, items) = match array {
13        Value::Values { items_type, items } => (items_type, items),
14
15        other => {
16            return Err(eval.err(
17                format!("arr_map() accepts only arrays found {}", other.type_name()).to_string(),
18                span,
19            ));
20        }
21    };
22    if !matches!(function, Value::Function { .. }) {
23        return Err(eval.err(
24            format!(
25                "arr_map() expected function or lambda found {}",
26                function.type_name()
27            ),
28            span,
29        ));
30    }
31
32    let mut result = Vec::with_capacity(items.len());
33
34    for item in items {
35        let mapped_item = eval.call_value(function.clone(), vec![item], span)?;
36        result.push(mapped_item);
37    }
38
39    let item_type = result
40        .first()
41        .map(|first| Evaluator::infer_type(first, false))
42        .unwrap_or(items_type);
43
44    Ok(Value::Values {
45        items_type: item_type,
46        items: result,
47    })
48}