From 39fca08541f0c23d19d25d46f3a1812bbc0cd288 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 8 Nov 2023 15:11:28 +0100 Subject: [PATCH] change loop function so you can write ().loop(() -> do_smth) --- examples/02_Calc_Sum.mers | 4 ++-- examples/03_Basic_Calculator.mers | 4 ++-- examples/04_Greatest_Common_Divisor.mers | 6 +++--- examples/05_Matrix_Multiplicator.mers | 22 ++++++++++++--------- mers_lib/src/program/configs/with_base.rs | 24 ++++++++++++++++------- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/examples/02_Calc_Sum.mers b/examples/02_Calc_Sum.mers index 7a97260..d30fce2 100755 --- a/examples/02_Calc_Sum.mers +++ b/examples/02_Calc_Sum.mers @@ -1,10 +1,10 @@ total := 0.0 -{() -> { +().loop(() -> { ("Total: ", total, ". Type a number to change.").concat.println ().read_line.trim.parse_float.try(( n -> &total = (total, n).sum, // not a number, so return a 1-tuple to break from the loop () -> (()) )) -}}.loop +}) "Goodbye.".println diff --git a/examples/03_Basic_Calculator.mers b/examples/03_Basic_Calculator.mers index a2f60e2..3a864bd 100755 --- a/examples/03_Basic_Calculator.mers +++ b/examples/03_Basic_Calculator.mers @@ -5,7 +5,7 @@ current := 0.0 -{() -> { +().loop(() -> { ("[ ", current, " ]").concat.println input := ().read_line.trim num := (input, 1).substring.trim.parse_float.try(( @@ -24,4 +24,4 @@ current := 0.0 } else if input.eq("exit") { (()) } -}}.loop +}) diff --git a/examples/04_Greatest_Common_Divisor.mers b/examples/04_Greatest_Common_Divisor.mers index 74293a3..2a5cccf 100755 --- a/examples/04_Greatest_Common_Divisor.mers +++ b/examples/04_Greatest_Common_Divisor.mers @@ -1,5 +1,5 @@ gcd := vals -> { - () -> { + ().loop(() -> { (a, b) := vals if a.eq(b) (a) @@ -7,8 +7,8 @@ gcd := vals -> { &vals = (a, b.subtract(a)) else &vals = (a.subtract(b), b) - } -}.loop + }) +} get_num := () -> { line := ().read_line.trim diff --git a/examples/05_Matrix_Multiplicator.mers b/examples/05_Matrix_Multiplicator.mers index 18366f4..6bf475c 100755 --- a/examples/05_Matrix_Multiplicator.mers +++ b/examples/05_Matrix_Multiplicator.mers @@ -17,7 +17,7 @@ split_once := (s, delim) -> { split_ := (s, delim, require_nonempty) -> { out := (s).as_list &out.pop - { + ().loop( () -> s.split_once(delim).try(( (s1, s2) -> { &s = s2 @@ -30,7 +30,7 @@ split_ := (s, delim, require_nonempty) -> { (()) } )) - }.loop + ) out } @@ -62,9 +62,11 @@ read_matrix_line := width -> { if w.eq(0) { width = line.len } else { - {() -> if line.len.subtract(w).signum.eq(-1) { - &line.push(0.0) - } else (())}.loop + ().loop(() -> + if line.len.subtract(w).signum.eq(-1) { + &line.push(0.0) + } else (()) + ) } (line) } @@ -87,10 +89,12 @@ matrix_get := (matrix, (line, col)) -> { leftpad := (str, l) -> { str := (str).concat d := l.subtract(str.len) - {() -> if d.signum.eq(1) { - &str = (" ", str).concat - &d = d.subtract(1) - } else {(())}}.loop + ().loop(() -> + if d.signum.eq(1) { + &str = (" ", str).concat + &d = d.subtract(1) + } else (()) + ) str } diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs index d663f13..2f086ad 100755 --- a/mers_lib/src/program/configs/with_base.rs +++ b/mers_lib/src/program/configs/with_base.rs @@ -13,7 +13,7 @@ use super::Config; impl Config { /// `deref: fn` clones the value from a reference /// `eq: fn` returns true if all the values are equal, otherwise false. - /// `loop: fn` runs a function until it returns (T) instead of (), then returns T. + /// `loop: fn` runs a function until it returns (T) instead of (), then returns T. Also works with ((), f) instead of f for ().loop(() -> { ... }) syntax, which may be more readable /// `try: fn` runs the first valid function with the argument. usage: (arg, (f1, f2, f3)).try /// NOTE: try's return type may miss some types that can actually happen when using it on tuples, so... don't do ((a, b), (f1, any -> ())).try unless f1 also returns () /// `len: fn` gets the length of strings or tuples @@ -180,7 +180,11 @@ impl Config { info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Arc::new(|a, _i| { let mut o = Type::empty(); - for t in &a.types { + for t in a.types.iter().flat_map(|v| if let Some(t) = v.as_any().downcast_ref::() { + if let Some(t) = t.0.get(1) { + t.types.iter().collect::>() + } else { [v].into_iter().collect() } + } else { [v].into_iter().collect() }) { if let Some(t) = t.as_any().downcast_ref::() { for t in (t.0)(&Type::empty_tuple())?.types { if let Some(t) = t.as_any().downcast_ref::() { @@ -200,15 +204,21 @@ impl Config { Ok(o) }), run: Arc::new(|a, _i| { - if let Some(r) = a.get().as_any().downcast_ref::() { + let a = a.get(); + let delay_drop; + let function = if let Some(function) = a.as_any().downcast_ref::() { + function + } else if let Some(r) = a.as_any().downcast_ref::() { + delay_drop = r.0[1].get(); + delay_drop.as_any().downcast_ref::().unwrap() + } else { + unreachable!("called loop on non-function") + }; loop { - if let Some(r) = r.run(Data::empty_tuple()).one_tuple_content() { + if let Some(r) = function.run(Data::empty_tuple()).one_tuple_content() { break r; } } - } else { - unreachable!("called loop on non-function") - } }), }), )