diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index fd87a05d..f7a4941b 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -985,6 +985,21 @@ Please check corresponding loop function description what `continue` and `break` general case, passed values to `break` and `continue` will be used in place of the return value of the internal iteration expression. +### `cfor(init, condition, increment, body)` + +`c_for` Mimics c-style tri-arg (plus body) for loops. Return value of `c_for` is number of iterations performed in the + loop. Unlike other loops, the `body` is not provided with pre-initialized `_` style variables - all initialization + and increments has to be handled by the programmers themselves. + `break` and `continue` statements are handled within `body` expression only, and not in `condition` or `increment`. + +
+ c_for(x=0, x<10, x+=1,
+    c_for(y=0, y<10, y+=1,
+        print(str('%d * %d = %d', x, y, x*y))
+    )
+ )
+ 
+ ### `for(list,expr(_,_i))` Evaluates expression over list of items from the `list`. Supplies `_`(value) and `_i`(iteration number) to the `expr`. diff --git a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md index d79eb59f..65dc2715 100644 --- a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md +++ b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md @@ -19,6 +19,21 @@ Please check corresponding loop function description what `continue` and `break` general case, passed values to `break` and `continue` will be used in place of the return value of the internal iteration expression. +### `cfor(init, condition, increment, body)` + +`c_for` Mimics c-style tri-arg (plus body) for loops. Return value of `c_for` is number of iterations performed in the + loop. Unlike other loops, the `body` is not provided with pre-initialized `_` style variables - all initialization + and increments has to be handled by the programmers themselves. + `break` and `continue` statements are handled within `body` expression only, and not in `condition` or `increment`. + +
+ c_for(x=0, x<10, x+=1,
+    c_for(y=0, y<10, y+=1,
+        print(str('%d * %d = %d', x, y, x*y))
+    )
+ )
+ 
+ ### `for(list,expr(_,_i))` Evaluates expression over list of items from the `list`. Supplies `_`(value) and `_i`(iteration number) to the `expr`. diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index fbe5a08c..724ea9ce 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -1081,6 +1081,32 @@ public class Expression return result; }); + // runs traditional for(init, condition, increment, body) tri-argument for loop with body in between + addLazyFunction("c_for", 4, (c, t, lv) -> { + LazyValue initial = lv.get(0); + LazyValue condition = lv.get(1); + LazyValue increment = lv.get(2); + LazyValue body = lv.get(3); + int iterations = 0; + for (initial.evalValue(c, Context.VOID); condition.evalValue(c, Context.BOOLEAN).getBoolean(); increment.evalValue(c, Context.VOID)) + { + try + { + body.evalValue(c, Context.VOID); + } + catch (BreakStatement stmt) + { + break; + } + catch (ContinueStatement ignored) + { + } + iterations++; + } + int finalIterations = iterations; + return (cc, tt) -> new NumericValue(finalIterations); + }); + // similar to map, but returns total number of successes // for(list, expr) => success_count // can be substituted for first and all, but first is more efficient and all doesn't require knowing list size