ajhahn.de
← Flash
Flash 60 lines
// Labeled loops: a label on `while` / `for` is a break/continue target —
// `outer: while` + `break :outer` leaves the outer loop from anywhere inside
// it, `continue :outer` restarts its next iteration. The spellings unify with
// the labeled BLOCK's `break :label v` (long supported): one label grammar,
// loop or block. A label is an error when nothing targets it.
//
// Lives in examples/register/ (post-v0.5 grammar — the frozen stage0
// bootstrap compiler cannot parse it; gated by `zig build fixpoint`).

fn pick(task []?u32) ?usize {
    for t, i in task {
        if t != null && t.? != 0 {
            return i
        }
    }
    return null
}

fn refill(task []mut ?u32) void {
    for *t in task {
        if t.* != null {
            t.* = 1
        }
    }
}

// The scheduler's pick loop: retry until a runnable slot appears, leaving
// through the labeled break once one holds a nonzero budget.
pub fn schedule(task []mut ?u32) usize {
    var idx usize = 0

    outer: while true {
        if pick(task) |i| {
            if task[i].? != 0 {
                idx = i
                break :outer
            }
        }
        refill(task)
    }

    return idx
}

// A labelled continue: the inner scan abandons a row mid-way and moves the
// OUTER loop to its next iteration; the labeled break exits with the answer.
pub fn firstFullRow(grid [][]u8) usize {
    var found usize = 0
    rows: for row, r in grid {
        for b in row {
            if b == 0 {
                continue :rows
            }
        }
        found = r + 1
        break :rows
    }
    return found
}