loop (callable -- loopState)callable: Already-selected loop body Block.loopState: Final carried state.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 loop body must have stack effect (A -- A Cond): apart from the final Cond, it must leave the same number of stack items, with the same schemas, that it received. The special case (-- Cond) is therefore valid.
Block must already be on the data stack.A must already be below it on the data stack.callable is removed from the stack. The body sees only the carried state A as its input.A TRUE, the final Cond is consumed and A becomes the next iteration input.A FALSE, the final Cond is consumed, the loop stops, and A remains on the data stack.A Cond with the exact same non-condition stack shape, the loop is invalid.(A -- A Cond) rule still applies.FALSE before repeating the same static state or before the static loop-count limit is reached.{} 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
-- 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
call builtin (callable -- calledResult) Calls an already-selected Block, Code, callable Dict, or known Text through a call boundary. No selection happens inside the builtin.if builtin (condition trueCallable falseCallable -- branchResult) Selects between two already-selected Block branches by Cond. Unknown conditions require both branches to be compiled and merged.ucall builtin (callable -- inlineResult) Processes an already-selected Block or known Text inline in the current scope.uif builtin (condition trueCallable falseCallable -- branchResult) Selects between two already-selected Block branches by a known Cond and processes the selected branch inline. No branch-output merge occurs.