Skip to main content

rl_lang/interpreter/stdlib/array/
arr_find_index.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_find_index(
8    eval: &mut Evaluator,
9    array: Value,
10    function: Value,
11    span: Span,
12) -> Result<Value, Error> {
13    let (_, items) = match array {
14        Value::Values { items_type, items } => (items_type, items),
15
16        other => {
17            return Err(eval.err(
18                format!(
19                    "arr_find_index() accepts only arrays found {}",
20                    other.type_name()
21                )
22                .to_string(),
23                span,
24            ));
25        }
26    };
27    let Value::Function(data) = &function else {
28        return Err(eval.err(
29            format!(
30                "arr_find_index() expected function or lambda found {}",
31                function.type_name()
32            ),
33            span,
34        ));
35    };
36
37    if !matches!(data.return_type, Some(TypeAnnotation::Bool)) {
38        return Err(eval.err(
39            format!(
40                "arr_find_index() expected function or lambda with Bool return type found {:?}",
41                data.return_type
42            ),
43            span,
44        ));
45    }
46
47    for (i, item) in items.iter().enumerate() {
48        let mapped_item = eval.call_value(function.clone(), vec![item.clone()], span)?;
49        if let Value::Bool(true) = mapped_item {
50            return Ok(Value::Integer(i as i64));
51        }
52    }
53
54    Ok(Value::Integer(-1_i64))
55}