loop

loop (callable -- loopState)

Inputs

Outputs

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.

Behavior

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