feat: range function

This commit is contained in:
Roman Godmaire 2024-05-14 11:39:48 -04:00
parent 6a83d228bb
commit ed86c884ec
2 changed files with 35 additions and 1 deletions

View file

@ -1,5 +1,5 @@
use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::{borrow::Borrow, collections::VecDeque};
use super::{macros::arg_count, NativeFunc, Value}; use super::{macros::arg_count, NativeFunc, Value};
use crate::Node; use crate::Node;
@ -139,6 +139,38 @@ pub(super) fn core() -> HashMap<String, Value> {
), ),
// Collections // Collections
("list", NativeFunc(Node::List)), ("list", NativeFunc(Node::List)),
(
"range",
NativeFunc(|mut args| {
let (min, max) = match args.len() {
0 => return Node::Error("expected at least 1 argument".to_string()),
1 => match args.pop_front().expect("argument length checked above") {
Node::Int(max) => (1, (max as usize)),
node => {
return Node::Error(format!("expected int, got {}", node.get_type()))
}
},
2 => match (args.pop_front().unwrap(), args.pop_front().unwrap()) {
(Node::Int(min), Node::Int(max)) => (min as usize, max as usize),
(min, max) => {
return Node::Error(format!(
"expected int and int, got {} and {}",
min.get_type(),
max.get_type()
))
}
},
count => {
return Node::Error(format!("expected 1 or 2 arguments, got {}", count))
}
};
let list =
VecDeque::from_iter((min..(max + 1)).into_iter().map(|i| Node::Int(i as i64)));
Node::List(list)
}),
),
( (
"list?", "list?",
NativeFunc(|args| { NativeFunc(|args| {

View file

@ -359,6 +359,8 @@ mod test {
#[case("(empty? (list))", "true")] #[case("(empty? (list))", "true")]
#[case("(count (list))", "0")] #[case("(count (list))", "0")]
#[case("(count (list 1 2 3))", "3")] #[case("(count (list 1 2 3))", "3")]
#[case("(range 5)", "(1 2 3 4 5)")]
#[case("(range 6 10)", "(6 7 8 9 10)")]
// Vectors // Vectors
#[case("(vector 1 2 3)", "[1 2 3]")] #[case("(vector 1 2 3)", "[1 2 3]")]
#[case("(vector? [])", "true")] #[case("(vector? [])", "true")]