From 1a944a3d9e94118a8ae4253ce2efb6a4be3d8e7c Mon Sep 17 00:00:00 2001 From: Collin Cahill Date: Wed, 4 Dec 2024 23:22:34 -0600 Subject: [PATCH] Initial commit/early Zig lessons --- lang/arrays.zig | 5 +++ lang/assignment.zig | 8 +++++ lang/defer.zig | 19 ++++++++++++ lang/errors.zig | 74 ++++++++++++++++++++++++++++++++++++++++++++ lang/for.zig | 15 +++++++++ lang/functions.zig | 21 +++++++++++++ lang/hello-world.zig | 5 +++ lang/if.zig | 19 ++++++++++++ lang/test_fail.zig | 6 ++++ lang/test_pass.zig | 6 ++++ lang/while.zig | 38 +++++++++++++++++++++++ 11 files changed, 216 insertions(+) create mode 100644 lang/arrays.zig create mode 100644 lang/assignment.zig create mode 100644 lang/defer.zig create mode 100644 lang/errors.zig create mode 100644 lang/for.zig create mode 100644 lang/functions.zig create mode 100644 lang/hello-world.zig create mode 100644 lang/if.zig create mode 100644 lang/test_fail.zig create mode 100644 lang/test_pass.zig create mode 100644 lang/while.zig diff --git a/lang/arrays.zig b/lang/arrays.zig new file mode 100644 index 0000000..ab4708b --- /dev/null +++ b/lang/arrays.zig @@ -0,0 +1,5 @@ +const a = [5]u8{ 'h', 'e', 'l', 'l', 'o' }; +const b = [_]u8{ 'w', 'o', 'r', 'l', 'd' }; + +const array = [_]u8{ 'h', 'e', 'l', 'l', 'o' }; +const length = array.len; // 5 diff --git a/lang/assignment.zig b/lang/assignment.zig new file mode 100644 index 0000000..86dd5a6 --- /dev/null +++ b/lang/assignment.zig @@ -0,0 +1,8 @@ +const constant: i32 = 5; +var variable: u32 = 5000; + +// @as performs an explicit type coercion +const inferred_constant = @as(i32, 5); +var inferred_variable = @as(u32, 5000); + +// > where possible, const values are preferred over var values diff --git a/lang/defer.zig b/lang/defer.zig new file mode 100644 index 0000000..4134d7b --- /dev/null +++ b/lang/defer.zig @@ -0,0 +1,19 @@ +const expect = @import("std").testing.expect; + +test "defer" { + var x: i16 = 5; + { + defer x += 2; + try expect(x == 5); + } + try expect(x == 7); +} + +test "multi defer" { + var x: f32 = 5; + { + defer x += 2; + defer x /= 2; + } + try expect(x == 4.5); +} diff --git a/lang/errors.zig b/lang/errors.zig new file mode 100644 index 0000000..f64a046 --- /dev/null +++ b/lang/errors.zig @@ -0,0 +1,74 @@ +const expect = @import("std").testing.expect; + +const FileOpenError = error{ + AccessDenied, + OutOfMemory, + FileNotFound, +}; + +const AllocationError = error{OutOfMemory}; + +test "coerce error from a subset to a superset" { + const err: FileOpenError = AllocationError.OutOfMemory; + try expect(err == FileOpenError.OutOfMemory); +} + +test "error union" { + const maybe_error: AllocationError!u16 = 10; + const no_error = maybe_error catch 0; + + try expect(@TypeOf(no_error) == u16); + try expect(no_error == 10); +} + +fn failingFunction() error{Oops}!void { + return error.Oops; +} + +test "returning an error" { + failingFunction() catch |err| { + try expect(err == error.Oops); + return; + }; +} + +fn failFn() error{Oops}!i32 { + try failingFunction(); + return 12; +} + +test "try" { + const v = failFn() catch |err| { + try expect(err == error.Oops); + return; + }; + try expect(v == 12); +} + +var problems: u32 = 98; + +fn failFnCounter() error{Oops}!void { + errdefer problems += 1; + try failingFunction(); +} + +test "errdefer" { + failFnCounter() catch |err| { + try expect(err == error.Oops); + try expect(problems == 99); + return; + }; +} + +fn createFile() !void { + return error.AccessDenied; +} + +test "inferred error set" { + const x: error{AccessDenied}!void = createFile(); + _ = x catch {}; +} + +const A = error{ NotDir, PathNotFound }; +const B = error{ OutOfMemory, PathNotFound }; +const C = A || B; diff --git a/lang/for.zig b/lang/for.zig new file mode 100644 index 0000000..e9c2dcd --- /dev/null +++ b/lang/for.zig @@ -0,0 +1,15 @@ +test "for" { + const string = [_]u8{ 'a', 'b', 'c' }; + + for (string, 0..) |character, index| { + _ = character; + _ = index; + } + for (string) |character| { + _ = character; + } + for (string, 0..) |_, index| { + _ = index; + } + for (string) |_| {} +} diff --git a/lang/functions.zig b/lang/functions.zig new file mode 100644 index 0000000..a2d9765 --- /dev/null +++ b/lang/functions.zig @@ -0,0 +1,21 @@ +const expect = @import("std").testing.expect; + +fn addFive(x: u32) u32 { + return x + 5; +} + +fn fibonacci(n: u16) u16 { + if (n == 0 or n == 1) return n; + return fibonacci(n - 1) + fibonacci(n - 2); +} + +test "function" { + const y = addFive(0); + try expect(@TypeOf(y) == u32); + try expect(y == 5); +} + +test "function recursion" { + const x = fibonacci(10); + try expect(x == 55); +} diff --git a/lang/hello-world.zig b/lang/hello-world.zig new file mode 100644 index 0000000..933ff9b --- /dev/null +++ b/lang/hello-world.zig @@ -0,0 +1,5 @@ +const std = @import("std"); + +pub fn main() !void { + std.debug.print("Hello, World!\n", .{}); +} diff --git a/lang/if.zig b/lang/if.zig new file mode 100644 index 0000000..f479afd --- /dev/null +++ b/lang/if.zig @@ -0,0 +1,19 @@ +const expect = @import("std").testing.expect; + +test "if statement" { + const a = true; + var x: u16 = 0; + if (a) { + x += 1; + } else { + x += 2; + } + try expect(x == 1); +} + +test "if statement expression" { + const a = true; + var x: u16 = 0; + x += if (a) 1 else 2; + try expect(x == 1); +} diff --git a/lang/test_fail.zig b/lang/test_fail.zig new file mode 100644 index 0000000..929c207 --- /dev/null +++ b/lang/test_fail.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const expect = std.testing.expect; + +test "always fails" { + try expect(false); +} diff --git a/lang/test_pass.zig b/lang/test_pass.zig new file mode 100644 index 0000000..5697b8e --- /dev/null +++ b/lang/test_pass.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const expect = std.testing.expect; + +test "always succeeds" { + try expect(true); +} diff --git a/lang/while.zig b/lang/while.zig new file mode 100644 index 0000000..d94d64a --- /dev/null +++ b/lang/while.zig @@ -0,0 +1,38 @@ +const expect = @import("std").testing.expect; + +test "while" { + var i: u8 = 2; + while (i < 100) { + i *= 2; + } + try expect(i == 128); +} + +test "while with continue expression" { + var sum: u8 = 0; + var i: u8 = 1; + while (i <= 10) : (i += 1) { + sum += i; + } + try expect(sum == 55); +} + +test "while with continue" { + var sum: u8 = 0; + var i: u8 = 0; + while (i <= 3) : (i += 1) { + if (i == 2) continue; + sum += i; + } + try expect(sum == 4); +} + +test "while with break" { + var sum: u8 = 0; + var i: u8 = 0; + while (i <= 3) : (i += 1) { + if (i == 2) break; + sum += i; + } + try expect(sum == 1); +}