Skip to main content

rl_lang/interpreter/stdlib/array/
arr_zip.rs

1use std::rc::Rc;
2
3use crate::ast::statements::TypeAnnotation;
4use crate::interpreter::{evaluator::Evaluator, values::Value};
5use crate::utils::errors::{Error, Reason};
6use crate::utils::span::Span;
7
8/// Zips two arrays into an array of tuples.
9///
10/// `arr_zip([1, 2, 3], ["a", "b", "c"])` → `[(1, "a"), (2, "b"), (3, "c")]`
11///
12/// Stops at the shorter array (same behaviour as Rust's `zip`).
13pub fn std_arr_zip(_: &mut Evaluator, args: Vec<Value>, span: Span) -> Result<Value, Error> {
14    if args.len() != 2 {
15        return Err(Error::at(
16            Reason::Runtime,
17            format!("arr_zip: expected 2 arguments, got {}", args.len()),
18            span,
19        ));
20    }
21
22    let (a, b) = match (&args[0], &args[1]) {
23        (Value::Values { items: a, .. }, Value::Values { items: b, .. }) => (a, b),
24        _ => {
25            return Err(Error::at(
26                Reason::Runtime,
27                format!(
28                    "arr_zip: expected two arrays, got {} and {}",
29                    args[0].type_name(),
30                    args[1].type_name()
31                ),
32                span,
33            ));
34        }
35    };
36
37    let items = a
38        .iter()
39        .zip(b.iter())
40        .map(|(x, y)| Value::Tuple(vec![x.clone(), y.clone()]))
41        .collect();
42
43    Ok(Value::Values {
44        items_type: TypeAnnotation::Tuple(Rc::new(vec![
45            TypeAnnotation::Null,
46            TypeAnnotation::Null,
47        ])),
48        items,
49    })
50}