mirror of
https://github.com/ziglang/zig.git
synced 2024-11-22 20:30:17 +00:00
migrate langref documentation generation to the build system
This commit is contained in:
parent
9d64332a59
commit
1b90888f57
73
build.zig
73
build.zig
@ -9,7 +9,7 @@ const fs = std.fs;
|
||||
const InstallDirectoryOptions = std.Build.InstallDirectoryOptions;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const zig_version = std.SemanticVersion{ .major = 0, .minor = 13, .patch = 0 };
|
||||
const zig_version: std.SemanticVersion = .{ .major = 0, .minor = 13, .patch = 0 };
|
||||
const stack_size = 32 * 1024 * 1024;
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
@ -32,22 +32,7 @@ pub fn build(b: *std.Build) !void {
|
||||
const std_docs = b.option(bool, "std-docs", "include standard library autodocs") orelse false;
|
||||
const no_bin = b.option(bool, "no-bin", "skip emitting compiler binary") orelse false;
|
||||
|
||||
const docgen_exe = b.addExecutable(.{
|
||||
.name = "docgen",
|
||||
.root_source_file = b.path("tools/docgen.zig"),
|
||||
.target = b.host,
|
||||
.optimize = .Debug,
|
||||
.single_threaded = single_threaded,
|
||||
});
|
||||
|
||||
const docgen_cmd = b.addRunArtifact(docgen_exe);
|
||||
docgen_cmd.addArgs(&.{ "--zig", b.graph.zig_exe });
|
||||
if (b.zig_lib_dir) |p| {
|
||||
docgen_cmd.addArg("--zig-lib-dir");
|
||||
docgen_cmd.addDirectoryArg(p);
|
||||
}
|
||||
docgen_cmd.addFileArg(b.path("doc/langref.html.in"));
|
||||
const langref_file = docgen_cmd.addOutputFileArg("langref.html");
|
||||
const langref_file = generateLangRef(b);
|
||||
const install_langref = b.addInstallFileWithDir(langref_file, .prefix, "doc/langref.html");
|
||||
if (!skip_install_langref) {
|
||||
b.getInstallStep().dependOn(&install_langref.step);
|
||||
@ -1256,3 +1241,57 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMSupport",
|
||||
"LLVMDemangle",
|
||||
};
|
||||
|
||||
fn generateLangRef(b: *std.Build) std.Build.LazyPath {
|
||||
const doctest_exe = b.addExecutable(.{
|
||||
.name = "doctest",
|
||||
.root_source_file = b.path("tools/doctest.zig"),
|
||||
.target = b.host,
|
||||
.optimize = .Debug,
|
||||
});
|
||||
|
||||
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
|
||||
std.debug.panic("unable to open 'doc/langref' directory: {s}", .{@errorName(err)});
|
||||
};
|
||||
defer dir.close();
|
||||
|
||||
var wf = b.addWriteFiles();
|
||||
|
||||
var it = dir.iterateAssumeFirstIteration();
|
||||
while (it.next() catch @panic("failed to read dir")) |entry| {
|
||||
if (std.mem.startsWith(u8, entry.name, ".") or entry.kind != .file)
|
||||
continue;
|
||||
|
||||
const out_basename = b.fmt("{s}.out", .{std.fs.path.stem(entry.name)});
|
||||
const cmd = b.addRunArtifact(doctest_exe);
|
||||
cmd.addArgs(&.{
|
||||
"--zig", b.graph.zig_exe,
|
||||
// TODO: enhance doctest to use "--listen=-" rather than operating
|
||||
// in a temporary directory
|
||||
"--cache-root", b.cache_root.path orelse ".",
|
||||
});
|
||||
if (b.zig_lib_dir) |p| {
|
||||
cmd.addArg("--zig-lib-dir");
|
||||
cmd.addDirectoryArg(p);
|
||||
}
|
||||
cmd.addArgs(&.{"-i"});
|
||||
cmd.addFileArg(b.path(b.fmt("doc/langref/{s}", .{entry.name})));
|
||||
|
||||
cmd.addArgs(&.{"-o"});
|
||||
_ = wf.addCopyFile(cmd.addOutputFileArg(out_basename), out_basename);
|
||||
}
|
||||
|
||||
const docgen_exe = b.addExecutable(.{
|
||||
.name = "docgen",
|
||||
.root_source_file = b.path("tools/docgen.zig"),
|
||||
.target = b.host,
|
||||
.optimize = .Debug,
|
||||
});
|
||||
|
||||
const docgen_cmd = b.addRunArtifact(docgen_exe);
|
||||
docgen_cmd.addArgs(&.{"--code-dir"});
|
||||
docgen_cmd.addDirectoryArg(wf.getDirectory());
|
||||
|
||||
docgen_cmd.addFileArg(b.path("doc/langref.html.in"));
|
||||
return docgen_cmd.addOutputFileArg("langref.html");
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ ninja install
|
||||
echo "Looking for non-conforming code formatting..."
|
||||
stage3-debug/bin/zig fmt --check .. \
|
||||
--exclude ../test/cases/ \
|
||||
--exclude ../doc/ \
|
||||
--exclude ../build-debug
|
||||
|
||||
# simultaneously test building self-hosted without LLVM and with 32-bit arm
|
||||
|
@ -53,6 +53,7 @@ ninja install
|
||||
echo "Looking for non-conforming code formatting..."
|
||||
stage3-release/bin/zig fmt --check .. \
|
||||
--exclude ../test/cases/ \
|
||||
--exclude ../doc/ \
|
||||
--exclude ../build-release
|
||||
|
||||
# simultaneously test building self-hosted without LLVM and with 32-bit arm
|
||||
|
@ -61,6 +61,7 @@ ninja install
|
||||
echo "Looking for non-conforming code formatting..."
|
||||
stage3-debug/bin/zig fmt --check .. \
|
||||
--exclude ../test/cases/ \
|
||||
--exclude ../doc/ \
|
||||
--exclude ../build-debug
|
||||
|
||||
# simultaneously test building self-hosted without LLVM and with 32-bit arm
|
||||
|
@ -61,6 +61,7 @@ ninja install
|
||||
echo "Looking for non-conforming code formatting..."
|
||||
stage3-release/bin/zig fmt --check .. \
|
||||
--exclude ../test/cases/ \
|
||||
--exclude ../doc/ \
|
||||
--exclude ../build-debug \
|
||||
--exclude ../build-release
|
||||
|
||||
|
5439
doc/langref.html.in
5439
doc/langref.html.in
File diff suppressed because it is too large
Load Diff
60
doc/langref/Assembly Syntax Explained.zig
Normal file
60
doc/langref/Assembly Syntax Explained.zig
Normal file
@ -0,0 +1,60 @@
|
||||
pub fn syscall1(number: usize, arg1: usize) usize {
|
||||
// Inline assembly is an expression which returns a value.
|
||||
// the `asm` keyword begins the expression.
|
||||
return asm
|
||||
// `volatile` is an optional modifier that tells Zig this
|
||||
// inline assembly expression has side-effects. Without
|
||||
// `volatile`, Zig is allowed to delete the inline assembly
|
||||
// code if the result is unused.
|
||||
volatile (
|
||||
// Next is a comptime string which is the assembly code.
|
||||
// Inside this string one may use `%[ret]`, `%[number]`,
|
||||
// or `%[arg1]` where a register is expected, to specify
|
||||
// the register that Zig uses for the argument or return value,
|
||||
// if the register constraint strings are used. However in
|
||||
// the below code, this is not used. A literal `%` can be
|
||||
// obtained by escaping it with a double percent: `%%`.
|
||||
// Often multiline string syntax comes in handy here.
|
||||
\\syscall
|
||||
// Next is the output. It is possible in the future Zig will
|
||||
// support multiple outputs, depending on how
|
||||
// https://github.com/ziglang/zig/issues/215 is resolved.
|
||||
// It is allowed for there to be no outputs, in which case
|
||||
// this colon would be directly followed by the colon for the inputs.
|
||||
:
|
||||
// This specifies the name to be used in `%[ret]` syntax in
|
||||
// the above assembly string. This example does not use it,
|
||||
// but the syntax is mandatory.
|
||||
[ret]
|
||||
// Next is the output constraint string. This feature is still
|
||||
// considered unstable in Zig, and so LLVM/GCC documentation
|
||||
// must be used to understand the semantics.
|
||||
// http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string
|
||||
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
|
||||
// In this example, the constraint string means "the result value of
|
||||
// this inline assembly instruction is whatever is in $rax".
|
||||
"={rax}"
|
||||
// Next is either a value binding, or `->` and then a type. The
|
||||
// type is the result type of the inline assembly expression.
|
||||
// If it is a value binding, then `%[ret]` syntax would be used
|
||||
// to refer to the register bound to the value.
|
||||
(-> usize),
|
||||
// Next is the list of inputs.
|
||||
// The constraint for these inputs means, "when the assembly code is
|
||||
// executed, $rax shall have the value of `number` and $rdi shall have
|
||||
// the value of `arg1`". Any number of input parameters is allowed,
|
||||
// including none.
|
||||
: [number] "{rax}" (number),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
// Next is the list of clobbers. These declare a set of registers whose
|
||||
// values will not be preserved by the execution of this assembly code.
|
||||
// These do not include output or input registers. The special clobber
|
||||
// value of "memory" means that the assembly writes to arbitrary undeclared
|
||||
// memory locations - not only the memory pointed to by a declared indirect
|
||||
// output. In this example we list $rcx and $r11 because it is known the
|
||||
// kernel syscall does not preserve these registers.
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
// syntax
|
13
doc/langref/addWithOverflow_builtin.zig
Normal file
13
doc/langref/addWithOverflow_builtin.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const print = @import("std").debug.print;
|
||||
pub fn main() void {
|
||||
const byte: u8 = 255;
|
||||
|
||||
const ov = @addWithOverflow(byte, 10);
|
||||
if (ov[1] != 0) {
|
||||
print("overflowed result: {}\n", .{ov[0]});
|
||||
} else {
|
||||
print("result: {}\n", .{ov[0]});
|
||||
}
|
||||
}
|
||||
|
||||
// exe=succeed
|
16
doc/langref/anonymous_struct_name.zig
Normal file
16
doc/langref/anonymous_struct_name.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const Node = struct {
|
||||
next: ?*Node,
|
||||
name: []const u8,
|
||||
};
|
||||
|
||||
var node_a = Node{
|
||||
.next = null,
|
||||
.name = "Node A",
|
||||
};
|
||||
|
||||
var node_b = Node{
|
||||
.next = &node_a,
|
||||
.name = "Node B",
|
||||
};
|
||||
|
||||
// syntax
|
9
doc/langref/assign_undefined.zig
Normal file
9
doc/langref/assign_undefined.zig
Normal file
@ -0,0 +1,9 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
pub fn main() void {
|
||||
var x: i32 = undefined;
|
||||
x = 1;
|
||||
print("{d}", .{x});
|
||||
}
|
||||
|
||||
// exe=succeed
|
26
doc/langref/bad_default_value.zig
Normal file
26
doc/langref/bad_default_value.zig
Normal file
@ -0,0 +1,26 @@
|
||||
const Threshold = struct {
|
||||
minimum: f32 = 0.25,
|
||||
maximum: f32 = 0.75,
|
||||
|
||||
const Category = enum { low, medium, high };
|
||||
|
||||
fn categorize(t: Threshold, value: f32) Category {
|
||||
assert(t.maximum >= t.minimum);
|
||||
if (value < t.minimum) return .low;
|
||||
if (value > t.maximum) return .high;
|
||||
return .medium;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var threshold: Threshold = .{
|
||||
.maximum = 0.20,
|
||||
};
|
||||
const category = threshold.categorize(0.90);
|
||||
try std.io.getStdOut().writeAll(@tagName(category));
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
// exe=fail
|
17
doc/langref/base64.zig
Normal file
17
doc/langref/base64.zig
Normal file
@ -0,0 +1,17 @@
|
||||
const base64 = @import("std").base64;
|
||||
|
||||
export fn decode_base_64(
|
||||
dest_ptr: [*]u8,
|
||||
dest_len: usize,
|
||||
source_ptr: [*]const u8,
|
||||
source_len: usize,
|
||||
) usize {
|
||||
const src = source_ptr[0..source_len];
|
||||
const dest = dest_ptr[0..dest_len];
|
||||
const base64_decoder = base64.standard.Decoder;
|
||||
const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable;
|
||||
base64_decoder.decode(dest[0..decoded_size], src) catch unreachable;
|
||||
return decoded_size;
|
||||
}
|
||||
|
||||
// syntax
|
13
doc/langref/build.zig
Normal file
13
doc/langref/build.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "example",
|
||||
.root_source_file = .{ .path = "example.zig" },
|
||||
.optimize = optimize,
|
||||
});
|
||||
b.default_step.dependOn(&exe.step);
|
||||
}
|
||||
|
||||
// syntax
|
24
doc/langref/build_c.zig
Normal file
24
doc/langref/build_c.zig
Normal file
@ -0,0 +1,24 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const lib = b.addSharedLibrary(.{
|
||||
.name = "mathtest",
|
||||
.root_source_file = .{ .path = "mathtest.zig" },
|
||||
.version = .{ .major = 1, .minor = 0, .patch = 0 },
|
||||
});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-std=c99"} });
|
||||
exe.linkLibrary(lib);
|
||||
exe.linkSystemLibrary("c");
|
||||
|
||||
b.default_step.dependOn(&exe.step);
|
||||
|
||||
const run_cmd = exe.run();
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
// syntax
|
18
doc/langref/build_object.zig
Normal file
18
doc/langref/build_object.zig
Normal file
@ -0,0 +1,18 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const obj = b.addObject(.{
|
||||
.name = "base64",
|
||||
.root_source_file = .{ .path = "base64.zig" },
|
||||
});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-std=c99",} });
|
||||
exe.addObject(obj);
|
||||
exe.linkSystemLibrary("c");
|
||||
b.installArtifact(exe);
|
||||
}
|
||||
|
||||
// syntax
|
35
doc/langref/builtin.CallModifier struct.zig
Normal file
35
doc/langref/builtin.CallModifier struct.zig
Normal file
@ -0,0 +1,35 @@
|
||||
pub const CallModifier = enum {
|
||||
/// Equivalent to function call syntax.
|
||||
auto,
|
||||
|
||||
/// Equivalent to async keyword used with function call syntax.
|
||||
async_kw,
|
||||
|
||||
/// Prevents tail call optimization. This guarantees that the return
|
||||
/// address will point to the callsite, as opposed to the callsite's
|
||||
/// callsite. If the call is otherwise required to be tail-called
|
||||
/// or inlined, a compile error is emitted instead.
|
||||
never_tail,
|
||||
|
||||
/// Guarantees that the call will not be inlined. If the call is
|
||||
/// otherwise required to be inlined, a compile error is emitted instead.
|
||||
never_inline,
|
||||
|
||||
/// Asserts that the function call will not suspend. This allows a
|
||||
/// non-async function to call an async function.
|
||||
no_async,
|
||||
|
||||
/// Guarantees that the call will be generated with tail call optimization.
|
||||
/// If this is not possible, a compile error is emitted instead.
|
||||
always_tail,
|
||||
|
||||
/// Guarantees that the call will inlined at the callsite.
|
||||
/// If this is not possible, a compile error is emitted instead.
|
||||
always_inline,
|
||||
|
||||
/// Evaluates the call at compile-time. If the call cannot be completed at
|
||||
/// compile-time, a compile error is emitted instead.
|
||||
compile_time,
|
||||
};
|
||||
|
||||
// syntax
|
11
doc/langref/cImport_builtin.zig
Normal file
11
doc/langref/cImport_builtin.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const c = @cImport({
|
||||
// See https://github.com/ziglang/zig/issues/515
|
||||
@cDefine("_NO_CRT_STDIO_INLINE", "1");
|
||||
@cInclude("stdio.h");
|
||||
});
|
||||
pub fn main() void {
|
||||
_ = c.printf("hello\n");
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// link_libc
|
8
doc/langref/catch.zig
Normal file
8
doc/langref/catch.zig
Normal file
@ -0,0 +1,8 @@
|
||||
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
|
||||
|
||||
fn doAThing(str: []u8) void {
|
||||
const number = parseU64(str, 10) catch 13;
|
||||
_ = number; // ...
|
||||
}
|
||||
|
||||
// syntax
|
8
doc/langref/catch_err_return.zig
Normal file
8
doc/langref/catch_err_return.zig
Normal file
@ -0,0 +1,8 @@
|
||||
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
|
||||
|
||||
fn doAThing(str: []u8) !void {
|
||||
const number = parseU64(str, 10) catch |err| return err;
|
||||
_ = number; // ...
|
||||
}
|
||||
|
||||
// syntax
|
18
doc/langref/change_active_union_field.zig
Normal file
18
doc/langref/change_active_union_field.zig
Normal file
@ -0,0 +1,18 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Foo = union {
|
||||
float: f32,
|
||||
int: u32,
|
||||
};
|
||||
|
||||
pub fn main() void {
|
||||
var f = Foo{ .int = 42 };
|
||||
bar(&f);
|
||||
}
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
f.* = Foo{ .float = 12.34 };
|
||||
std.debug.print("value: {}\n", .{f.float});
|
||||
}
|
||||
|
||||
// exe=succeed
|
14
doc/langref/checking_null_in_zig.zig
Normal file
14
doc/langref/checking_null_in_zig.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const Foo = struct{};
|
||||
fn doSomethingWithFoo(foo: *Foo) void { _ = foo; }
|
||||
|
||||
fn doAThing(optional_foo: ?*Foo) void {
|
||||
// do some stuff
|
||||
|
||||
if (optional_foo) |foo| {
|
||||
doSomethingWithFoo(foo);
|
||||
}
|
||||
|
||||
// do some stuff
|
||||
}
|
||||
|
||||
// syntax
|
13
doc/langref/cli_allocation.zig
Normal file
13
doc/langref/cli_allocation.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const allocator = arena.allocator();
|
||||
|
||||
const ptr = try allocator.create(i32);
|
||||
std.debug.print("ptr={*}\n", .{ptr});
|
||||
}
|
||||
|
||||
// exe=succeed
|
12
doc/langref/comments.zig
Normal file
12
doc/langref/comments.zig
Normal file
@ -0,0 +1,12 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
pub fn main() void {
|
||||
// Comments in Zig start with "//" and end at the next LF byte (end of line).
|
||||
// The line below is a comment and won't be executed.
|
||||
|
||||
//print("Hello?", .{});
|
||||
|
||||
print("Hello, world!\n", .{}); // another comment
|
||||
}
|
||||
|
||||
// exe=succeed
|
11
doc/langref/compile-time_duck_typing.zig
Normal file
11
doc/langref/compile-time_duck_typing.zig
Normal file
@ -0,0 +1,11 @@
|
||||
fn max(comptime T: type, a: T, b: T) T {
|
||||
return if (a > b) a else b;
|
||||
}
|
||||
fn gimmeTheBiggerFloat(a: f32, b: f32) f32 {
|
||||
return max(f32, a, b);
|
||||
}
|
||||
fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
|
||||
return max(u64, a, b);
|
||||
}
|
||||
|
||||
// syntax
|
4
doc/langref/compile_variables.zig
Normal file
4
doc/langref/compile_variables.zig
Normal file
@ -0,0 +1,4 @@
|
||||
const builtin = @import("builtin");
|
||||
const separator = if (builtin.os.tag == .windows) '\\' else '/';
|
||||
|
||||
// syntax
|
7
doc/langref/compiler_generated_function.zig
Normal file
7
doc/langref/compiler_generated_function.zig
Normal file
@ -0,0 +1,7 @@
|
||||
fn max(a: bool, b: bool) bool {
|
||||
{
|
||||
return a or b;
|
||||
}
|
||||
}
|
||||
|
||||
// syntax
|
15
doc/langref/constant_identifier_cannot_change.zig
Normal file
15
doc/langref/constant_identifier_cannot_change.zig
Normal file
@ -0,0 +1,15 @@
|
||||
const x = 1234;
|
||||
|
||||
fn foo() void {
|
||||
// It works at file scope as well as inside functions.
|
||||
const y = 5678;
|
||||
|
||||
// Once assigned, an identifier cannot be changed.
|
||||
y += 1;
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
foo();
|
||||
}
|
||||
|
||||
// exe=build_fail
|
22
doc/langref/defer_unwind.zig
Normal file
22
doc/langref/defer_unwind.zig
Normal file
@ -0,0 +1,22 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const print = std.debug.print;
|
||||
|
||||
test "defer unwinding" {
|
||||
print("\n", .{});
|
||||
|
||||
defer {
|
||||
print("1 ", .{});
|
||||
}
|
||||
defer {
|
||||
print("2 ", .{});
|
||||
}
|
||||
if (false) {
|
||||
// defers are not run if they are never executed.
|
||||
defer {
|
||||
print("3 ", .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test
|
19
doc/langref/doc_comments.zig
Normal file
19
doc/langref/doc_comments.zig
Normal file
@ -0,0 +1,19 @@
|
||||
/// A structure for storing a timestamp, with nanosecond precision (this is a
|
||||
/// multiline doc comment).
|
||||
const Timestamp = struct {
|
||||
/// The number of seconds since the epoch (this is also a doc comment).
|
||||
seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
|
||||
/// The number of nanoseconds past the second (doc comment again).
|
||||
nanos: u32,
|
||||
|
||||
/// Returns a `Timestamp` struct representing the Unix epoch; that is, the
|
||||
/// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
|
||||
pub fn unixEpoch() Timestamp {
|
||||
return Timestamp{
|
||||
.seconds = 0,
|
||||
.nanos = 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// syntax
|
4
doc/langref/enum_export.zig
Normal file
4
doc/langref/enum_export.zig
Normal file
@ -0,0 +1,4 @@
|
||||
const Foo = enum(c_int) { a, b, c };
|
||||
export fn entry(foo: Foo) void { _ = foo; }
|
||||
|
||||
// obj
|
4
doc/langref/enum_export_error.zig
Normal file
4
doc/langref/enum_export_error.zig
Normal file
@ -0,0 +1,4 @@
|
||||
const Foo = enum { a, b, c };
|
||||
export fn entry(foo: Foo) void { _ = foo; }
|
||||
|
||||
// obj=parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'C'
|
41
doc/langref/error_return_trace.zig
Normal file
41
doc/langref/error_return_trace.zig
Normal file
@ -0,0 +1,41 @@
|
||||
pub fn main() !void {
|
||||
try foo(12);
|
||||
}
|
||||
|
||||
fn foo(x: i32) !void {
|
||||
if (x >= 5) {
|
||||
try bar();
|
||||
} else {
|
||||
try bang2();
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() !void {
|
||||
if (baz()) {
|
||||
try quux();
|
||||
} else |err| switch (err) {
|
||||
error.FileNotFound => try hello(),
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() !void {
|
||||
try bang1();
|
||||
}
|
||||
|
||||
fn quux() !void {
|
||||
try bang2();
|
||||
}
|
||||
|
||||
fn hello() !void {
|
||||
try bang2();
|
||||
}
|
||||
|
||||
fn bang1() !void {
|
||||
return error.FileNotFound;
|
||||
}
|
||||
|
||||
fn bang2() !void {
|
||||
return error.PermissionDenied;
|
||||
}
|
||||
|
||||
// exe=fail
|
41
doc/langref/error_union_parsing_u64.zig
Normal file
41
doc/langref/error_union_parsing_u64.zig
Normal file
@ -0,0 +1,41 @@
|
||||
const std = @import("std");
|
||||
const maxInt = std.math.maxInt;
|
||||
|
||||
pub fn parseU64(buf: []const u8, radix: u8) !u64 {
|
||||
var x: u64 = 0;
|
||||
|
||||
for (buf) |c| {
|
||||
const digit = charToDigit(c);
|
||||
|
||||
if (digit >= radix) {
|
||||
return error.InvalidChar;
|
||||
}
|
||||
|
||||
// x *= radix
|
||||
var ov = @mulWithOverflow(x, radix);
|
||||
if (ov[1] != 0) return error.OverFlow;
|
||||
|
||||
// x += digit
|
||||
ov = @addWithOverflow(ov[0], digit);
|
||||
if (ov[1] != 0) return error.OverFlow;
|
||||
x = ov[0];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
fn charToDigit(c: u8) u8 {
|
||||
return switch (c) {
|
||||
'0' ... '9' => c - '0',
|
||||
'A' ... 'Z' => c - 'A' + 10,
|
||||
'a' ... 'z' => c - 'a' + 10,
|
||||
else => maxInt(u8),
|
||||
};
|
||||
}
|
||||
|
||||
test "parse u64" {
|
||||
const result = try parseU64("1234", 10);
|
||||
try std.testing.expect(result == 1234);
|
||||
}
|
||||
|
||||
// test
|
3
doc/langref/export_any_symbol_name.zig
Normal file
3
doc/langref/export_any_symbol_name.zig
Normal file
@ -0,0 +1,3 @@
|
||||
export fn @"A function name that is a complete sentence."() void {}
|
||||
|
||||
// obj
|
7
doc/langref/export_builtin.zig
Normal file
7
doc/langref/export_builtin.zig
Normal file
@ -0,0 +1,7 @@
|
||||
comptime {
|
||||
@export(internalName, .{ .name = "foo", .linkage = .strong });
|
||||
}
|
||||
|
||||
fn internalName() callconv(.C) void {}
|
||||
|
||||
// obj
|
3
doc/langref/export_builtin_equivalent_code.zig
Normal file
3
doc/langref/export_builtin_equivalent_code.zig
Normal file
@ -0,0 +1,3 @@
|
||||
export fn foo() void {}
|
||||
|
||||
// obj
|
12
doc/langref/fibonacci_comptime_infinite_recursion.zig
Normal file
12
doc/langref/fibonacci_comptime_infinite_recursion.zig
Normal file
@ -0,0 +1,12 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn fibonacci(index: i32) i32 {
|
||||
//if (index < 2) return index;
|
||||
return fibonacci(index - 1) + fibonacci(index - 2);
|
||||
}
|
||||
|
||||
test "fibonacci" {
|
||||
try comptime assert(fibonacci(7) == 13);
|
||||
}
|
||||
|
||||
// syntax
|
14
doc/langref/float_literals.zig
Normal file
14
doc/langref/float_literals.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const floating_point = 123.0E+77;
|
||||
const another_float = 123.0;
|
||||
const yet_another = 123.0e+77;
|
||||
|
||||
const hex_floating_point = 0x103.70p-5;
|
||||
const another_hex_float = 0x103.70;
|
||||
const yet_another_hex_float = 0x103.70P-5;
|
||||
|
||||
// underscores may be placed between two digits as a visual separator
|
||||
const lightspeed = 299_792_458.000_000;
|
||||
const nanosecond = 0.000_000_001;
|
||||
const more_hex = 0x1234_5678.9ABC_CDEFp-10;
|
||||
|
||||
// syntax
|
12
doc/langref/float_mode_exe.zig
Normal file
12
doc/langref/float_mode_exe.zig
Normal file
@ -0,0 +1,12 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
extern fn foo_strict(x: f64) f64;
|
||||
extern fn foo_optimized(x: f64) f64;
|
||||
|
||||
pub fn main() void {
|
||||
const x = 0.001;
|
||||
print("optimized = {}\n", .{foo_optimized(x)});
|
||||
print("strict = {}\n", .{foo_strict(x)});
|
||||
}
|
||||
|
||||
// syntax
|
15
doc/langref/float_mode_obj.zig
Normal file
15
doc/langref/float_mode_obj.zig
Normal file
@ -0,0 +1,15 @@
|
||||
const std = @import("std");
|
||||
const big = @as(f64, 1 << 40);
|
||||
|
||||
export fn foo_strict(x: f64) f64 {
|
||||
return x + big - big;
|
||||
}
|
||||
|
||||
export fn foo_optimized(x: f64) f64 {
|
||||
@setFloatMode(.optimized);
|
||||
return x + big - big;
|
||||
}
|
||||
|
||||
// obj
|
||||
// optimize=ReleaseFast
|
||||
// disable_cache
|
7
doc/langref/float_special_values.zig
Normal file
7
doc/langref/float_special_values.zig
Normal file
@ -0,0 +1,7 @@
|
||||
const std = @import("std");
|
||||
|
||||
const inf = std.math.inf(f32);
|
||||
const negative_inf = -std.math.inf(f64);
|
||||
const nan = std.math.nan(f128);
|
||||
|
||||
// syntax
|
15
doc/langref/generic_data_structure.zig
Normal file
15
doc/langref/generic_data_structure.zig
Normal file
@ -0,0 +1,15 @@
|
||||
fn List(comptime T: type) type {
|
||||
return struct {
|
||||
items: []T,
|
||||
len: usize,
|
||||
};
|
||||
}
|
||||
|
||||
// The generic List data structure can be instantiated by passing in a type:
|
||||
var buffer: [10]i32 = undefined;
|
||||
var list = List(i32){
|
||||
.items = &buffer,
|
||||
.len = 0,
|
||||
};
|
||||
|
||||
// syntax
|
11
doc/langref/handle_error_with_catch_block.zig.zig
Normal file
11
doc/langref/handle_error_with_catch_block.zig.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
|
||||
|
||||
fn doAThing(str: []u8) void {
|
||||
const number = parseU64(str, 10) catch blk: {
|
||||
// do things
|
||||
break :blk 13;
|
||||
};
|
||||
_ = number; // number is now initialized
|
||||
}
|
||||
|
||||
// syntax
|
8
doc/langref/hello.zig
Normal file
8
doc/langref/hello.zig
Normal file
@ -0,0 +1,8 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Hello, {s}!\n", .{"world"});
|
||||
}
|
||||
|
||||
// exe=succeed
|
7
doc/langref/hello_again.zig
Normal file
7
doc/langref/hello_again.zig
Normal file
@ -0,0 +1,7 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
std.debug.print("Hello, world!\n", .{});
|
||||
}
|
||||
|
||||
// exe=succeed
|
14
doc/langref/identifiers.zig
Normal file
14
doc/langref/identifiers.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const @"identifier with spaces in it" = 0xff;
|
||||
const @"1SmallStep4Man" = 112358;
|
||||
|
||||
const c = @import("std").c;
|
||||
pub extern "c" fn @"error"() void;
|
||||
pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
|
||||
|
||||
const Color = enum {
|
||||
red,
|
||||
@"really red",
|
||||
};
|
||||
const color: Color = .@"really red";
|
||||
|
||||
// syntax
|
34
doc/langref/inline_assembly.zig
Normal file
34
doc/langref/inline_assembly.zig
Normal file
@ -0,0 +1,34 @@
|
||||
pub fn main() noreturn {
|
||||
const msg = "hello world\n";
|
||||
_ = syscall3(SYS_write, STDOUT_FILENO, @intFromPtr(msg), msg.len);
|
||||
_ = syscall1(SYS_exit, 0);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub const SYS_write = 1;
|
||||
pub const SYS_exit = 60;
|
||||
|
||||
pub const STDOUT_FILENO = 1;
|
||||
|
||||
pub fn syscall1(number: usize, arg1: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (number),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (number),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3),
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// target=x86_64-linux
|
11
doc/langref/inline_call.zig
Normal file
11
doc/langref/inline_call.zig
Normal file
@ -0,0 +1,11 @@
|
||||
test "inline function call" {
|
||||
if (foo(1200, 34) != 1234) {
|
||||
@compileError("bad");
|
||||
}
|
||||
}
|
||||
|
||||
inline fn foo(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// test
|
9
doc/langref/inline_prong_range.zig
Normal file
9
doc/langref/inline_prong_range.zig
Normal file
@ -0,0 +1,9 @@
|
||||
fn isFieldOptional(comptime T: type, field_index: usize) !bool {
|
||||
const fields = @typeInfo(T).Struct.fields;
|
||||
return switch (field_index) {
|
||||
inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .Optional,
|
||||
else => return error.IndexOutOfBounds,
|
||||
};
|
||||
}
|
||||
|
||||
// syntax
|
13
doc/langref/integer_literals.zig
Normal file
13
doc/langref/integer_literals.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const decimal_int = 98222;
|
||||
const hex_int = 0xff;
|
||||
const another_hex_int = 0xFF;
|
||||
const octal_int = 0o755;
|
||||
const binary_int = 0b11110000;
|
||||
|
||||
// underscores may be placed between two digits as a visual separator
|
||||
const one_billion = 1_000_000_000;
|
||||
const binary_mask = 0b1_1111_1111;
|
||||
const permissions = 0o7_5_5;
|
||||
const big_address = 0xFF80_0000_0000_0000;
|
||||
|
||||
// syntax
|
5
doc/langref/invalid_doc-comment.zig
Normal file
5
doc/langref/invalid_doc-comment.zig
Normal file
@ -0,0 +1,5 @@
|
||||
/// doc-comment
|
||||
//! top-level doc-comment
|
||||
const std = @import("std");
|
||||
|
||||
// obj=expected type expression, found 'a document comment'
|
10
doc/langref/macro.zig
Normal file
10
doc/langref/macro.zig
Normal file
@ -0,0 +1,10 @@
|
||||
pub export fn foo() c_int {
|
||||
var a: c_int = 1;
|
||||
_ = &a;
|
||||
var b: c_int = 2;
|
||||
_ = &b;
|
||||
return a + b;
|
||||
}
|
||||
pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9
|
||||
|
||||
// syntax
|
10
doc/langref/math.zig
Normal file
10
doc/langref/math.zig
Normal file
@ -0,0 +1,10 @@
|
||||
extern fn print(i32) void;
|
||||
|
||||
export fn add(a: i32, b: i32) void {
|
||||
print(a + b);
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// target=wasm32-freestanding
|
||||
// additional_option=-fno-entry
|
||||
// additional_option=--export=add
|
14
doc/langref/math_add.zig
Normal file
14
doc/langref/math_add.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const math = @import("std").math;
|
||||
const print = @import("std").debug.print;
|
||||
pub fn main() !void {
|
||||
var byte: u8 = 255;
|
||||
|
||||
byte = if (math.add(u8, byte, 1)) |result| result else |err| {
|
||||
print("unable to add one: {s}\n", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
|
||||
print("result: {}\n", .{byte});
|
||||
}
|
||||
|
||||
// exe=fail
|
5
doc/langref/mathtest.zig
Normal file
5
doc/langref/mathtest.zig
Normal file
@ -0,0 +1,5 @@
|
||||
export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// syntax
|
10
doc/langref/multiline_string_literals.zig
Normal file
10
doc/langref/multiline_string_literals.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const hello_world_in_c =
|
||||
\\#include <stdio.h>
|
||||
\\
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ printf("hello world\n");
|
||||
\\ return 0;
|
||||
\\}
|
||||
;
|
||||
|
||||
// syntax
|
11
doc/langref/mutable_var.zig
Normal file
11
doc/langref/mutable_var.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
pub fn main() void {
|
||||
var y: i32 = 5678;
|
||||
|
||||
y += 1;
|
||||
|
||||
print("{d}", .{y});
|
||||
}
|
||||
|
||||
// exe=succeed
|
11
doc/langref/not_atomic_cmpxchgStrong.zig
Normal file
11
doc/langref/not_atomic_cmpxchgStrong.zig
Normal file
@ -0,0 +1,11 @@
|
||||
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
|
||||
const old_value = ptr.*;
|
||||
if (old_value == expected_value) {
|
||||
ptr.* = new_value;
|
||||
return null;
|
||||
} else {
|
||||
return old_value;
|
||||
}
|
||||
}
|
||||
|
||||
// syntax
|
3
doc/langref/null.zig
Normal file
3
doc/langref/null.zig
Normal file
@ -0,0 +1,3 @@
|
||||
const optional_value: ?i32 = null;
|
||||
|
||||
// syntax
|
7
doc/langref/optional_integer.zig
Normal file
7
doc/langref/optional_integer.zig
Normal file
@ -0,0 +1,7 @@
|
||||
// normal integer
|
||||
const normal_int: i32 = 1234;
|
||||
|
||||
// optional integer
|
||||
const optional_int: ?i32 = 5678;
|
||||
|
||||
// syntax
|
33
doc/langref/poc_printValue_fn.zig
Normal file
33
doc/langref/poc_printValue_fn.zig
Normal file
@ -0,0 +1,33 @@
|
||||
const Writer = struct {
|
||||
pub fn printValue(self: *Writer, value: anytype) !void {
|
||||
switch (@typeInfo(@TypeOf(value))) {
|
||||
.Int => {
|
||||
return self.writeInt(value);
|
||||
},
|
||||
.Float => {
|
||||
return self.writeFloat(value);
|
||||
},
|
||||
.Pointer => {
|
||||
return self.write(value);
|
||||
},
|
||||
else => {
|
||||
@compileError("Unable to print type '" ++ @typeName(@TypeOf(value)) ++ "'");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn write(self: *Writer, value: []const u8) !void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
fn writeInt(self: *Writer, value: anytype) !void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
fn writeFloat(self: *Writer, value: anytype) !void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
};
|
||||
|
||||
// syntax
|
79
doc/langref/poc_print_fn.zig
Normal file
79
doc/langref/poc_print_fn.zig
Normal file
@ -0,0 +1,79 @@
|
||||
const Writer = struct {
|
||||
/// Calls print and then flushes the buffer.
|
||||
pub fn print(self: *Writer, comptime format: []const u8, args: anytype) anyerror!void {
|
||||
const State = enum {
|
||||
start,
|
||||
open_brace,
|
||||
close_brace,
|
||||
};
|
||||
|
||||
comptime var start_index: usize = 0;
|
||||
comptime var state = State.start;
|
||||
comptime var next_arg: usize = 0;
|
||||
|
||||
inline for (format, 0..) |c, i| {
|
||||
switch (state) {
|
||||
State.start => switch (c) {
|
||||
'{' => {
|
||||
if (start_index < i) try self.write(format[start_index..i]);
|
||||
state = State.open_brace;
|
||||
},
|
||||
'}' => {
|
||||
if (start_index < i) try self.write(format[start_index..i]);
|
||||
state = State.close_brace;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
State.open_brace => switch (c) {
|
||||
'{' => {
|
||||
state = State.start;
|
||||
start_index = i;
|
||||
},
|
||||
'}' => {
|
||||
try self.printValue(args[next_arg]);
|
||||
next_arg += 1;
|
||||
state = State.start;
|
||||
start_index = i + 1;
|
||||
},
|
||||
's' => {
|
||||
continue;
|
||||
},
|
||||
else => @compileError("Unknown format character: " ++ [1]u8{c}),
|
||||
},
|
||||
State.close_brace => switch (c) {
|
||||
'}' => {
|
||||
state = State.start;
|
||||
start_index = i;
|
||||
},
|
||||
else => @compileError("Single '}' encountered in format string"),
|
||||
},
|
||||
}
|
||||
}
|
||||
comptime {
|
||||
if (args.len != next_arg) {
|
||||
@compileError("Unused arguments");
|
||||
}
|
||||
if (state != State.start) {
|
||||
@compileError("Incomplete format string: " ++ format);
|
||||
}
|
||||
}
|
||||
if (start_index < format.len) {
|
||||
try self.write(format[start_index..format.len]);
|
||||
}
|
||||
try self.flush();
|
||||
}
|
||||
|
||||
fn write(self: *Writer, value: []const u8) !void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
pub fn printValue(self: *Writer, value: anytype) !void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
fn flush(self: *Writer) !void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
// syntax
|
10
doc/langref/print.zig
Normal file
10
doc/langref/print.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
const a_number: i32 = 1234;
|
||||
const a_string = "foobar";
|
||||
|
||||
pub fn main() void {
|
||||
print("here is a string: '{s}' here is a number: {}\n", .{a_string, a_number});
|
||||
}
|
||||
|
||||
// exe=succeed
|
11
doc/langref/print_comptime-known_format.zig
Normal file
11
doc/langref/print_comptime-known_format.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
const a_number: i32 = 1234;
|
||||
const a_string = "foobar";
|
||||
const fmt = "here is a string: '{s}' here is a number: {}\n";
|
||||
|
||||
pub fn main() void {
|
||||
print(fmt, .{a_string, a_number});
|
||||
}
|
||||
|
||||
// exe=succeed
|
15
doc/langref/redundant_fqn.zig
Normal file
15
doc/langref/redundant_fqn.zig
Normal file
@ -0,0 +1,15 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const json = struct {
|
||||
pub const JsonValue = union(enum) {
|
||||
number: f64,
|
||||
boolean: bool,
|
||||
// ...
|
||||
};
|
||||
};
|
||||
|
||||
pub fn main() void {
|
||||
std.debug.print("{s}\n", .{@typeName(json.JsonValue)});
|
||||
}
|
||||
|
||||
// exe=succeed
|
13
doc/langref/result_location_interfering_with_swap.zig
Normal file
13
doc/langref/result_location_interfering_with_swap.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const expect = @import("std").testing.expect;
|
||||
test "attempt to swap array elements with array initializer" {
|
||||
var arr: [2]u32 = .{ 1, 2 };
|
||||
arr = .{ arr[1], arr[0] };
|
||||
// The previous line is equivalent to the following two lines:
|
||||
// arr[0] = arr[1];
|
||||
// arr[1] = arr[0];
|
||||
// So this fails!
|
||||
try expect(arr[0] == 2); // succeeds
|
||||
try expect(arr[1] == 1); // fails
|
||||
}
|
||||
|
||||
// test_error=
|
12
doc/langref/result_type_propagation.zig
Normal file
12
doc/langref/result_type_propagation.zig
Normal file
@ -0,0 +1,12 @@
|
||||
const expectEqual = @import("std").testing.expectEqual;
|
||||
test "result type propagates through struct initializer" {
|
||||
const S = struct { x: u32 };
|
||||
const val: u64 = 123;
|
||||
const s: S = .{ .x = @intCast(val) };
|
||||
// .{ .x = @intCast(val) } has result type `S` due to the type annotation
|
||||
// @intCast(val) has result type `u32` due to the type of the field `S.x`
|
||||
// val has no result type, as it is permitted to be any integer type
|
||||
try expectEqual(@as(u32, 123), s.x);
|
||||
}
|
||||
|
||||
// test
|
11
doc/langref/runtime_divExact_remainder.zig
Normal file
11
doc/langref/runtime_divExact_remainder.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var a: u32 = 10;
|
||||
var b: u32 = 3;
|
||||
_ = .{ &a, &b };
|
||||
const c = @divExact(a, b);
|
||||
std.debug.print("value: {}\n", .{c});
|
||||
}
|
||||
|
||||
// exe=fail
|
11
doc/langref/runtime_division_by_zero.zig
Normal file
11
doc/langref/runtime_division_by_zero.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var a: u32 = 1;
|
||||
var b: u32 = 0;
|
||||
_ = .{ &a, &b };
|
||||
const c = a / b;
|
||||
std.debug.print("value: {}\n", .{c});
|
||||
}
|
||||
|
||||
// exe=fail
|
13
doc/langref/runtime_incorrect_pointer_alignment.zig
Normal file
13
doc/langref/runtime_incorrect_pointer_alignment.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const mem = @import("std").mem;
|
||||
pub fn main() !void {
|
||||
var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
|
||||
const bytes = mem.sliceAsBytes(array[0..]);
|
||||
if (foo(bytes) != 0x11111111) return error.Wrong;
|
||||
}
|
||||
fn foo(bytes: []u8) u32 {
|
||||
const slice4 = bytes[1..5];
|
||||
const int_slice = mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
|
||||
return int_slice[0];
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_index_out_of_bounds.zig
Normal file
10
doc/langref/runtime_index_out_of_bounds.zig
Normal file
@ -0,0 +1,10 @@
|
||||
pub fn main() void {
|
||||
const x = foo("hello");
|
||||
_ = x;
|
||||
}
|
||||
|
||||
fn foo(x: []const u8) u8 {
|
||||
return x[5];
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_invalid_cast.zig
Normal file
10
doc/langref/runtime_invalid_cast.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var value: i32 = -1; // runtime-known
|
||||
_ = &value;
|
||||
const unsigned: u32 = @intCast(value);
|
||||
std.debug.print("value: {}\n", .{unsigned});
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_invalid_cast_truncate.zig
Normal file
10
doc/langref/runtime_invalid_cast_truncate.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var spartan_count: u16 = 300; // runtime-known
|
||||
_ = &spartan_count;
|
||||
const byte: u8 = @intCast(spartan_count);
|
||||
std.debug.print("value: {}\n", .{byte});
|
||||
}
|
||||
|
||||
// exe=fail
|
16
doc/langref/runtime_invalid_enum_cast.zig
Normal file
16
doc/langref/runtime_invalid_enum_cast.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Foo = enum {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
};
|
||||
|
||||
pub fn main() void {
|
||||
var a: u2 = 3;
|
||||
_ = &a;
|
||||
const b: Foo = @enumFromInt(a);
|
||||
std.debug.print("value: {s}\n", .{@tagName(b)});
|
||||
}
|
||||
|
||||
// exe=fail
|
11
doc/langref/runtime_invalid_error_code.zig
Normal file
11
doc/langref/runtime_invalid_error_code.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
const err = error.AnError;
|
||||
var number = @intFromError(err) + 500;
|
||||
_ = &number;
|
||||
const invalid_err = @errorFromInt(number);
|
||||
std.debug.print("value: {}\n", .{invalid_err});
|
||||
}
|
||||
|
||||
// exe=fail
|
19
doc/langref/runtime_invalid_error_set_cast.zig
Normal file
19
doc/langref/runtime_invalid_error_set_cast.zig
Normal file
@ -0,0 +1,19 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Set1 = error{
|
||||
A,
|
||||
B,
|
||||
};
|
||||
const Set2 = error{
|
||||
A,
|
||||
C,
|
||||
};
|
||||
pub fn main() void {
|
||||
foo(Set1.B);
|
||||
}
|
||||
fn foo(set1: Set1) void {
|
||||
const x: Set2 = @errorCast(set1);
|
||||
std.debug.print("value: {}\n", .{x});
|
||||
}
|
||||
|
||||
// exe=fail
|
8
doc/langref/runtime_invalid_null_pointer_cast.zig
Normal file
8
doc/langref/runtime_invalid_null_pointer_cast.zig
Normal file
@ -0,0 +1,8 @@
|
||||
pub fn main() void {
|
||||
var opt_ptr: ?*i32 = null;
|
||||
_ = &opt_ptr;
|
||||
const ptr: *i32 = @ptrCast(opt_ptr);
|
||||
_ = ptr;
|
||||
}
|
||||
|
||||
// exe=fail
|
@ -0,0 +1,8 @@
|
||||
pub fn main() void {
|
||||
var float: f32 = 4294967296; // runtime-known
|
||||
_ = &float;
|
||||
const int: i32 = @intFromFloat(float);
|
||||
_ = int;
|
||||
}
|
||||
|
||||
// exe=fail
|
9
doc/langref/runtime_overflow.zig
Normal file
9
doc/langref/runtime_overflow.zig
Normal file
@ -0,0 +1,9 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var byte: u8 = 255;
|
||||
byte += 1;
|
||||
std.debug.print("value: {}\n", .{byte});
|
||||
}
|
||||
|
||||
// exe=fail
|
7
doc/langref/runtime_reaching_unreachable.zig
Normal file
7
doc/langref/runtime_reaching_unreachable.zig
Normal file
@ -0,0 +1,7 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
std.debug.assert(false);
|
||||
}
|
||||
|
||||
// exe=fail
|
11
doc/langref/runtime_remainder_division_by_zero.zig
Normal file
11
doc/langref/runtime_remainder_division_by_zero.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var a: u32 = 10;
|
||||
var b: u32 = 0;
|
||||
_ = .{ &a, &b };
|
||||
const c = a % b;
|
||||
std.debug.print("value: {}\n", .{c});
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_shlExact_overflow.zig
Normal file
10
doc/langref/runtime_shlExact_overflow.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var x: u8 = 0b01010101; // runtime-known
|
||||
_ = &x;
|
||||
const y = @shlExact(x, 2);
|
||||
std.debug.print("value: {}\n", .{y});
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_shrExact_overflow.zig
Normal file
10
doc/langref/runtime_shrExact_overflow.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var x: u8 = 0b10101010; // runtime-known
|
||||
_ = &x;
|
||||
const y = @shrExact(x, 2);
|
||||
std.debug.print("value: {}\n", .{y});
|
||||
}
|
||||
|
||||
// exe=fail
|
12
doc/langref/runtime_unwrap_error.zig
Normal file
12
doc/langref/runtime_unwrap_error.zig
Normal file
@ -0,0 +1,12 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
const number = getNumberOrFail() catch unreachable;
|
||||
std.debug.print("value: {}\n", .{number});
|
||||
}
|
||||
|
||||
fn getNumberOrFail() !i32 {
|
||||
return error.UnableToReturnNumber;
|
||||
}
|
||||
|
||||
// exe=fail
|
10
doc/langref/runtime_unwrap_null.zig
Normal file
10
doc/langref/runtime_unwrap_null.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
var optional_number: ?i32 = null;
|
||||
_ = &optional_number;
|
||||
const number = optional_number.?;
|
||||
std.debug.print("value: {}\n", .{number});
|
||||
}
|
||||
|
||||
// exe=fail
|
5
doc/langref/runtime_vs_comptime.zig
Normal file
5
doc/langref/runtime_vs_comptime.zig
Normal file
@ -0,0 +1,5 @@
|
||||
fn divide(a: i32, b: i32) i32 {
|
||||
return a / b;
|
||||
}
|
||||
|
||||
// syntax
|
18
doc/langref/runtime_wrong_union_field_access.zig
Normal file
18
doc/langref/runtime_wrong_union_field_access.zig
Normal file
@ -0,0 +1,18 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Foo = union {
|
||||
float: f32,
|
||||
int: u32,
|
||||
};
|
||||
|
||||
pub fn main() void {
|
||||
var f = Foo{ .int = 42 };
|
||||
bar(&f);
|
||||
}
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
f.float = 12.34;
|
||||
std.debug.print("value: {}\n", .{f.float});
|
||||
}
|
||||
|
||||
// exe=fail
|
15
doc/langref/sentinel-terminated_pointer.zig
Normal file
15
doc/langref/sentinel-terminated_pointer.zig
Normal file
@ -0,0 +1,15 @@
|
||||
const std = @import("std");
|
||||
|
||||
// This is also available as `std.c.printf`.
|
||||
pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
_ = printf("Hello, world!\n"); // OK
|
||||
|
||||
const msg = "Hello, world!\n";
|
||||
const non_null_terminated_msg: [msg.len]u8 = msg.*;
|
||||
_ = printf(&non_null_terminated_msg);
|
||||
}
|
||||
|
||||
// exe=build_fail
|
||||
// link_libc
|
3
doc/langref/single_value_error_set.zig
Normal file
3
doc/langref/single_value_error_set.zig
Normal file
@ -0,0 +1,3 @@
|
||||
const err = (error {FileNotFound}).FileNotFound;
|
||||
|
||||
// syntax
|
3
doc/langref/single_value_error_set_shortcut.zig
Normal file
3
doc/langref/single_value_error_set_shortcut.zig
Normal file
@ -0,0 +1,3 @@
|
||||
const err = error.FileNotFound;
|
||||
|
||||
// syntax
|
41
doc/langref/stack_trace.zig
Normal file
41
doc/langref/stack_trace.zig
Normal file
@ -0,0 +1,41 @@
|
||||
pub fn main() void {
|
||||
foo(12);
|
||||
}
|
||||
|
||||
fn foo(x: i32) void {
|
||||
if (x >= 5) {
|
||||
bar();
|
||||
} else {
|
||||
bang2();
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() void {
|
||||
if (baz()) {
|
||||
quux();
|
||||
} else {
|
||||
hello();
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() bool {
|
||||
return bang1();
|
||||
}
|
||||
|
||||
fn quux() void {
|
||||
bang2();
|
||||
}
|
||||
|
||||
fn hello() void {
|
||||
bang2();
|
||||
}
|
||||
|
||||
fn bang1() bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn bang2() void {
|
||||
@panic("PermissionDenied");
|
||||
}
|
||||
|
||||
// exe=fail
|
21
doc/langref/string_literals.zig
Normal file
21
doc/langref/string_literals.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const print = @import("std").debug.print;
|
||||
const mem = @import("std").mem; // will be used to compare bytes
|
||||
|
||||
pub fn main() void {
|
||||
const bytes = "hello";
|
||||
print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u8
|
||||
print("{d}\n", .{bytes.len}); // 5
|
||||
print("{c}\n", .{bytes[1]}); // 'e'
|
||||
print("{d}\n", .{bytes[5]}); // 0
|
||||
print("{}\n", .{'e' == '\x65'}); // true
|
||||
print("{d}\n", .{'\u{1f4a9}'}); // 128169
|
||||
print("{d}\n", .{'💯'}); // 128175
|
||||
print("{u}\n", .{'⚡'});
|
||||
print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true
|
||||
print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true
|
||||
const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.
|
||||
print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...
|
||||
print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters
|
||||
}
|
||||
|
||||
// exe=succeed
|
15
doc/langref/struct_default_field_values.zig
Normal file
15
doc/langref/struct_default_field_values.zig
Normal file
@ -0,0 +1,15 @@
|
||||
const Foo = struct {
|
||||
a: i32 = 1234,
|
||||
b: i32,
|
||||
};
|
||||
|
||||
test "default struct initialization fields" {
|
||||
const x: Foo = .{
|
||||
.b = 5,
|
||||
};
|
||||
if (x.a + x.b != 1239) {
|
||||
comptime unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
// test
|
11
doc/langref/struct_default_value.zig
Normal file
11
doc/langref/struct_default_value.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const Threshold = struct {
|
||||
minimum: f32,
|
||||
maximum: f32,
|
||||
|
||||
const default: Threshold = .{
|
||||
.minimum = 0.25,
|
||||
.maximum = 0.75,
|
||||
};
|
||||
};
|
||||
|
||||
// syntax
|
16
doc/langref/struct_name.zig
Normal file
16
doc/langref/struct_name.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
const Foo = struct {};
|
||||
std.debug.print("variable: {s}\n", .{@typeName(Foo)});
|
||||
std.debug.print("anonymous: {s}\n", .{@typeName(struct {})});
|
||||
std.debug.print("function: {s}\n", .{@typeName(List(i32))});
|
||||
}
|
||||
|
||||
fn List(comptime T: type) type {
|
||||
return struct {
|
||||
x: T,
|
||||
};
|
||||
}
|
||||
|
||||
// exe=succeed
|
16
doc/langref/test_TypeOf_builtin.zig
Normal file
16
doc/langref/test_TypeOf_builtin.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test "no runtime side effects" {
|
||||
var data: i32 = 0;
|
||||
const T = @TypeOf(foo(i32, &data));
|
||||
try comptime expect(T == i32);
|
||||
try expect(data == 0);
|
||||
}
|
||||
|
||||
fn foo(comptime T: type, ptr: *T) T {
|
||||
ptr.* += 1;
|
||||
return ptr.*;
|
||||
}
|
||||
|
||||
// test
|
16
doc/langref/test_aligned_struct_fields.zig
Normal file
16
doc/langref/test_aligned_struct_fields.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
test "aligned struct fields" {
|
||||
const S = struct {
|
||||
a: u32 align(2),
|
||||
b: u32 align(64),
|
||||
};
|
||||
var foo = S{ .a = 1, .b = 2 };
|
||||
|
||||
try expectEqual(64, @alignOf(S));
|
||||
try expectEqual(*align(2) u32, @TypeOf(&foo.a));
|
||||
try expectEqual(*align(64) u32, @TypeOf(&foo.b));
|
||||
}
|
||||
|
||||
// test
|
20
doc/langref/test_allocator.zig
Normal file
20
doc/langref/test_allocator.zig
Normal file
@ -0,0 +1,20 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test "using an allocator" {
|
||||
var buffer: [100]u8 = undefined;
|
||||
var fba = std.heap.FixedBufferAllocator.init(&buffer);
|
||||
const allocator = fba.allocator();
|
||||
const result = try concat(allocator, "foo", "bar");
|
||||
try expect(std.mem.eql(u8, "foobar", result));
|
||||
}
|
||||
|
||||
fn concat(allocator: Allocator, a: []const u8, b: []const u8) ![]u8 {
|
||||
const result = try allocator.alloc(u8, a.len + b.len);
|
||||
@memcpy(result[0..a.len], a);
|
||||
@memcpy(result[a.len..], b);
|
||||
return result;
|
||||
}
|
||||
|
||||
// test
|
11
doc/langref/test_allowzero.zig
Normal file
11
doc/langref/test_allowzero.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test "allowzero" {
|
||||
var zero: usize = 0; // var to make to runtime-known
|
||||
_ = &zero; // suppress 'var is never mutated' error
|
||||
const ptr: *allowzero i32 = @ptrFromInt(zero);
|
||||
try expect(@intFromPtr(ptr) == 0);
|
||||
}
|
||||
|
||||
// test
|
7
doc/langref/test_ambiguous_coercion.zig
Normal file
7
doc/langref/test_ambiguous_coercion.zig
Normal file
@ -0,0 +1,7 @@
|
||||
// Compile time coercion of float to int
|
||||
test "implicit cast to comptime_int" {
|
||||
const f: f32 = 54.0 / 5;
|
||||
_ = f;
|
||||
}
|
||||
|
||||
// test_error=
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user