feat: filter for iterators

This commit is contained in:
Roman Godmaire 2024-05-14 14:18:19 -04:00
parent 315478826f
commit 25ea02d5e6

View file

@ -258,7 +258,33 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
Node::List(list)
}
Node::Filter(mut body) => todo!(),
Node::Filter(mut body) => {
if body.len() != 2 {
todo!();
}
let list = body.pop_front().expect("arg count verified above");
let list = match eval_node(env, list)? {
Node::List(list) => list,
_ => todo!(),
};
let func = match body.pop_front().expect("arg count verified above") {
node @ Node::Function(_) => node,
_ => todo!(),
};
let mut res = VecDeque::new();
for node in list {
if let Node::Boolean(true) =
eval_node(env, Node::List(vec![func.clone(), node.clone()].into()))?
{
res.push_back(node);
}
}
Node::List(res)
}
Node::Reduce(mut body) => todo!(),
Node::Fold(mut body) => todo!(),
@ -455,6 +481,9 @@ mod test {
#[case("(pop-back (list 1 2 3))", "(1 2)")]
#[case("(push-back [1 2 3] 4)", "[1 2 3 4]")]
#[case("(pop-back [1 2 3 4])", "[1 2 3]")]
// Iteration
#[case("(map '(1 2 3) (fn* (x) (* x x)))", "(1 4 9)")]
#[case("(filter '(1 2 3) (fn* (x) (> x 1)))", "(2 3)")]
fn test_evaluator(#[case] input: &str, #[case] expected: &str) {
dbg!(input);