Skip to content

Commit

Permalink
add dot literals
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Nov 24, 2023
1 parent b1322e0 commit 1297481
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 5 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ on:

jobs:
lint:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -28,3 +29,18 @@ jobs:
# if you encounter error, rerun the command below and commit the changes
make lint
git diff --exit-code
test:
timeout-minutes: 10
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
with:
version: master
- name: Run Test
run: ./run-all.sh
6 changes: 6 additions & 0 deletions 01-zig-files-are-struct/src/foo.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
pub var a: usize = 1;

b: usize,

const Self = @This();

pub fn inc(self: *Self) void {
self.b += 1;
}
5 changes: 3 additions & 2 deletions 01-zig-files-are-struct/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ const std = @import("std");
const Foo = @import("foo.zig");

pub fn main() !void {
const foo = Foo{ .b = 100 };
var foo = Foo{ .b = 100 };
std.debug.print("Type of Foo is {any}, foo is {any}\n", .{
@TypeOf(Foo),
@TypeOf(foo),
});

std.debug.print("foo = {any}, Foo.a = {d}, foo.b = {d}\n", .{ foo, Foo.a, foo.b });
foo.inc();
std.debug.print("foo.b = {d}\n", .{foo.b});
}
13 changes: 13 additions & 0 deletions 02-name-convention/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const std = @import("std");

pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "02-name-convertion",
.root_source_file = .{ .path = "src/main.zig" },
.target = .{},
.optimize = .Debug,
});

b.installArtifact(exe);
b.step("run", "Run").dependOn(&b.addRunArtifact(exe).step);
}
29 changes: 29 additions & 0 deletions 02-name-convention/src/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const std = @import("std");

const Rect = struct {
w: usize,
h: usize,

fn init(w: usize, h: usize) Rect {
return .{ .w = w, .h = h };
}

fn getArea(self: Rect) usize {
return self.w * self.h;
}
};

pub fn main() !void {
const rect = Rect.init(1, 2);
std.debug.print("Area of rect is {d}\n", .{rect.getArea()});

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

var list = std.ArrayList(Rect).init(allocator);
defer list.deinit();

try list.append(rect);
std.debug.print("Len of list is {d}\n", .{list.items.len});
}
13 changes: 13 additions & 0 deletions 03-dot-literals/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const std = @import("std");

pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "03-dot-literals",
.root_source_file = .{ .path = "src/main.zig" },
.target = .{},
.optimize = .Debug,
});

b.installArtifact(exe);
b.step("run", "Run").dependOn(&b.addRunArtifact(exe).step);
}
40 changes: 40 additions & 0 deletions 03-dot-literals/src/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const std = @import("std");

const Rect = struct {
w: usize,
h: usize,
};

const Color = enum { Red, Green, Blue };

fn mySquare(x: usize) usize {
return x * x;
}

pub fn main() !void {
const rect: Rect = .{ .w = 1, .h = 2 };
const rect2 = .{ .w = 1, .h = 2 };
std.debug.print("Type of rect is {any}\n", .{@TypeOf(rect)});
std.debug.print("Type of rect2 is {any}\n", .{@TypeOf(rect2)});
// inline for (@typeInfo(@TypeOf(rect)).Struct.fields) |fld| {
// std.debug.print("field name:{s}, field:{any}\n", .{ fld.name, fld });
// }
// inline for (@typeInfo(@TypeOf(rect2)).Struct.fields) |fld| {
// std.debug.print("field name:{s}, field:{any}\n", .{ fld.name, fld });
// }

const c: Color = .Red;
const c2 = .Red;
std.debug.print("Type of c is {any}\n", .{@TypeOf(c)});
std.debug.print("Type of c2 is {any}\n", .{@TypeOf(c2)});

// We can rely on .{ ... } to construct a tuple of tuples
// This can be handy when testing different inputs of functions.
inline for (.{
.{ 1, 1 },
.{ 2, 4 },
.{ 3, 9 },
}) |case| {
try std.testing.expectEqual(mySquare(case.@"0"), case.@"1");
}
}
85 changes: 82 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,104 @@ Each tips is given an example named after it, which could be run with `zig build
Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. `@import` returns the struct type corresponding to the file.

```zig
// foo.zig
// Foo.zig
pub var a: usize = 1;
b: usize,
const Self = @This();
pub fn inc(self: *Self) void {
self.b += 1;
}
// main.zig
const Foo = @import("foo.zig");
const Foo = @import("Foo.zig");
pub fn main() !void {
const foo = Foo{ .b = 100 };
std.debug.print("Type of Foo is {any}, foo is {any}\n", .{
@TypeOf(Foo),
@TypeOf(foo),
});
foo.inc();
std.debug.print("foo.b = {d}\n", .{foo.b});
}
```

This will output

```
```text
Type of Foo is type, foo is foo
foo.b = 101
```

## 02. Naming Convention

> Source: https://www.openmymind.net/Zig-Quirks/
In general:

- Functions are `camelCase`
- Types are `PascalCase`
- Variables are `lowercase_with_underscores`

So we know `file_path` is mostly a variable, and `FilePath` is mostly a type.

One exception to those rules is functions that return types. They are `PascalCase`, eg:

```zig
pub fn ArrayList(comptime T: type) type {
return ArrayListAligned(T, null);
}
```

Normally, file names are `lowercase_with_underscore`. However, files that expose a type directly (like our first example), follow the type naming rule. Thus, the file should be named `Foo.zig`, not `foo.zig`.

## 03. Dot Literals

In Zig `.{ ... }` is everywhere, it can be used to initialize struct/tuple/enum, depending on its context.

```zig
const Rect = struct {
w: usize,
h: usize,
};
const Color = enum { Red, Green, Blue };
fn mySquare(x: usize) usize {
return x * x;
}
pub fn main() !void {
const rect: Rect = .{ .w = 1, .h = 2 };
const rect2 = .{ .w = 1, .h = 2 };
std.debug.print("Type of rect is {any}\n", .{@TypeOf(rect)});
std.debug.print("Type of rect2 is {any}\n", .{@TypeOf(rect2)});
const c: Color = .Red;
const c2 = .Red;
std.debug.print("Type of c is {any}\n", .{@TypeOf(c)});
std.debug.print("Type of c2 is {any}\n", .{@TypeOf(c2)});
// We can use .{ ... } to construct a tuple of tuples
// This can be handy when test different inputs of functions.
inline for (.{
.{ 1, 1 },
.{ 2, 4 },
.{ 3, 9 },
}) |case| {
try std.testing.expectEqual(mySquare(case.@"0"), case.@"1");
}
}
```

This will output

```text
Type of rect is main.Rect
Type of rect2 is struct{comptime w: comptime_int = 1, comptime h: comptime_int = 2}
Type of c is main.Color
Type of c2 is @TypeOf(.enum_literal)
```
9 changes: 9 additions & 0 deletions run-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash


SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

for dir in `find . -maxdepth 1 -type d -not -name '.*'`; do
echo "Run example ${dir}..."
cd "${SCRIPT_DIR}/${dir}" && zig build run
done

0 comments on commit 1297481

Please sign in to comment.