commit 018821fbee627807c5a0f622bf8492679f51547e
parent 32c6bdf44e7a212a683eb19df03a2722d781e723
Author: Christian Ermann <christianermann@gmail.com>
Date: Mon, 2 Mar 2026 20:03:44 -0800
Check for implicit pointer types
Diffstat:
| M | src/main.zig | | | 137 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
1 file changed, 112 insertions(+), 25 deletions(-)
diff --git a/src/main.zig b/src/main.zig
@@ -210,6 +210,17 @@ const ComplexType = union(enum) {
};
}
+ pub fn isPointer(self: ComplexType) bool {
+ return switch (self) {
+ .single => |inner| {
+ return inner.category == .object;
+ },
+ .array => |inner| {
+ return inner.category == .object;
+ },
+ };
+ }
+
pub fn render(self: ComplexType, writer: anytype) !void {
switch (self) {
.single => |single| {
@@ -342,6 +353,14 @@ const Type = union(enum) {
};
}
+ pub fn isPointer(self: Type) bool {
+ return switch (self) {
+ .primitive => false,
+ .complex => |inner| inner.isPointer(),
+ .callback => false,
+ };
+ }
+
pub fn render(self: Type, writer: anytype) !void {
return switch (self) {
.primitive => |inner| inner.render(writer),
@@ -435,7 +454,7 @@ const ParameterType = struct {
optional: bool = false,
default: ?DefaultValue = null,
- fn render(self: ParameterType, writer: anytype) !void {
+ fn renderAsParam(self: ParameterType, writer: anytype) !void {
try writer.writeAll(self.name);
try writer.writeAll(": ");
if (self.optional) {
@@ -449,10 +468,33 @@ const ParameterType = struct {
.immutable => try self.type.renderConst(writer),
.mutable => try self.type.render(writer),
}
+ } else if (self.type.isPointer()) {
+ try writer.writeAll("*");
+ try self.type.render(writer);
} else {
try self.type.render(writer);
}
}
+
+ fn renderAsArg(self: ParameterType, writer: anytype) !void {
+ if (self.pointer) |_| {
+ try writer.writeAll("@ptrCast(");
+ } else if (self.type.isPointer()) {
+ try writer.writeAll("@ptrCast(");
+ }
+ if (self.type.isInt()) {
+ try writer.writeAll("@intCast(");
+ }
+ try writer.writeAll(self.name);
+ if (self.pointer) |_| {
+ try writer.writeAll(")");
+ } else if (self.type.isPointer()) {
+ try writer.writeAll(")");
+ }
+ if (self.type.isInt()) {
+ try writer.writeAll(")");
+ }
+ }
};
const TypeDef = struct {
@@ -630,7 +672,7 @@ const Struct = struct {
for (members) |member| {
try renderDoc(member, writer, indent + 1);
try renderIndent(indent + 1, writer);
- try member.render(writer);
+ try member.renderAsParam(writer);
try writer.writeAll(",\n");
}
}
@@ -653,7 +695,7 @@ const Callback = struct {
if (self.args) |args| {
for (args) |arg| {
try writer.writeAll(" ");
- try arg.render(writer);
+ try arg.renderAsParam(writer);
try writer.writeAll(",\n");
}
}
@@ -669,6 +711,9 @@ const ReturnType = struct {
pointer: ?Pointer = null,
pub fn render(self: ReturnType, writer: anytype) !void {
+ if (self.optional) {
+ try writer.writeAll("?");
+ }
if (self.pointer) |pointer| {
if (!self.type.isArray()) {
try writer.writeAll("*");
@@ -677,6 +722,9 @@ const ReturnType = struct {
.immutable => try self.type.renderConst(writer),
.mutable => try self.type.render(writer),
}
+ } else if (self.type.isPointer()) {
+ try writer.writeAll("*");
+ try self.type.render(writer);
} else {
try self.type.render(writer);
}
@@ -691,18 +739,68 @@ const Function = struct {
callback: ?CallbackType = null,
args: ?[]ParameterType = null,
- pub fn render(self: Function, writer: anytype, indent: u32) !void {
- try renderIndent(indent, writer);
- try writer.writeAll("pub fn ");
- try snakeToCamel(self.name, writer);
- try writer.writeAll("(\n");
+ fn renderArgsZig(
+ self: Function,
+ writer: anytype,
+ object: ?[]const u8,
+ indent: u32
+ ) !void {
+ if (object) |obj| {
+ try renderIndent(indent, writer);
+ try writer.writeAll("self: *");
+ try snakeToPascal(obj, writer);
+ try writer.writeAll(",\n");
+ }
if (self.args) |args| {
for (args) |arg| {
- try renderIndent(indent + 1, writer);
- try arg.render(writer);
+ try renderIndent(indent, writer);
+ try arg.renderAsParam(writer);
try writer.writeAll(",\n");
}
}
+ }
+
+ fn renderArgsC(
+ self: Function,
+ writer: anytype,
+ object: ?[]const u8,
+ indent: u32
+ ) !void {
+ if (object) |_| {
+ try renderIndent(indent, writer);
+ try writer.writeAll("@ptrCast(self),\n");
+ }
+ if (self.args) |args| {
+ for (args) |arg| {
+ if (arg.type.isArray()) {
+ try renderIndent(indent, writer);
+ try writer.writeAll("@intCast(");
+ try writer.writeAll(arg.name);
+ try writer.writeAll(".len),\n");
+ try renderIndent(indent, writer);
+ try writer.writeAll("@ptrCast(");
+ try writer.writeAll(arg.name);
+ try writer.writeAll(".ptr),\n");
+ } else {
+ try renderIndent(indent, writer);
+ try arg.renderAsArg(writer);
+ try writer.writeAll(",\n");
+ }
+ }
+ }
+ }
+
+ pub fn render(
+ self: Function,
+ writer: anytype,
+ object: ?[]const u8,
+ indent: u32,
+ ) !void {
+ try renderIndent(indent, writer);
+ try writer.writeAll("pub fn ");
+ try snakeToCamel(self.name, writer);
+ try writer.writeAll("(\n");
+ try self.renderArgsZig(writer, object, indent + 1);
try renderIndent(indent, writer);
try writer.writeAll(") ");
if (self.returns) |returns| {
@@ -711,8 +809,6 @@ const Function = struct {
try writer.writeAll("void");
}
try writer.writeAll(" {\n");
-
- // return
try renderIndent(indent + 1, writer);
if (self.returns) |returns| {
try writer.writeAll("return ");
@@ -723,18 +819,10 @@ const Function = struct {
try writer.writeAll("@intCast(");
}
}
- // c func
try writer.writeAll("c.wgpu");
try snakeToPascal(self.name, writer);
try writer.writeAll("(\n");
- // c func args
- if (self.args) |args| {
- for (args) |arg| {
- try renderIndent(indent + 1, writer);
- try writer.writeAll(arg.name);
- try writer.writeAll(",\n");
- }
- }
+ try self.renderArgsC(writer, object, indent + 2);
try renderIndent(indent + 1, writer);
if (self.returns) |returns| {
if (returns.pointer) |_| {
@@ -745,7 +833,6 @@ const Function = struct {
}
}
try writer.writeAll(");\n");
-
try renderIndent(indent, writer);
try writer.writeAll("}\n");
}
@@ -763,10 +850,10 @@ const Object = struct {
try renderIndent(indent, writer);
try writer.writeAll("pub const ");
try snakeToPascal(self.name, writer);
- try writer.writeAll(" = extern struct {\n");
+ try writer.writeAll(" = opaque {\n");
try renderIndent(indent, writer);
for (self.methods) |method| {
- try method.render(writer, indent + 1);
+ try method.render(writer, self.name, indent + 1);
try writer.writeAll("\n");
}
try writer.writeAll("};\n");
@@ -901,7 +988,7 @@ pub fn main() !void {
}
try stdout.writeAll("// functions\n");
for (parsed.value.functions) |function| {
- try function.render(stdout, 0);
+ try function.render(stdout, null, 0);
try stdout.writeAll("\n");
}
try stdout.writeAll("// methods\n");