loop (inputs... callable -- outputs...)

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 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

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