From 2e6125bc66bd717838fb107107564cdd66112613 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Jan 2018 03:24:03 -0500 Subject: [PATCH] ziglang.org home page no longer in this repo update docs examples which use build-exe to be tested See #465 --- build.zig | 9 - doc/home.html.in | 724 -------------------------------------------- doc/langref.html.in | 80 ++--- 3 files changed, 30 insertions(+), 783 deletions(-) delete mode 100644 doc/home.html.in diff --git a/build.zig b/build.zig index b3ed0a5a48..189e0e156f 100644 --- a/build.zig +++ b/build.zig @@ -24,17 +24,8 @@ pub fn build(b: &Builder) -> %void { }); docgen_cmd.step.dependOn(&docgen_exe.step); - var docgen_home_cmd = b.addCommand(null, b.env_map, [][]const u8 { - docgen_exe.getOutputPath(), - rel_zig_exe, - "doc/home.html.in", - os.path.join(b.allocator, b.cache_root, "home.html") catch unreachable, - }); - docgen_home_cmd.step.dependOn(&docgen_exe.step); - const docs_step = b.step("docs", "Build documentation"); docs_step.dependOn(&docgen_cmd.step); - docs_step.dependOn(&docgen_home_cmd.step); const test_step = b.step("test", "Run all the tests"); diff --git a/doc/home.html.in b/doc/home.html.in deleted file mode 100644 index 086a078a90..0000000000 --- a/doc/home.html.in +++ /dev/null @@ -1,724 +0,0 @@ - - - - - - The Zig Programming Language - - - - - -

- Zig is an open-source programming language designed for robustness, - optimality, and clarity. -

-

- Download | - Documentation | - Source Code | - Bug Tracker | - IRC | - Donate $1/month -

-

Feature Highlights

- -

Reading Material

- -

Source Code Examples

- -

Hello World

-
const std = @import("std");
-
-pub fn main() -> %void {
-    // If this program is run without stdout attached, exit with an error.
-    var stdout_file = try std.io.getStdOut();
-    // If this program encounters pipe failure when printing to stdout, exit
-    // with an error.
-    try stdout_file.write("Hello, world!\n");
-}
-

Build this with:

-
zig build-exe hello.zig
-

Hello World with libc

-
const c = @cImport({
-    // See https://github.com/zig-lang/zig/issues/515
-    @cDefine("_NO_CRT_STDIO_INLINE", "1");
-    @cInclude("stdio.h");
-    @cInclude("string.h");
-});
-
-const msg = c"Hello, world!\n";
-
-export fn main(argc: c_int, argv: &&u8) -> c_int {
-    if (c.printf(msg) != c_int(c.strlen(msg)))
-        return -1;
-
-    return 0;
-}
-

Build this with:

-
zig build-exe hello.zig --library c
-

Parsing Unsigned Integers

-
pub fn parseUnsigned(comptime T: type, buf: []u8, radix: u8) -> %T {
-    var x: T = 0;
-
-    for (buf) |c| {
-        const digit = try charToDigit(c, radix);
-        x = try mulOverflow(T, x, radix);
-        x = try addOverflow(T, x, digit);
-    }
-
-    return x;
-}
-
-error InvalidChar;
-
-fn charToDigit(c: u8, radix: u8) -> %u8 {
-    const value = switch (c) {
-        '0' ... '9' => c - '0',
-        'A' ... 'Z' => c - 'A' + 10,
-        'a' ... 'z' => c - 'a' + 10,
-        else => return error.InvalidChar,
-    };
-
-    if (value >= radix)
-        return error.InvalidChar;
-
-    return value;
-}
-
-error Overflow;
-
-pub fn mulOverflow(comptime T: type, a: T, b: T) -> %T {
-    var answer: T = undefined;
-    if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
-}
-
-pub fn addOverflow(comptime T: type, a: T, b: T) -> %T {
-    var answer: T = undefined;
-    if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
-}
-
-fn getNumberWithDefault(s: []u8) -> u32 {
-    parseUnsigned(u32, s, 10) catch 42
-}
-
-fn getNumberOrCrash(s: []u8) -> u32 {
-    %%parseUnsigned(u32, s, 10)
-}
-
-fn addTwoTogetherOrReturnErr(a_str: []u8, b_str: []u8) -> %u32 {
-    const a = parseUnsigned(u32, a_str, 10) catch |err| return err;
-    const b = parseUnsigned(u32, b_str, 10) catch |err| return err;
-    return a + b;
-}
-

