loop (inputs... callable -- outputs...)
Inputs
inputs...: Objects carried below the loop callable.callable: Already-selected loop body Block.
Outputs
outputs...: The final carried state; the terminatingCondis consumed.
loop repeatedly calls one already-selected Block. No name lookup or field selection happens inside the builtin.
Each iteration body call uses a normal call boundary. Locals created inside an iteration do not remain available in the next iteration or after the loop. Persistent state must stay on the data stack or be written to outer storage.
The run-time repetition invariant is (A -- A Cond): each body call preserves the carried stack’s shape — the number of objects and their schemas — not necessarily their values, and leaves a final Cond. The body’s final Cond is consumed: TRUE repeats with the returned carried state; FALSE stops and leaves that state on the data stack. While the condition is known, iterations are performed at compile time and the body may change the carried state (add items or change their schemas). The iteration whose condition first turns out unknown must leave as many items as it received; its outputs fix the schemas, and from then on repetition happens at run time and every iteration must leave the same number of items with those schemas; otherwise the loop is invalid. The special case (-- Cond) is therefore valid.
Behavior
- A static loop is invalid if it does not reach a known
FALSEbefore repeating the same static state or before the static loop-count limit is reached.
Example
{} 0 {} [
counter: 3;
total: 0;
[
"-- loop body --" printCompilerMessage
total printStack _:;
counter printStack _:;
total counter + !total
counter 1 - !counter
counter 0 >
] loop
"-- after loop --" printCompilerMessage
total printStack _:;
counter printStack _:;
"-- stack-carried state --" printCompilerMessage
3 [
current:;
next: current 1 -;
next new
next 0 >
] loop printStack _:;
"-- immediate FALSE keeps the current state --" printCompilerMessage
5 [
current:;
current new
FALSE
] loop printStack _:;
0
] "main" exportFunction
Expected Output During Compilation
-- loop body --
0 Cref
3 Cref
-- loop body --
3 Cref
2 Cref
-- loop body --
5 Cref
1 Cref
-- after loop --
6 Cref
0 Cref
-- stack-carried state --
0
-- immediate FALSE keeps the current state --
5
See also
callbuiltin(inputs... callable -- outputs...)Calls an already-selected Block, Code, callable Dict, or known Text through a call boundary. No selection happens inside the builtin.ifbuiltin(inputs... condition trueCallable falseCallable -- outputs...)Selects between two already-selected Block branches by Cond. Unknown conditions require both branches to be compiled and merged.ucallbuiltin(inputs... callable -- outputs...)Processes an already-selected Block or known Text inline in the current scope.uifbuiltin(inputs... condition trueCallable falseCallable -- outputs...)Selects between two already-selected Block branches by a known Cond and processes the selected branch inline. No branch-output merge occurs.