// cookbook — the COOKBOOK.md recipes as one compiled module. // // Every fenced Flash example in COOKBOOK.md lives here as real code, so a // recipe can never drift into syntax the compiler rejects, and the test // blocks run the recipes against the standard library for real. // // Lives in examples/register/ (post-v0.5 grammar — the frozen stage0 // bootstrap compiler cannot parse it; gated by `zig build fixpoint`). use std use core const Allocator = std.mem.Allocator // --- One arena per job --- // Allocate freely inside the job, release everything with one deinit. // Whatever must outlive the arena is copied out to the caller's allocator // before the function returns. pub fn greeting(child Allocator, name []u8, attempt u32) ![]u8 { var arena = core.arena.ArenaAllocator.init(child) defer arena.deinit() alloc := arena.allocator() line := try core.fmt.allocPrint(alloc, "hello {s}, attempt {d}", .{ name, attempt }) return child.dupe(u8, line) } // --- Error handling --- pub const ConfigError = error{ NotFound, OutOfMemory } // Originate with `error.Name`, propagate with `try`, recover with `catch`. pub fn valueOf(table [][]u8, key []u8) ConfigError![]u8 { for line in table { if core.mem.indexOfScalar(u8, line, '=') |eq| { if core.mem.eql(u8, line[0..eq], key) { return line[eq + 1 ..] } } } return error.NotFound } pub fn portOrDefault(s []u8) u16 { return core.fmt.parseInt(u16, s, 10) catch 8080 } // errdefer releases what is already built when a later step fails. pub fn dupePair(alloc Allocator, a []u8, b []u8) ![2][]u8 { first := try alloc.dupe(u8, a) errdefer alloc.free(first) second := try alloc.dupe(u8, b) return .{ first, second } } // --- Cast chains --- pub const Header = struct { magic u32, len u32, } // Spell #ptrCast outermost: the lowered Zig is then already in the order // zig fmt canonicalizes to. pub fn asHeader(raw [*]mut u8) *mut Header { return #ptrCast(#alignCast(raw)) } // --- Bit manipulation --- pub const READY u32 = 1 << 5 pub fn isReady(reg u32) bool { return reg & READY != 0 } pub fn green(rgba u32) u8 { return #truncate((rgba >> 8) & 0xFF) } pub fn nextSeq(seq u8) u8 { return seq +% 1 } // --- Struct literals and the formatter --- pub const Config = struct { name []u8 = "", retries u8 = 3, verbose bool = false, } // The formatter keeps initializers on one line — write them collapsed. pub fn defaultConfig() Config { return .{} } pub fn verboseConfig(name []u8) Config { return .{ .name = name, .retries = 5, .verbose = true } } pub var scratch [64]u8 = [_]u8{0} ** 64 // --- JSON --- pub fn portOf(alloc Allocator, src []u8) !i64 { doc := try core.json.parse(alloc, src) value := doc.get("port") orelse return error.MissingPort return switch value { .int => |n| n, else => error.MissingPort, } } test "greeting survives its arena" { s := try greeting(std.testing.allocator, "port", 2) defer std.testing.allocator.free(s) try std.testing.expect(core.mem.eql(u8, s, "hello port, attempt 2")) } test "valueOf finds keys and reports missing ones" { table := [_][]u8{ "host=10.0.0.1", "port=8080" } v := try valueOf(&table, "port") try std.testing.expect(core.mem.eql(u8, v, "8080")) try std.testing.expectError(error.NotFound, valueOf(&table, "user")) try std.testing.expectEqual(8080, portOrDefault("8080")) try std.testing.expectEqual(8080, portOrDefault("not a number")) } test "dupePair hands back two independent copies" { pair := try dupePair(std.testing.allocator, "a", "bb") defer { std.testing.allocator.free(pair[0]) std.testing.allocator.free(pair[1]) } try std.testing.expect(core.mem.eql(u8, pair[1], "bb")) } test "asHeader reinterprets raw bytes in place" { var buf [8]u8 align(4) = [_]u8{0} ** 8 h := asHeader(&buf) h.magic = 0x464c5348 try std.testing.expectEqual(0x48, buf[0]) } test "bit recipes" { try std.testing.expect(isReady(READY)) try std.testing.expect(!isReady(0)) try std.testing.expectEqual(0x34, green(0x00123456)) try std.testing.expectEqual(0, nextSeq(255)) } test "struct literal recipes" { cfg := verboseConfig("uart0") try std.testing.expect(cfg.verbose) try std.testing.expectEqual(5, cfg.retries) try std.testing.expectEqual(3, defaultConfig().retries) try std.testing.expectEqual(0, scratch[10]) } test "portOf reads a JSON document" { var arena = core.arena.ArenaAllocator.init(std.testing.allocator) defer arena.deinit() n := try portOf(arena.allocator(), "{\"host\":\"example\",\"port\":8080}") try std.testing.expectEqual(8080, n) }