treesummaryrefslogcommitdiff
path: root/src/refl.zig
diff options
context:
space:
mode:
authorPatrick2026-05-14 22:11:46 +0000
committerPatrick2026-05-14 22:11:46 +0000
commitde2426d29dcbe32227e0aa42ac6747e77d97a6f6 (patch)
tree95f2289b6003901422772e470acb97cf590652f8 /src/refl.zig
parent0137b78397e7f50ed00d034838ffb969d1592d09 (diff)
downloadreactive-zig-de2426d29dcbe32227e0aa42ac6747e77d97a6f6.tar.gz
reactive-zig-de2426d29dcbe32227e0aa42ac6747e77d97a6f6.zip
update
Diffstat (limited to 'src/refl.zig')
-rw-r--r--src/refl.zig91
1 files changed, 60 insertions, 31 deletions
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()});
}