HashMap with Custom Allocator

-
const debug = @import("debug.zig");
-const assert = debug.assert;
-const math = @import("math.zig");
-const mem = @import("mem.zig");
-const Allocator = mem.Allocator;
-
-const want_modification_safety = !@compileVar("is_release");
-const debug_u32 = if (want_modification_safety) u32 else void;
-
-pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)->u32,
-    comptime eql: fn(a: K, b: K)->bool) -> type
-{
-    struct {
-        entries: []Entry,
-        size: usize,
-        max_distance_from_start_index: usize,
-        allocator: &Allocator,
-        // this is used to detect bugs where a hashtable is edited while an iterator is running.
-        modification_count: debug_u32,
-
-        const Self = this;
-
-        pub const Entry = struct {
-            used: bool,
-            distance_from_start_index: usize,
-            key: K,
-            value: V,
-        };
-
-        pub const Iterator = struct {
-            hm: &Self,
-            // how many items have we returned
-            count: usize,
-            // iterator through the entry array
-            index: usize,
-            // used to detect concurrent modification
-            initial_modification_count: debug_u32,
-
-            pub fn next(it: &Iterator) -> ?&Entry {
-                if (want_modification_safety) {
-                    assert(it.initial_modification_count == it.hm.modification_count); // concurrent modification
-                }
-                if (it.count >= it.hm.size) return null;
-                while (it.index < it.hm.entries.len) : (it.index += 1) {
-                    const entry = &it.hm.entries[it.index];
-                    if (entry.used) {
-                        it.index += 1;
-                        it.count += 1;
-                        return entry;
-                    }
-                }
-                unreachable // no next item
-            }
-        };
-
-        pub fn init(hm: &Self, allocator: &Allocator) {
-            hm.entries = []Entry{};
-            hm.allocator = allocator;
-            hm.size = 0;
-            hm.max_distance_from_start_index = 0;
-            // it doesn't actually matter what we set this to since we use wrapping integer arithmetic
-            hm.modification_count = undefined;
-        }
-
-        pub fn deinit(hm: &Self) {
-            hm.allocator.free(Entry, hm.entries);
-        }
-
-        pub fn clear(hm: &Self) {
-            for (hm.entries) |*entry| {
-                entry.used = false;
-            }
-            hm.size = 0;
-            hm.max_distance_from_start_index = 0;
-            hm.incrementModificationCount();
-        }
-
-        pub fn put(hm: &Self, key: K, value: V) -> %void {
-            if (hm.entries.len == 0) {
-                try hm.initCapacity(16);
-            }
-            hm.incrementModificationCount();
-
-            // if we get too full (60%), double the capacity
-            if (hm.size * 5 >= hm.entries.len * 3) {
-                const old_entries = hm.entries;
-                try hm.initCapacity(hm.entries.len * 2);
-                // dump all of the old elements into the new table
-                for (old_entries) |*old_entry| {
-                    if (old_entry.used) {
-                        hm.internalPut(old_entry.key, old_entry.value);
-                    }
-                }
-                hm.allocator.free(Entry, old_entries);
-            }
-
-            hm.internalPut(key, value);
-        }
-
-        pub fn get(hm: &Self, key: K) -> ?&Entry {
-            return hm.internalGet(key);
-        }
-
-        pub fn remove(hm: &Self, key: K) {
-            hm.incrementModificationCount();
-            const start_index = hm.keyToIndex(key);
-            {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
-                const index = (start_index + roll_over) % hm.entries.len;
-                var entry = &hm.entries[index];
-
-                assert(entry.used); // key not found
-
-                if (!eql(entry.key, key)) continue;
-
-                while (roll_over < hm.entries.len) : (roll_over += 1) {
-                    const next_index = (start_index + roll_over + 1) % hm.entries.len;
-                    const next_entry = &hm.entries[next_index];
-                    if (!next_entry.used or next_entry.distance_from_start_index == 0) {
-                        entry.used = false;
-                        hm.size -= 1;
-                        return;
-                    }
-                    *entry = *next_entry;
-                    entry.distance_from_start_index -= 1;
-                    entry = next_entry;
-                }
-                unreachable // shifting everything in the table
-            }}
-            unreachable // key not found
-        }
-
-        pub fn entryIterator(hm: &Self) -> Iterator {
-            return Iterator {
-                .hm = hm,
-                .count = 0,
-                .index = 0,
-                .initial_modification_count = hm.modification_count,
-            };
-        }
-
-        fn initCapacity(hm: &Self, capacity: usize) -> %void {
-            hm.entries = try hm.allocator.alloc(Entry, capacity);
-            hm.size = 0;
-            hm.max_distance_from_start_index = 0;
-            for (hm.entries) |*entry| {
-                entry.used = false;
-            }
-        }
-
-        fn incrementModificationCount(hm: &Self) {
-            if (want_modification_safety) {
-                hm.modification_count +%= 1;
-            }
-        }
-
-        fn internalPut(hm: &Self, orig_key: K, orig_value: V) {
-            var key = orig_key;
-            var value = orig_value;
-            const start_index = hm.keyToIndex(key);
-            var roll_over: usize = 0;
-            var distance_from_start_index: usize = 0;
-            while (roll_over < hm.entries.len) : ({roll_over += 1; distance_from_start_index += 1}) {
-                const index = (start_index + roll_over) % hm.entries.len;
-                const entry = &hm.entries[index];
-
-                if (entry.used and !eql(entry.key, key)) {
-                    if (entry.distance_from_start_index < distance_from_start_index) {
-                        // robin hood to the rescue
-                        const tmp = *entry;
-                        hm.max_distance_from_start_index = math.max(hm.max_distance_from_start_index,
-                            distance_from_start_index);
-                        *entry = Entry {
-                            .used = true,
-                            .distance_from_start_index = distance_from_start_index,
-                            .key = key,
-                            .value = value,
-                        };
-                        key = tmp.key;
-                        value = tmp.value;
-                        distance_from_start_index = tmp.distance_from_start_index;
-                    }
-                    continue;
-                }
-
-                if (!entry.used) {
-                    // adding an entry. otherwise overwriting old value with
-                    // same key
-                    hm.size += 1;
-                }
-
-                hm.max_distance_from_start_index = math.max(distance_from_start_index, hm.max_distance_from_start_index);
-                *entry = Entry {
-                    .used = true,
-                    .distance_from_start_index = distance_from_start_index,
-                    .key = key,
-                    .value = value,
-                };
-                return;
-            }
-            unreachable // put into a full map
-        }
-
-        fn internalGet(hm: &Self, key: K) -> ?&Entry {
-            const start_index = hm.keyToIndex(key);
-            {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
-                const index = (start_index + roll_over) % hm.entries.len;
-                const entry = &hm.entries[index];
-
-                if (!entry.used) return null;
-                if (eql(entry.key, key)) return entry;
-            }}
-            return null;
-        }
-
-        fn keyToIndex(hm: &Self, key: K) -> usize {
-            return usize(hash(key)) % hm.entries.len;
-        }
-    }
-}
-
-test "basic hash map test" {
-    var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
-    map.init(&debug.global_allocator);
-    defer map.deinit();
-
-    %%map.put(1, 11);
-    %%map.put(2, 22);
-    %%map.put(3, 33);
-    %%map.put(4, 44);
-    %%map.put(5, 55);
-
-    assert((??map.get(2)).value == 22);
-    map.remove(2);
-    assert(if (const entry ?= map.get(2)) false else true);
-}
-
-fn hash_i32(x: i32) -> u32 {
-    *(&u32)(&x)
-}
-fn eql_i32(a: i32, b: i32) -> bool {
-    a == b
-}
-

