treesummaryrefslogcommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/refl.zig63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/refl.zig b/src/refl.zig
new file mode 100644
index 0000000..3dd851f
--- /dev/null
+++ b/src/refl.zig
@@ -0,0 +1,63 @@
+const std = @import("std");
+
+fn A(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;
+
+ inline for (ti.fields, 0..) |field, idx| {
+ names[idx] = field.name;
+ types[idx] = extern 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, @constCast(@ptrCast(@alignCast(def)))).*} else null;
+ attrs[idx] = .{
+ .@"comptime" = field.is_comptime,
+ .@"align" = field.alignment,
+ .default_value_ptr = &default,
+ };
+ }
+ inline for (ti.decls, 0..) |decl, idx| {
+ const default = struct {
+ pub fn call() void {
+ std.debug.print("calling {s}\n", .{decl.name});
+ @call(.auto, @field(T, decl.name), .{});
+ std.debug.print("done calling {s}\n", .{decl.name});
+ }
+ };
+ names[ti.fields.len + idx] = decl.name;
+ types[ti.fields.len + idx] = type;
+ attrs[ti.fields.len + idx] = .{.default_value_ptr = &default};
+ }
+
+ return @Struct(.auto, null, &names, &types, &attrs);
+}
+
+pub fn main() !void {
+ const a = A(struct {
+ i: i32 = 123,
+ j: i32 = 456,
+ pub fn b() void {
+ std.debug.print("B!\n", .{});
+ }
+ pub fn c() void {
+ std.debug.print("C!\n", .{});
+ }
+ }) {};
+ std.debug.print("[{}] {}\n", .{@TypeOf(a), a});
+ a.b.call();
+ a.c.call();
+ std.debug.print("{}\n", .{a.i.get()});
+ std.debug.print("{}\n", .{a.j.get()});
+}
+