ajhahn.de
← Flash
Flash 67 lines
// `|*x|` pointer captures: the capture binds a POINTER to the element or
// payload instead of a copy, so a body writes in place — `for *p in &arr`
// lowers to Zig's `for (&arr) |*p|`. The `*` rides the element capture only
// (an index stays a value) and works on `for`, the `if`/`while` payloads, and
// switch prongs; error captures (`catch |e|`, `else |e|`) still bind by value.
//
// Lives in examples/register/ (post-v0.5 grammar — the frozen stage0
// bootstrap compiler cannot parse it; gated by `zig build fixpoint`).

var table [16]u8 = undefined

// The canonical in-place loop: a pointer element plus the index.
pub fn resetTable() void {
    for *p, i in &table {
        p.* = #intCast(i)
    }
}

pub fn fillPattern(msg *mut [64]u8) void {
    for *b, i in msg {
        b.* = #truncate(i *% 31 +% 7)
    }
}

pub fn fillStrings(kargv *mut [8][]u8) void {
    for *s in kargv {
        s.* = "x"
    }
}

var slot ?u8 = 3

// The payload forms: `if`/`while` bind a pointer into the optional, so the
// body mutates the stored value, not a copy.
pub fn bumpSlot() void {
    if slot |*x| {
        x.* += 1
    }
}

pub fn drainSlot() void {
    while slot |*x| {
        if x.* == 0 {
            slot = null
        } else {
            x.* -= 1
        }
    }
}

pub const Packet = union(enum) {
    counter u32,
    flag bool,
}

// A prong pointer capture writes the active variant's payload in place.
pub fn bump(p *mut Packet) void {
    switch p.* {
        .counter => |*n| {
            n.* += 1
        },
        .flag => |*b| {
            b.* = !b.*
        },
    }
}