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
}