From d2fc8c1ebeade0dc28ac1a6f0fd1429870115cc7 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 8 Nov 2023 15:54:46 +0100 Subject: [PATCH] Add division to examples/03 and add `any` and `all` functions for Iter --- examples/03_Basic_Calculator.mers | 6 ++-- mers_lib/src/program/configs/with_iters.rs | 35 +++++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/examples/03_Basic_Calculator.mers b/examples/03_Basic_Calculator.mers index 3a864bd..d0cabc8 100755 --- a/examples/03_Basic_Calculator.mers +++ b/examples/03_Basic_Calculator.mers @@ -1,6 +1,6 @@ "- Calculator -".println "Type = to set the value to that number.".println -"Type +, - or * to change the value.".println +"Type +, -, * or / to change the value.".println "Type exit to exit.".println current := 0.0 @@ -19,9 +19,11 @@ current := 0.0 ¤t = (current, (num, -1).product).sum } else if mode.eq("*") { ¤t = (current, num).product + } else if mode.eq("/") { + ¤t = (current, num).div } else if mode.eq("=") { ¤t = num - } else if input.eq("exit") { + } else if (input.eq("exit"), input.eq("")).any { (()) } }) diff --git a/mers_lib/src/program/configs/with_iters.rs b/mers_lib/src/program/configs/with_iters.rs index f162fcd..f6d0934 100755 --- a/mers_lib/src/program/configs/with_iters.rs +++ b/mers_lib/src/program/configs/with_iters.rs @@ -26,8 +26,17 @@ impl Config { /// `map_while: fn` maps while the map-function returns (d), ends the iterator once () is returned. /// `take: fn` takes at most so many elements from the iterator. /// `enumerate: fn` transforms an iterator over T into one over (Int, T), where Int is the index of the element + /// `any: fn` returns true if any element of the iterator are true + /// `all: fn` returns true if all elements of the iterator are true pub fn with_iters(self) -> Self { - self.add_var( + self + .add_var("any".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + Data::new(data::bool::Bool(a.get().iterable().unwrap().any(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0)))) + }))) + .add_var("all".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + Data::new(data::bool::Bool(a.get().iterable().unwrap().all(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0)))) + }))) + .add_var( "for_each".to_string(), Data::new(data::function::Function { info: Arc::new(program::run::Info::neverused()), @@ -383,3 +392,27 @@ impl Iters { } } } + +fn genfunc_iter_in_val_out( + name: String, + iter_type: impl MersType + 'static, + out_type: Type, + run: impl Fn(Data, &mut crate::info::Info) -> Data + Send + Sync + 'static, +) -> Function { + Function { + info: Arc::new(crate::info::Info::neverused()), + info_check: Arc::new(Mutex::new(crate::info::Info::neverused())), + out: Arc::new(move |a, _i| { + if let Some(iter_over) = a.iterable() { + if iter_over.is_included_in(&iter_type) { + Ok(out_type.clone()) + } else { + Err(format!("Cannot call function {name} on iterator over type {a}, which isn't {iter_type}.").into()) + } + } else { + Err(format!("Cannot call function {name} on non-iterable type {a}.").into()) + } + }), + run: Arc::new(run), + } +}