Skip to content

Commit c764d8b

Browse files
committed
Add various Zig code examples demonstrating switch statements, type casting, unions, and vector operations
- Implement basic and advanced switch statement examples in `switch.zig` - Introduce type casting examples in `type-cast.zig` - Create union type examples in `union.zig` - Add unit tests for basic functions in `unit_test.zig` - Implement unreachable code demonstration in `unreachable.zig` - Showcase vector operations including basic usage, splatting, reduction, shuffling, and selection in `vector.zig`
1 parent d935c5b commit c764d8b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+6424
-8
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
strategy:
2323
matrix:
2424
os: [ubuntu-latest, macos-latest, windows-latest]
25-
version: [0.11.0, 0.12.1, 0.13.0, ""]
25+
version: [0.11.0, 0.12.1, 0.13.0, 0.14.0, ""]
2626
fail-fast: false
2727
runs-on: ${{ matrix.os }}
2828
steps:

build/0.15.zig

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,28 @@ pub fn build(b: *Build) void {
4444
// build exe
4545
const exe = b.addExecutable(.{
4646
.name = output_name,
47-
.root_source_file = b.path(path),
48-
.target = target,
49-
.optimize = optimize,
47+
.root_module = b.addModule(output_name, .{
48+
.root_source_file = b.path(path),
49+
.target = target,
50+
.optimize = optimize,
51+
}),
5052
});
5153
exe.linkLibC();
5254

5355
// add to default install
5456
b.installArtifact(exe);
5557

5658
// build test
59+
const test_name = std.fmt.allocPrint(b.allocator, "{s}_test", .{output_name}) catch |err| {
60+
log.err("fmt test name failed, err is {}", .{err});
61+
std.process.exit(1);
62+
};
5763
const unit_tests = b.addTest(.{
58-
.root_source_file = b.path(path),
59-
.target = target,
60-
.optimize = optimize,
64+
.root_module = b.addModule(test_name, .{
65+
.root_source_file = b.path(path),
66+
.target = target,
67+
.optimize = optimize,
68+
}),
6169
});
6270

6371
// add to default install

course/code/15

Lines changed: 0 additions & 1 deletion
This file was deleted.

course/code/15/array.zig

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
pub fn main() !void {
2+
CreateArray.main();
3+
Matrix.main();
4+
TerminatedArray.main();
5+
Multiply.main();
6+
Connect.main();
7+
FuncInitArray.main();
8+
ComptimeInitArray.main();
9+
}
10+
11+
const CreateArray = struct {
12+
// #region create_array
13+
const print = @import("std").debug.print;
14+
15+
pub fn main() void {
16+
const message = [5]u8{ 'h', 'e', 'l', 'l', 'o' };
17+
// const message = [_]u8{ 'h', 'e', 'l', 'l', 'o' };
18+
print("{s}\n", .{message}); // hello
19+
print("{c}\n", .{message[0]}); // h
20+
}
21+
// #endregion create_array
22+
};
23+
24+
const Deconstruct = struct {
25+
// #region deconstruct
26+
const print = @import("std").debug.print;
27+
28+
fn swizzleRgbaToBgra(rgba: [4]u8) [4]u8 {
29+
// 解构
30+
const r, const g, const b, const a = rgba;
31+
return .{ b, g, r, a };
32+
}
33+
34+
pub fn main() void {
35+
const pos = [_]i32{ 1, 2 };
36+
// 解构
37+
const x, const y = pos;
38+
print("x = {}, y = {}\n", .{ x, y });
39+
40+
const orange: [4]u8 = .{ 255, 165, 0, 255 };
41+
print("{any}\n", .{swizzleRgbaToBgra(orange)});
42+
}
43+
// #endregion deconstruct
44+
};
45+
46+
const Matrix = struct {
47+
// #region matrix
48+
const print = @import("std").debug.print;
49+
50+
pub fn main() void {
51+
const matrix_4x4 = [4][4]f32{
52+
[_]f32{ 1.0, 0.0, 0.0, 0.0 },
53+
[_]f32{ 0.0, 1.0, 0.0, 1.0 },
54+
[_]f32{ 0.0, 0.0, 1.0, 0.0 },
55+
[_]f32{ 0.0, 0.0, 0.0, 1.0 },
56+
};
57+
58+
for (matrix_4x4, 0..) |arr_val, arr_index| {
59+
for (arr_val, 0..) |val, index| {
60+
print("元素{}-{}是: {}\n", .{ arr_index, index, val });
61+
}
62+
}
63+
}
64+
// #endregion matrix
65+
};
66+
67+
const TerminatedArray = struct {
68+
// #region terminated_array
69+
const print = @import("std").debug.print;
70+
71+
pub fn main() void {
72+
const array = [_:0]u8{ 1, 2, 3, 4 };
73+
print("数组长度为: {}\n", .{array.len}); // 4
74+
print("数组最后一个元素值: {}\n", .{array[array.len - 1]}); // 4
75+
print("哨兵值为: {}\n", .{array[array.len]}); // 0
76+
}
77+
// #endregion terminated_array
78+
};
79+
80+
const Multiply = struct {
81+
// #region multiply
82+
const print = @import("std").debug.print;
83+
84+
pub fn main() void {
85+
const small = [3]i8{ 1, 2, 3 };
86+
const big: [9]i8 = small ** 3;
87+
print("{any}\n", .{big}); // [9]i8{ 1, 2, 3, 1, 2, 3, 1, 2, 3 }
88+
}
89+
// #endregion multiply
90+
};
91+
92+
const Connect = struct {
93+
// #region connect
94+
const print = @import("std").debug.print;
95+
96+
pub fn main() void {
97+
const part_one = [_]i32{ 1, 2, 3, 4 };
98+
const part_two = [_]i32{ 5, 6, 7, 8 };
99+
const all_of_it = part_one ++ part_two; // [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }
100+
101+
_ = all_of_it;
102+
}
103+
// #endregion connect
104+
};
105+
106+
const FuncInitArray = struct {
107+
// #region func_init_array
108+
const print = @import("std").debug.print;
109+
110+
pub fn main() void {
111+
const array = [_]i32{make(3)} ** 10;
112+
print("{any}\n", .{array});
113+
}
114+
115+
fn make(x: i32) i32 {
116+
return x + 1;
117+
}
118+
// #endregion func_init_array
119+
};
120+
121+
const ComptimeInitArray = struct {
122+
// #region comptime_init_array
123+
const print = @import("std").debug.print;
124+
125+
pub fn main() void {
126+
const fancy_array = init: {
127+
var initial_value: [10]usize = undefined;
128+
for (&initial_value, 0..) |*pt, i| {
129+
pt.* = i;
130+
}
131+
break :init initial_value;
132+
};
133+
print("{any}\n", .{fancy_array});
134+
}
135+
// #endregion comptime_init_array
136+
};

course/code/15/assembly.zig

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
pub fn main() !void {}
2+
3+
const external_assembly = struct {
4+
// #region external_assembly
5+
const std = @import("std");
6+
7+
comptime {
8+
asm (
9+
\\.global my_func;
10+
\\.type my_func, @function;
11+
\\my_func:
12+
\\ lea (%rdi,%rsi,1),%eax
13+
\\ retq
14+
);
15+
}
16+
17+
extern fn my_func(a: i32, b: i32) i32;
18+
19+
pub fn main() void {
20+
std.debug.print("{}\n", .{my_func(2, 5)});
21+
}
22+
// #endregion external_assembly
23+
};
24+
25+
const inline_assembly = struct {
26+
// #region inline_assembly
27+
pub fn main() noreturn {
28+
const msg = "hello world\n";
29+
_ = syscall3(SYS_write, STDOUT_FILENO, @intFromPtr(msg), msg.len);
30+
_ = syscall1(SYS_exit, 0);
31+
unreachable;
32+
}
33+
34+
pub const SYS_write = 1;
35+
pub const SYS_exit = 60;
36+
37+
pub const STDOUT_FILENO = 1;
38+
39+
pub fn syscall1(number: usize, arg1: usize) usize {
40+
return asm volatile ("syscall"
41+
: [ret] "={rax}" (-> usize),
42+
: [number] "{rax}" (number),
43+
[arg1] "{rdi}" (arg1),
44+
: "rcx", "r11"
45+
);
46+
}
47+
48+
pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
49+
return asm volatile ("syscall"
50+
: [ret] "={rax}" (-> usize),
51+
: [number] "{rax}" (number),
52+
[arg1] "{rdi}" (arg1),
53+
[arg2] "{rsi}" (arg2),
54+
[arg3] "{rdx}" (arg3),
55+
: "rcx", "r11"
56+
);
57+
}
58+
// #endregion inline_assembly
59+
};