Tetris Clone

- -

- Source Code on GitHub -

-

Bare Bones Operating System

-

- Source Code on GitHub -

-

Cat Utility

-
const std = @import("std");
-const io = std.io;
-const mem = std.mem;
-const os = std.os;
-
-pub fn main() -> %void {
-    const exe = os.args.at(0);
-    var catted_anything = false;
-    var arg_i: usize = 1;
-    while (arg_i < os.args.count()) : (arg_i += 1) {
-        const arg = os.args.at(arg_i);
-        if (mem.eql(u8, arg, "-")) {
-            catted_anything = true;
-            try cat_stream(&io.stdin);
-        } else if (arg[0] == '-') {
-            return usage(exe);
-        } else {
-            var is = io.InStream.open(arg, null) catch |err| {
-                %%io.stderr.printf("Unable to open file: {}\n", @errorName(err));
-                return err;
-            };
-            defer is.close();
-
-            catted_anything = true;
-            try cat_stream(&is);
-        }
-    }
-    if (!catted_anything) {
-        try cat_stream(&io.stdin);
-    }
-    try io.stdout.flush();
-}
-
-fn usage(exe: []const u8) -> %void {
-    %%io.stderr.printf("Usage: {} [FILE]...\n", exe);
-    return error.Invalid;
-}
-
-fn cat_stream(is: &io.InStream) -> %void {
-    var buf: [1024 * 4]u8 = undefined;
-
-    while (true) {
-        const bytes_read = is.read(buf[0..]) catch |err| {
-            %%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err));
-            return err;
-        };
-
-        if (bytes_read == 0) {
-            break;
-        }
-
-        io.stdout.write(buf[0..bytes_read]) catch |err| {
-            %%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err));
-            return err;
-        };
-    }
-}
-

