Iterate Loops

Iterate loops are syntactic sugar for partitioning a variable-sized input slice into fixed-sized chunk slices (with possible smaller-sized remainders). Individual chunks' fixed sizes are typically easier for bounds-checking.

For example, with primarily 8 length chunks, a 26 length input can be processed in five chunks (of length 8, 8, 8, 1 and 1). Accessing chunk[7] is trivially in-bounds if chunk.length() is exactly 8.

var chunk : slice base.u8
var input : slice base.u8

etc

iterate (chunk = input)(length: 8, unroll: 2) {
    // Within this block, chunk.length() is always 8. For a 26 length input,
    // this block will run three times:
    //  - with "chunk = input[0 .. 8]",
    //  - with "chunk = input[8 .. 16]",
    //  - with "chunk = input[16 .. 24]".
    etc

} else (length: 1, unroll: 1) {
    // Each block of the iterate loop only runs after all previous blocks (in
    // this case the only previous block) are exhausted: the remaining input is
    // shorter than each of their given lengths.
    //
    // Within this block, chunk.length() is always 1. Continuing the previous
    // example, this block will run two times:
    //  - with "chunk = input[24 .. 25]",
    //  - with "chunk = input[25 .. 26]".
    etc
}

Chunk processing (i.e. loop bodies) can also be unrolled, which affects performance but not semantics.