course/code/15/atomic.zig

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
pub fn main() !void {
2+
// #region atomic_value
3+
const std = @import("std");
4+
const RefCount = struct {
5+
count: std.atomic.Value(usize),
6+
dropFn: *const fn (*RefCount) void,
7+
8+
const RefCount = @This();
9+
10+
fn ref(rc: *RefCount) void {
11+
// no synchronization necessary; just updating a counter.
12+
_ = rc.count.fetchAdd(1, .monotonic);
13+
}
14+
15+
fn unref(rc: *RefCount) void {
16+
// release ensures code before unref() happens-before the
17+
// count is decremented as dropFn could be called by then.
18+
if (rc.count.fetchSub(1, .release) == 1) {
19+
// seeing 1 in the counter means that other unref()s have happened,
20+
// but it doesn't mean that uses before each unref() are visible.
21+
// The load acquires the release-sequence created by previous unref()s
22+
// in order to ensure visibility of uses before dropping.
23+
_ = rc.count.load(.acquire);
24+
(rc.dropFn)(rc);
25+
}
26+
}
27+
28+
fn noop(rc: *RefCount) void {
29+
_ = rc;
30+
}
31+
};
32+
33+
var ref_count: RefCount = .{
34+
.count = std.atomic.Value(usize).init(0),
35+
.dropFn = RefCount.noop,
36+
};
37+
ref_count.ref();
38+
ref_count.unref();
39+
// #endregion atomic_value
40+
41+
}
42+
43+
test "spinLoopHint" {
44+
const std = @import("std");
45+
// #region spinLoopHint
46+
for (0..10) |_| {
47+
std.atomic.spinLoopHint();
48+
}
49+
// #endregion spinLoopHint
50+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
该文件夹是构建系统的示例文件!
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
// 标准构建目标
5+
const target = b.standardTargetOptions(.{});
6+
7+
// 标准构建模式
8+
const optimize = b.standardOptimizeOption(.{});
9+
10+
// 添加一个二进制可执行程序构建
11+
const exe = b.addExecutable(.{
12+
.name = "zig",
13+
.root_module = b.addModule("zig", .{
14+
.root_source_file = b.path("src/main.zig"),
15+
.target = target,
16+
.optimize = optimize,
17+
}),
18+
});
19+
20+
// 添加到顶级 install step 中作为依赖
21+
b.installArtifact(exe);
22+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.{
2+
// This is the default name used by packages depending on this one. For
3+
// example, when a user runs `zig fetch --save <url>`, this field is used
4+
// as the key in the `dependencies` table. Although the user can choose a
5+
// different name, most users will stick with this provided value.
6+
//
7+
// It is redundant to include "zig" in this name because it is already
8+
// within the Zig package namespace.
9+
.name = .basic,
10+
11+
// This is a [Semantic Version](https://semver.org/).
12+
// In a future version of Zig it will be used for package deduplication.
13+
.version = "0.0.0",
14+
.fingerprint = 0x907975534fe79435,
15+
16+
// This field is optional.
17+
// This is currently advisory only; Zig does not yet do anything
18+
// with this value.
19+
//.minimum_zig_version = "0.11.0",
20+
21+
// This field is optional.
22+
// Each dependency must either provide a `url` and `hash`, or a `path`.
23+
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
24+
// Once all dependencies are fetched, `zig build` no longer requires
25+
// internet connectivity.
26+
.dependencies = .{
27+
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
28+
//.example = .{
29+
// // When updating this field to a new URL, be sure to delete the corresponding
30+
// // `hash`, otherwise you are communicating that you expect to find the old hash at
31+
// // the new URL.
32+
// .url = "https://example.com/foo.tar.gz",
33+
//
34+
// // This is computed from the file contents of the directory of files that is
35+
// // obtained after fetching `url` and applying the inclusion rules given by
36+
// // `paths`.
37+
// //
38+
// // This field is the source of truth; packages do not come from a `url`; they
39+
// // come from a `hash`. `url` is just one of many possible mirrors for how to
40+
// // obtain a package matching this `hash`.
41+
// //
42+
// // Uses the [multihash](https://multiformats.io/multihash/) format.
43+
// .hash = "...",
44+
//
45+
// // When this is provided, the package is found in a directory relative to the
46+
// // build root. In this case the package's hash is irrelevant and therefore not
47+
// // computed. This field and `url` are mutually exclusive.
48+
// .path = "foo",
49+
50+
// // When this is set to `true`, a package is declared to be lazily
51+
// // fetched. This makes the dependency only get fetched if it is
52+
// // actually used.
53+
// .lazy = false,
54+
//},
55+
},
56+
57+
// Specifies the set of files and directories that are included in this package.
58+
// Only files and directories listed here are included in the `hash` that
59+
// is computed for this package. Only files listed here will remain on disk
60+
// when using the zig package manager. As a rule of thumb, one should list
61+
// files required for compilation plus any license(s).
62+
// Paths are relative to the build root. Use the empty string (`""`) to refer to
63+
// the build root itself.
64+
// A directory listed here means that all files within, recursively, are included.
65+
.paths = .{
66+
"build.zig",
67+
"build.zig.zon",
68+
"src",
69+
// For example...
70+
//"LICENSE",
71+
//"README.md",
72+
},
73+
}

0 commit comments

Comments
 (0)