Multiline String Syntax

-
pub fn createAllShaders() -> AllShaders {
-    var as : AllShaders = undefined;
-
-    as.primitive = createShader(
-        \\#version 150 core
-        \\
-        \\in vec3 VertexPosition;
-        \\
-        \\uniform mat4 MVP;
-        \\
-        \\void main(void) {
-        \\    gl_Position = vec4(VertexPosition, 1.0) * MVP;
-        \\}
-    ,
-        \\#version 150 core
-        \\
-        \\out vec4 FragColor;
-        \\
-        \\uniform vec4 Color;
-        \\
-        \\void main(void) {
-        \\    FragColor = Color;
-        \\}
-    , null);
-
-    as.primitive_attrib_position = as.primitive.attrib_location(c"VertexPosition");
-    as.primitive_uniform_mvp = as.primitive.uniform_location(c"MVP");
-    as.primitive_uniform_color = as.primitive.uniform_location(c"Color");
-
-
-
-    as.texture = createShader(
-        \\#version 150 core
-        \\
-        \\in vec3 VertexPosition;
-        \\in vec2 TexCoord;
-        \\
-        \\out vec2 FragTexCoord;
-        \\
-        \\uniform mat4 MVP;
-        \\
-        \\void main(void)
-        \\{
-        \\    FragTexCoord = TexCoord;
-        \\    gl_Position = vec4(VertexPosition, 1.0) * MVP;
-        \\}
-    ,
-        \\#version 150 core
-        \\
-        \\in vec2 FragTexCoord;
-        \\out vec4 FragColor;
-        \\
-        \\uniform sampler2D Tex;
-        \\
-        \\void main(void)
-        \\{
-        \\    FragColor = texture(Tex, FragTexCoord);
-        \\}
-    , null);
-
-    as.texture_attrib_tex_coord = as.texture.attrib_location(c"TexCoord");
-    as.texture_attrib_position = as.texture.attrib_location(c"VertexPosition");
-    as.texture_uniform_mvp = as.texture.uniform_location(c"MVP");
-    as.texture_uniform_tex = as.texture.uniform_location(c"Tex");
-
-    debug_gl.assert_no_error();
-
-    return as;
-}
-

