zig-webgpu-gen

git clone git://git.electrosoup.com/zig-webgpu-gen
Log | Files | Refs

commit a09b25f7dd0b6d25c58646c1fcc34146e894bf4c
parent 81ee36dcbae6104b42a145c499c8ec60f1555d8b
Author: Christian Ermann <christianermann@gmail.com>
Date:   Sun,  1 Mar 2026 17:01:42 -0800

Improve struct rendering

Diffstat:
Msrc/main.zig | 137++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 129 insertions(+), 8 deletions(-)

diff --git a/src/main.zig b/src/main.zig @@ -90,9 +90,25 @@ const PrimitiveType = enum { @"array<float32>", @"array<float64>", + pub fn isArray(self: PrimitiveType) bool { + return switch (self) { + .@"array<bool>" => true, + .@"array<string>" => true, + .@"array<uint16>" => true, + .@"array<uint32>" => true, + .@"array<uint64>" => true, + .@"array<usize>" => true, + .@"array<int16>" => true, + .@"array<int32>" => true, + .@"array<float32>" => true, + .@"array<float64>" => true, + else => false, + }; + } + fn toString(self: PrimitiveType) []const u8 { return switch (self) { - .c_void => "c_void", + .c_void => "anyopaque", .bool => "bool", .nullable_string => "?[]const u8", .string_with_default_empty => "[]const u8", @@ -120,9 +136,34 @@ const PrimitiveType = enum { }; } + fn toStringConst(self: PrimitiveType) ![]const u8 { + return switch (self) { + .@"array<bool>" => "[]const bool", + .@"array<string>" => "[]const []const u8", + .@"array<uint16>" => "[]const u16", + .@"array<uint32>" => "[]const u32", + .@"array<uint64>" => "[]const u64", + .@"array<usize>" => "[]const usize", + .@"array<int16>" => "[]const i16", + .@"array<int32>" => "[]const i32", + .@"array<float32>" => "[]const f32", + .@"array<float64>" => "[]const f64", + else => error.Unimplemented, + }; + } + pub fn render(self: PrimitiveType, writer: anytype) !void { try writer.writeAll(self.toString()); } + + pub fn renderConst(self: PrimitiveType, writer: anytype) !void { + if (self.isArray()) { + try writer.writeAll(try self.toStringConst()); + } else { + try writer.writeAll("const "); + try writer.writeAll(self.toString()); + } + } }; const ComplexType = union(enum) { @@ -143,6 +184,13 @@ const ComplexType = union(enum) { name: []const u8, }; + pub fn isArray(self: ComplexType) bool { + return switch (self) { + .single => false, + .array => true, + }; + } + pub fn render(self: ComplexType, writer: anytype) !void { switch (self) { .single => |single| { @@ -155,6 +203,19 @@ const ComplexType = union(enum) { } } + pub fn renderConst(self: ComplexType, writer: anytype) !void { + switch (self) { + .single => |single| { + try writer.writeAll("const "); + try snakeToPascal(single.name, writer); + }, + .array => |array| { + try writer.writeAll("[]const "); + try snakeToPascal(array.name, writer); + }, + } + } + pub fn parse(raw: []const u8) ?ComplexType { var array = false; var type_str = raw; @@ -246,6 +307,14 @@ const Type = union(enum) { complex: ComplexType, callback: CallbackType, + pub fn isArray(self: Type) bool { + return switch (self) { + .primitive => |inner| inner.isArray(), + .complex => |inner| inner.isArray(), + .callback => false, + }; + } + pub fn render(self: Type, writer: anytype) !void { return switch (self) { .primitive => |inner| inner.render(writer), @@ -254,6 +323,14 @@ const Type = union(enum) { }; } + pub fn renderConst(self: Type, writer: anytype) !void { + return switch (self) { + .primitive => |inner| inner.renderConst(writer), + .complex => |inner| inner.renderConst(writer), + .callback => error.Unimplemented, + }; + } + pub fn jsonParse( allocator: std.mem.Allocator, source: anytype, @@ -328,12 +405,26 @@ const ParameterType = struct { type: Type, passed_with_ownership: ?bool = null, pointer: ?Pointer = null, - optional: ?bool = null, + optional: bool = false, default: ?DefaultValue = null, fn render(self: ParameterType, writer: anytype) !void { - try writer.print("{s}: ", .{ self.name }); - try self.type.render(writer); + try writer.writeAll(self.name); + try writer.writeAll(": "); + if (self.optional) { + try writer.writeAll("?"); + } + if (self.pointer) |pointer| { + if (!self.type.isArray()) { + try writer.writeAll("*"); + } + switch (pointer) { + .immutable => try self.type.renderConst(writer), + .mutable => try self.type.render(writer), + } + } else { + try self.type.render(writer); + } } }; @@ -465,26 +556,56 @@ const BitFlagEntry = struct { value_combination: ?[][]const u8 = null, }; +const StructType = enum { + extensible, + extensible_callback_arg, + extension, + standalone, +}; + const Struct = struct { name: []const u8, namespace: ?[]const u8 = null, doc: []const u8, - type: []const u8, + type: StructType, extends: ?[][]const u8 = null, free_members: ?bool = null, members: ?[]ParameterType = null, - fn render(self: Struct, writer: anytype) !void { + fn render(self: Struct, writer: anytype, indent: u32) !void { + try renderDoc(self, writer, indent); + try renderIndent(indent, writer); try writer.writeAll("pub const "); try snakeToPascal(self.name, writer); try writer.writeAll(" = extern struct {\n"); + switch (self.type) { + .extensible, .extensible_callback_arg => { + try renderIndent(indent + 1, writer); + try writer.writeAll("next: ?*const ChainedStruct = null,\n"); + }, + .extension => { + try renderIndent(indent + 1, writer); + try writer.writeAll("chain: ChainedStruct = .{\n"); + try renderIndent(indent + 2, writer); + try writer.writeAll(".next = null,\n"); + try renderIndent(indent + 2, writer); + try writer.writeAll(".struct_type = ."); + try toLowercase(self.name, writer); + try writer.writeAll(",\n"); + try renderIndent(indent + 1, writer); + try writer.writeAll("},\n"); + }, + .standalone => {}, + } if (self.members) |members| { for (members) |member| { - try writer.writeAll(" "); + try renderDoc(member, writer, indent + 1); + try renderIndent(indent + 1, writer); try member.render(writer); try writer.writeAll(",\n"); } } + try renderIndent(indent, writer); try writer.writeAll("};\n"); } }; @@ -659,7 +780,7 @@ pub fn main() !void { } try stdout.writeAll("// structs\n"); for (parsed.value.structs) |obj| { - try obj.render(stdout); + try obj.render(stdout, 0); try stdout.writeAll("\n"); } try stdout.writeAll("// callbacks\n");