From 25ea02d5e6bc5a150bce22f132825a515b2ec517 Mon Sep 17 00:00:00 2001 From: Roman Godmaire Date: Tue, 14 May 2024 14:18:19 -0400 Subject: [PATCH] feat: filter for iterators --- mute-interpreter/src/evaluator.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/mute-interpreter/src/evaluator.rs b/mute-interpreter/src/evaluator.rs index ec2a137..5ebb6f5 100644 --- a/mute-interpreter/src/evaluator.rs +++ b/mute-interpreter/src/evaluator.rs @@ -258,7 +258,33 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { 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);