Mersenne Twister Random Number Generator

-
const assert = @import("debug.zig").assert;
-const rand_test = @import("rand_test.zig");
-
-pub const MT19937_32 = MersenneTwister(
-    u32, 624, 397, 31,
-    0x9908B0DF,
-    11, 0xFFFFFFFF,
-    7, 0x9D2C5680,
-    15, 0xEFC60000,
-    18, 1812433253);
-
-pub const MT19937_64 = MersenneTwister(
-    u64, 312, 156, 31,
-    0xB5026F5AA96619E9,
-    29, 0x5555555555555555,
-    17, 0x71D67FFFEDA60000,
-    37, 0xFFF7EEE000000000,
-    43, 6364136223846793005);
-
-/// Use `init` to initialize this state.
-pub const Rand = struct {
-    const Rng = if (@sizeOf(usize) >= 8) MT19937_64 else MT19937_32;
-
-    rng: Rng,
-
-    /// Initialize random state with the given seed.
-    pub fn init(r: &Rand, seed: usize) {
-        r.rng.init(seed);
-    }
-
-    /// Get an integer with random bits.
-    pub fn scalar(r: &Rand, comptime T: type) -> T {
-        if (T == usize) {
-            return r.rng.get();
-        } else {
-            var result: [@sizeOf(T)]u8 = undefined;
-            r.fillBytes(result);
-            return ([]T)(result)[0];
-        }
-    }
-
-    /// Fill `buf` with randomness.
-    pub fn fillBytes(r: &Rand, buf: []u8) {
-        var bytes_left = buf.len;
-        while (bytes_left >= @sizeOf(usize)) {
-            ([]usize)(buf[buf.len - bytes_left...])[0] = r.rng.get();
-            bytes_left -= @sizeOf(usize);
-        }
-        if (bytes_left > 0) {
-            var rand_val_array : [@sizeOf(usize)]u8 = undefined;
-            ([]usize)(rand_val_array)[0] = r.rng.get();
-            while (bytes_left > 0) {
-                buf[buf.len - bytes_left] = rand_val_array[@sizeOf(usize) - bytes_left];
-                bytes_left -= 1;
-            }
-        }
-    }
-
-    /// Get a random unsigned integer with even distribution between `start`
-    /// inclusive and `end` exclusive.
-    // TODO support signed integers and then rename to "range"
-    pub fn rangeUnsigned(r: &Rand, comptime T: type, start: T, end: T) -> T {
-        const range = end - start;
-        const leftover = @maxValue(T) % range;
-        const upper_bound = @maxValue(T) - leftover;
-        var rand_val_array : [@sizeOf(T)]u8 = undefined;
-
-        while (true) {
-            r.fillBytes(rand_val_array);
-            const rand_val = ([]T)(rand_val_array)[0];
-            if (rand_val < upper_bound) {
-                return start + (rand_val % range);
-            }
-        }
-    }
-
-    /// Get a floating point value in the range 0.0..1.0.
-    pub fn float(r: &Rand, comptime T: type) -> T {
-        // TODO Implement this way instead:
-        // const int = @int_type(false, @sizeOf(T) * 8);
-        // const mask = ((1 << @float_mantissa_bit_count(T)) - 1);
-        // const rand_bits = r.rng.scalar(int) & mask;
-        // return @float_compose(T, false, 0, rand_bits) - 1.0
-        const int_type = @intType(false, @sizeOf(T) * 8);
-        const precision = if (T == f32) {
-            16777216
-        } else if (T == f64) {
-            9007199254740992
-        } else {
-            @compileError("unknown floating point type")
-        };
-        return T(r.rangeUnsigned(int_type, 0, precision)) / T(precision);
-    }
-};
-
-fn MersenneTwister(
-    comptime int: type, comptime n: usize, comptime m: usize, comptime r: int,
-    comptime a: int,
-    comptime u: int, comptime d: int,
-    comptime s: int, comptime b: int,
-    comptime t: int, comptime c: int,
-    comptime l: int, comptime f: int) -> type
-{
-    struct {
-        const Self = this;
-
-        array: [n]int,
-        index: usize,
-
-        pub fn init(mt: &Self, seed: int) {
-            mt.index = n;
-
-            var prev_value = seed;
-            mt.array[0] = prev_value;
-            {var i: usize = 1; while (i < n) : (i += 1) {
-                prev_value = int(i) +% f *% (prev_value ^ (prev_value >> (int.bit_count - 2)));
-                mt.array[i] = prev_value;
-            }};
-        }
-
-        pub fn get(mt: &Self) -> int {
-            const mag01 = []int{0, a};
-            const LM: int = (1 << r) - 1;
-            const UM = ~LM;
-
-            if (mt.index >= n) {
-                var i: usize = 0;
-
-                while (i < n - m) : (i += 1) {
-                    const x = (mt.array[i] & UM) | (mt.array[i + 1] & LM);
-                    mt.array[i] = mt.array[i + m] ^ (x >> 1) ^ mag01[x & 0x1];
-                }
-
-                while (i < n - 1) : (i += 1) {
-                    const x = (mt.array[i] & UM) | (mt.array[i + 1] & LM);
-                    mt.array[i] = mt.array[i + m - n] ^ (x >> 1) ^ mag01[x & 0x1];
-
-                }
-                const x = (mt.array[i] & UM) | (mt.array[0] & LM);
-                mt.array[i] = mt.array[m - 1] ^ (x >> 1) ^ mag01[x & 0x1];
-
-                mt.index = 0;
-            }
-
-            var x = mt.array[mt.index];
-            mt.index += 1;
-
-            x ^= ((x >> u) & d);
-            x ^= ((x <<% s) & b);
-            x ^= ((x <<% t) & c);
-            x ^= (x >> l);
-
-            return x;
-        }
-    }
-}
-
-test "float 32" {
-    var r: Rand = undefined;
-    r.init(42);
-
-    {var i: usize = 0; while (i < 1000) : (i += 1) {
-        const val = r.float(f32);
-        assert(val >= 0.0);
-        assert(val < 1.0);
-    }}
-}
-
-test "MT19937_64" {
-    var rng: MT19937_64 = undefined;
-    rng.init(rand_test.mt64_seed);
-    for (rand_test.mt64_data) |value| {
-        assert(value == rng.get());
-    }
-}
-
-test "MT19937_32" {
-    var rng: MT19937_32 = undefined;
-    rng.init(rand_test.mt32_seed);
-    for (rand_test.mt32_data) |value| {
-        assert(value == rng.get());
-    }
-}
- - - - diff --git a/doc/langref.html.in b/doc/langref.html.in index 7b3dc9788c..11952cd17d 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -92,14 +92,16 @@ pub fn main() -> %void {

For some discussion on the rationale behind these design decisions, see issue #663

{#header_close#} {#header_open|Values#} -
const warn = @import("std").debug.warn;
-const os = @import("std").os;
-const assert = @import("std").debug.assert;
+      {#code_begin|exe|values#}
+const std = @import("std");
+const warn = std.debug.warn;
+const os = std.os;
+const assert = std.debug.assert;
 
 // error declaration, makes `error.ArgNotFound` available
 error ArgNotFound;
 
-pub fn main() -> %void {
+pub fn main() -> %void {
     // integers
     const one_plus_one: i32 = 1 + 1;
     warn("1 + 1 = {}\n", one_plus_one);
@@ -137,30 +139,8 @@ pub fn main() -> %void {
 
     warn("\nerror union 2\ntype: {}\nvalue: {}\n",
         @typeName(@typeOf(number_or_error)), number_or_error);
-}
-
$ zig build-exe values.zig
-$ ./values
-1 + 1 = 2
-7.0 / 3.0 = 2.333333
-false
-true
-false
-
-nullable 1
-type: ?[]const u8
-value: null
-
-nullable 2
-type: ?[]const u8
-value: hi
-
-error union 1
-type: %i32
-value: error.ArgNotFound
-
-error union 2
-type: %i32
-value: 1234
+} + {#code_end#} {#header_open|Primitive Types#} @@ -3630,17 +3610,18 @@ fn sum(numbers: []i32) -> i32 { {#header_close#} {#header_open|Case Study: printf in Zig#}

- Putting all of this together, let's seee how printf works in Zig. + Putting all of this together, let's see how printf works in Zig.

-
const warn = @import("std").debug.warn;
+      {#code_begin|exe|printf#}
+const warn = @import("std").debug.warn;
 
 const a_number: i32 = 1234;
 const a_string = "foobar";
 
-pub fn main(args: [][]u8) -> %void {
+pub fn main() {
     warn("here is a string: '{}' here is a number: {}\n", a_string, a_number);
-}
-
here is a string: 'foobar' here is a number: 1234
+} + {#code_end#}

Let's crack open the implementation of this and see how it works: @@ -3760,15 +3741,17 @@ pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) -> Zig doesn't care whether the format argument is a string literal, only that it is a compile-time known value that is implicitly castable to a []const u8:

-
const warn = @import("std").debug.warn;
+      {#code_begin|exe|printf#}
+const warn = @import("std").debug.warn;
 
 const a_number: i32 = 1234;
 const a_string = "foobar";
 const fmt = "here is a string: '{}' here is a number: {}\n";
 
-pub fn main(args: [][]u8) -> %void {
+pub fn main() {
     warn(fmt, a_string, a_number);
-}
+} + {#code_end#}

This works fine.

@@ -4943,8 +4926,9 @@ test "wraparound addition and subtraction" {

At runtime crashes with the message attempt to unwrap null and a stack trace.

One way to avoid this crash is to test for null instead of assuming non-null, with the if expression:

-
const warn = @import("std").debug.warn;
-pub fn main() -> %void {
+      {#code_begin|exe|test#}
+const warn = @import("std").debug.warn;
+pub fn main() {
     const nullable_number: ?i32 = null;
 
     if (nullable_number) |number| {
@@ -4952,10 +4936,8 @@ pub fn main() -> %void {
     } else {
         warn("it's null\n");
     }
-}
-
% zig build-exe test.zig
-$ ./test
-it's null
+} + {#code_end#} {#header_close#} {#header_open|Attempt to Unwrap Error#}

At compile-time:

@@ -4975,9 +4957,10 @@ fn getNumberOrFail() -> %i32 {

At runtime crashes with the message attempt to unwrap error: ErrorCode and a stack trace.

One way to avoid this crash is to test for an error instead of assuming a successful result, with the if expression:

-
const warn = @import("std").debug.warn;
+      {#code_begin|exe|test#}
+const warn = @import("std").debug.warn;
 
-pub fn main() -> %void {
+pub fn main() {
     const result = getNumberOrFail();
 
     if (result) |number| {
@@ -4989,13 +4972,10 @@ pub fn main() -> %void {
 
 error UnableToReturnNumber;
 
-fn getNumberOrFail() -> %i32 {
+fn getNumberOrFail() -> %i32 {
     return error.UnableToReturnNumber;
-}
-
$ zig build-exe test.zig
-$ ./test
-got error: UnableToReturnNumber
- +} + {#code_end#} {#header_close#} {#header_open|Invalid Error Code#}

At compile-time: