Overview of LOOP Statements¶
Quxlang's clause-based LOOP statement handles ordinary test-and-step loops,
numeric sequences, and container iteration. Every form ends its header with
DO and then supplies the body.
Test-and-step loops¶
A WHILE clause checks a condition before each iteration:
The combination of INIT, WHILE, and STEP expresses a conventional counted
loop:
VAR total I32 := 0;
LOOP INIT { VAR index I32 := 0; }
WHILE(index < 5)
STEP { index++; }
DO
{
total += index;
};
ASSERT(total == 10);
INIT runs once, WHILE runs before each iteration, and STEP runs after the
body. LOOP DO is an unconditional loop; use BREAK to leave it.
POSTTEST checks after the body, so the body runs at least once when no
WHILE clause is present:
Numeric sequences¶
VALUE, FROM, and either TO or UNTIL describe a numeric sequence:
VAR inclusive_total I32 := 0;
LOOP VALUE(value) FROM(0 AS I32) TO(6) BY(2 AS I32) DO
{
inclusive_total += value;
};
ASSERT(inclusive_total == 12);
VAR exclusive_total I32 := 0;
LOOP VALUE(value) FROM(0 AS I32) UNTIL(4) DO
{
exclusive_total += value;
};
ASSERT(exclusive_total == 6);
TO includes the bound; UNTIL excludes it. BY defaults to one. Give the
FROM expression a concrete type, as in 0 AS I32, because it determines the
type of the sequence variable, bound, and step.
A FILTER clause skips values without changing the sequence step:
Arrays and containers¶
ITEM(name) IN(range) iterates direct elements. When the iterator returns a
reference, the binding can modify the element:
VAR values [4]I32 :[1, 2, 3, 4];
VAR total I32 := 0;
LOOP ITEM(item) IN(values) DO
{
total += item;
item++;
};
ASSERT(total == 10);
ASSERT(values[0] == 2);
Container types participate through .BEGIN() and .END(). They may also
provide .VALUES(), .INDEXES(), and .IV_PAIRS() projections for
VALUE, INDEX, or combined INDEX VALUE loops.
An ITER(name) clause exposes the iterator to the loop body and to a custom
STEP clause:
LOOP ITER(iterator) ITEM(item) IN(container)
FILTER(item != 0)
STEP { iterator++; }
DO
{
consume(item);
};
The default iterator step is iterator++. BY(amount) uses
iterator += amount instead.
Loop control¶
CONTINUE advances through the loop's normal post-test and step path. BREAK
exits. Labels let a nested loop target an outer loop:
LOOP :rows VALUE(row) FROM(0 AS I32) UNTIL(height) DO
{
LOOP VALUE(column) FROM(0 AS I32) UNTIL(width) DO
{
IF (skip_remaining_columns(row, column))
{
CONTINUE :rows;
}
};
};
Reference¶
See the LOOP Statements Reference for clause-form
selection, exact phase ordering, iterator protocols, binding scope, boundary
comparisons, and every invalid clause combination.