Skip to main content

ganit_core/eval/functions/math/sequence/
mod.rs

1use crate::eval::coercion::to_number;
2use crate::eval::functions::check_arity;
3use crate::types::{ErrorKind, Value};
4
5/// `SEQUENCE(rows, [cols], [start], [step])`
6///
7/// Returns an array of sequential numbers.
8/// Default: cols=1, start=1, step=1.
9/// If cols=1: returns a flat column vector Array([start, start+step, ...]).
10/// If cols>1: returns a nested 2D Array.
11pub fn sequence_fn(args: &[Value]) -> Value {
12    if args.is_empty() {
13        // No args: SEQUENCE() = SEQUENCE(1) = [1]
14        return Value::Number(1.0);
15    }
16    if let Some(err) = check_arity(args, 1, 4) {
17        return err;
18    }
19    let rows = match to_number(args[0].clone()) {
20        Err(e) => return e,
21        Ok(v) => v as usize,
22    };
23    let cols = if args.len() >= 2 {
24        match to_number(args[1].clone()) {
25            Err(e) => return e,
26            Ok(v) => v as usize,
27        }
28    } else {
29        1
30    };
31    let start = if args.len() >= 3 {
32        match to_number(args[2].clone()) {
33            Err(e) => return e,
34            Ok(v) => v,
35        }
36    } else {
37        1.0
38    };
39    let step = if args.len() >= 4 {
40        match to_number(args[3].clone()) {
41            Err(e) => return e,
42            Ok(v) => v,
43        }
44    } else {
45        1.0
46    };
47
48    if rows == 0 || cols == 0 {
49        return Value::Error(ErrorKind::Num);
50    }
51
52    if cols == 1 {
53        // Return flat array (column vector)
54        let items: Vec<Value> = (0..rows)
55            .map(|i| Value::Number(start + step * i as f64))
56            .collect();
57        Value::Array(items)
58    } else {
59        // Return nested 2D array
60        let mut val = start;
61        let outer: Vec<Value> = (0..rows)
62            .map(|_| {
63                let row: Vec<Value> = (0..cols)
64                    .map(|_| {
65                        let v = Value::Number(val);
66                        val += step;
67                        v
68                    })
69                    .collect();
70                Value::Array(row)
71            })
72            .collect();
73        Value::Array(outer)
74    }
75}