treesummaryrefslogcommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig12
-rw-r--r--build.zig.zon2
-rw-r--r--flake.nix4
-rw-r--r--src/refl.zig91
4 files changed, 72 insertions, 37 deletions
diff --git a/build.zig b/build.zig
index 85c7417..dd9ca93 100644
--- a/build.zig
+++ b/build.zig
@@ -12,9 +12,15 @@ pub fn build(b: *std.Build) void {
.optimize = optimize,
}),
});
-
b.installArtifact(exe);
- const exe_tests = b.addTest(.{ .root_module = exe.root_module });
- b.step("test", "Run tests").dependOn(&b.addRunArtifact(exe_tests).step);
+ const exe_run = b.addRunArtifact(exe);
+ const exe_run_step = b.step("run", "Run");
+ exe_run_step.dependOn(&exe_run.step);
+ exe_run.step.dependOn(b.getInstallStep());
+ if (b.args) |args| exe_run.addArgs(args);
+
+ const exe_test = b.addTest(.{ .root_module = exe.root_module });
+ const exe_test_step = b.step("test", "Run tests");
+ exe_test_step.dependOn(&b.addRunArtifact(exe_test).step);
}
diff --git a/build.zig.zon b/build.zig.zon
index 6e3e442..4b8be95 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -1,7 +1,7 @@
.{
.name = .reactive_zig,
.version = "0.0.1",
- .minimum_zig_version = "0.16.0",
+ .minimum_zig_version = "0.17.0",
.paths = .{""},
.fingerprint = 0xde90678bdaa274ed,
}
diff --git a/flake.nix b/flake.nix
index dbb5545..654803e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -12,7 +12,7 @@
}: let
forAllSystems = f:
builtins.mapAttrs
- (system: pkgs: f pkgs zig.packages.${system}.zig_0_15_2)
+ (system: pkgs: f pkgs zig.packages.${system}.zig_0_16_0)
nixpkgs.legacyPackages;
in {
devShells = forAllSystems (pkgs: zig: {
@@ -27,7 +27,7 @@
version = "0.0.0";
src = ./.;
zigReleaseMode = "fast";
- # depsHash = "<replace this with the hash Nix provides in its error message>"
+ depsHash = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
};
});
};
diff --git a/src/refl.zig b/src/refl.zig
index c26225e..5cfcc52 100644
--- a/src/refl.zig
+++ b/src/refl.zig
@@ -2,7 +2,7 @@ const std = @import("std");
fn Args(params: []const std.builtin.Type.Fn.Param) type {
var argTypes: [params.len]type = undefined;
-
+
for (params, 0..) |p, i| {
argTypes[i] = p.type.?;
}
@@ -13,34 +13,55 @@ fn Args(params: []const std.builtin.Type.Fn.Param) type {
fn Val(comptime T: type) type {
const ti = @typeInfo(T).@"struct";
- var names: [ti.fields.len + ti.decls.len][]const u8 = undefined;
- var types: [ti.fields.len + ti.decls.len]type = undefined;
- var attrs: [ti.fields.len + ti.decls.len]std.builtin.Type.StructField.Attributes = undefined;
+ const fieldCount = ti.fields.len + ti.decls.len + 1;
+
+ var names: [fieldCount][]const u8 = undefined;
+ var types: [fieldCount]type = undefined;
+ var attrs: [fieldCount]std.builtin.Type.StructField.Attributes = undefined;
inline for (ti.fields, 0..) |field, idx| {
- names[idx] = field.name;
- types[idx] = struct {
- value: field.type,
- pub fn get(self: @This()) field.type {
- std.debug.print("getting {s}\n", .{field.name});
- return self.value;
- }
- pub fn set(self: *@This(), value: field.type) void {
- std.debug.print("setting {s}\n", .{field.name});
- self.value = value;
- }
- };
- const default = if (field.default_value_ptr) |def| types[idx]{ .value = @as(*field.type, @ptrCast(@alignCast(@constCast(def)))).* } else null;
- attrs[idx] = .{
- .@"comptime" = field.is_comptime,
- .@"align" = field.alignment,
- .default_value_ptr = &default,
- };
+ if (field.is_comptime)
+ @compileError("implement skipping comptime fields");
+
+ const fi = @typeInfo(field.type);
+ switch (fi) {
+ .@"struct" => {
+ names[idx] = field.name;
+ const NT = Val(field.type);
+ types[idx] = NT;
+ attrs[idx] = .{
+ .default_value_ptr = &NT{},
+ };
+ },
+ else => {
+ names[idx] = field.name;
+ const NT = struct {
+ pub fn get(self: *@This()) field.type {
+ std.debug.print("getting {s}\n", .{field.name});
+ const parent = self.valuePtr();
+ return @field(parent.value, field.name);
+ }
+ pub fn set(self: *@This(), value: field.type) void {
+ std.debug.print("setting {s}\n", .{field.name});
+ const parent = self.valuePtr();
+ @field(parent.value, field.name) = value;
+ }
+ fn valuePtr(self: *@This()) *align(@alignOf(@This())) Val(T) {
+ const parent: *align(@alignOf(@This())) Val(T) = @fieldParentPtr(field.name, self);
+ return parent;
+ }
+ };
+ types[idx] = NT;
+ attrs[idx] = .{
+ .default_value_ptr = &NT{},
+ };
+ },
+ }
}
inline for (ti.decls, 0..) |decl, idx| {
names[ti.fields.len + idx] = decl.name;
const fi = @typeInfo(@TypeOf(@field(T, decl.name))).@"fn";
-
+
const NT = struct {
pub fn call(self: @This(), args: Args(fi.params)) (fi.return_type orelse void) {
_ = self;
@@ -50,9 +71,15 @@ fn Val(comptime T: type) type {
}
};
types[ti.fields.len + idx] = NT;
- const default = NT {};
- attrs[ti.fields.len + idx] = .{ .default_value_ptr = &default };
+ attrs[ti.fields.len + idx] = .{ .default_value_ptr = &NT{} };
}
+ names[fieldCount - 1] = "value";
+ types[fieldCount - 1] = T;
+ attrs[fieldCount - 1] = .{
+ .@"comptime" = false,
+ .@"align" = @alignOf(T),
+ .default_value_ptr = &T{},
+ };
return @Struct(.auto, null, &names, &types, &attrs);
}
@@ -61,9 +88,9 @@ pub fn main() !void {
var a = Val(struct {
i: i32 = 123,
j: i32 = 456,
- s: Val(struct {
+ s: struct {
i: i32 = 789,
- }) = .{},
+ } = .{},
pub fn b() void {
std.debug.print("B!\n", .{});
}
@@ -75,11 +102,13 @@ pub fn main() !void {
std.debug.print("D! ({})\n", .{self});
}
}){};
- std.debug.print("[{}] {}\n", .{ @TypeOf(a), a });
- a.b.call(.{});
- a.c.call(.{a});
- a.c.call(.{a, 5});
+ std.debug.print("[{}] {}\n{}\n", .{ @TypeOf(a), a, a.value });
+ // a.b.call(.{});
+ // a.c.call(.{a});
+ // a.c.call(.{a, 5});
std.debug.print("{}\n", .{a.i.get()});
+ std.debug.print("{}\n", .{a.j.get()});
a.j.set(9);
std.debug.print("{}\n", .{a.j.get()});
+ std.debug.print("{}\n", .{a.s.i.get()});
}