forked from mirror/vulkan-zig
API Version parsing & rendering
This commit is contained in:
@@ -204,7 +204,6 @@ pub fn generate(allocator: *Allocator, xml_reader: var, writer: var) !void {
|
|||||||
defer gen.deinit();
|
defer gen.deinit();
|
||||||
|
|
||||||
gen.removePromotedExtensions();
|
gen.removePromotedExtensions();
|
||||||
|
|
||||||
try gen.resolveDeclarations();
|
try gen.resolveDeclarations();
|
||||||
try gen.render(writer);
|
try gen.render(writer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const ProfilingAllocator = struct {
|
|||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
if (std.os.argv.len <= 1) {
|
if (std.os.argv.len <= 1) {
|
||||||
std.debug.warn("Usage: vulkan-zig-gen <path-to-vk.xml>\n", .{});
|
std.debug.print("Usage: vulkan-zig-gen <path-to-vk.xml>\n", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ pub fn main() !void {
|
|||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
try vkgen.generate(&prof_alloc.allocator, file.reader(), stdout);
|
try vkgen.generate(&prof_alloc.allocator, file.reader(), stdout);
|
||||||
|
|
||||||
std.debug.warn("Total memory usage: {} KiB\n", .{@divTrunc(prof_alloc.max_usage, 1024)});
|
std.debug.print("Total memory usage: {} KiB\n", .{@divTrunc(prof_alloc.max_usage, 1024)});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "main" {
|
test "main" {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub const Alias = struct {
|
|||||||
pub const ApiConstant = struct {
|
pub const ApiConstant = struct {
|
||||||
pub const Value = union(enum) {
|
pub const Value = union(enum) {
|
||||||
expr: []const u8,
|
expr: []const u8,
|
||||||
alias: []const u8, // Alias of another API constant
|
version: [3][]const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub const Token = struct {
|
|||||||
minus,
|
minus,
|
||||||
tilde,
|
tilde,
|
||||||
dot,
|
dot,
|
||||||
|
hash,
|
||||||
lparen,
|
lparen,
|
||||||
rparen,
|
rparen,
|
||||||
lbracket,
|
lbracket,
|
||||||
@@ -38,6 +39,7 @@ pub const Token = struct {
|
|||||||
pub const CTokenizer = struct {
|
pub const CTokenizer = struct {
|
||||||
source: []const u8,
|
source: []const u8,
|
||||||
offset: usize = 0,
|
offset: usize = 0,
|
||||||
|
in_comment: bool = false,
|
||||||
|
|
||||||
fn peek(self: CTokenizer) ?u8 {
|
fn peek(self: CTokenizer) ?u8 {
|
||||||
return if (self.offset < self.source.len) self.source[self.offset] else null;
|
return if (self.offset < self.source.len) self.source[self.offset] else null;
|
||||||
@@ -88,7 +90,6 @@ pub const CTokenizer = struct {
|
|||||||
const start = self.offset;
|
const start = self.offset;
|
||||||
_ = self.consumeNoEof();
|
_ = self.consumeNoEof();
|
||||||
|
|
||||||
// TODO: 123ABC is now legal
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const c = self.peek() orelse break;
|
const c = self.peek() orelse break;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -103,15 +104,29 @@ pub const CTokenizer = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(self: *CTokenizer) !?Token {
|
fn skipws(self: *CTokenizer) void {
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (self.peek() orelse return null) {
|
switch (self.peek() orelse break) {
|
||||||
' ', '\t', '\n', '\r' => _ = self.consumeNoEof(),
|
' ', '\t', '\n', '\r' => _ = self.consumeNoEof(),
|
||||||
else => break,
|
else => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const c = self.peek().?;
|
pub fn next(self: *CTokenizer) !?Token {
|
||||||
|
self.skipws();
|
||||||
|
if (mem.startsWith(u8, self.source[self.offset ..], "//") or self.in_comment) {
|
||||||
|
const end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse {
|
||||||
|
self.offset = self.source.len;
|
||||||
|
self.in_comment = true;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
self.in_comment = false;
|
||||||
|
self.offset = end + 1;
|
||||||
|
}
|
||||||
|
self.skipws();
|
||||||
|
|
||||||
|
const c = self.peek() orelse return null;
|
||||||
var id: Token.Id = undefined;
|
var id: Token.Id = undefined;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'A'...'Z', 'a'...'z', '_' => return self.keyword(),
|
'A'...'Z', 'a'...'z', '_' => return self.keyword(),
|
||||||
@@ -123,6 +138,7 @@ pub const CTokenizer = struct {
|
|||||||
'-' => id = .minus,
|
'-' => id = .minus,
|
||||||
'~' => id = .tilde,
|
'~' => id = .tilde,
|
||||||
'.' => id = .dot,
|
'.' => id = .dot,
|
||||||
|
'#' => id = .hash,
|
||||||
'[' => id = .lbracket,
|
'[' => id = .lbracket,
|
||||||
']' => id = .rbracket,
|
']' => id = .rbracket,
|
||||||
'(' => id = .lparen,
|
'(' => id = .lparen,
|
||||||
@@ -176,20 +192,23 @@ pub const XmlCTokenizer = struct {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var in_comment: bool = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (self.ctok) |*ctok| {
|
if (self.ctok) |*ctok| {
|
||||||
if (try ctok.next()) |tok| {
|
if (try ctok.next()) |tok| {
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
in_comment = ctok.in_comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ctok = null;
|
self.ctok = null;
|
||||||
|
|
||||||
if (self.it.next()) |child| {
|
if (self.it.next()) |child| {
|
||||||
switch (child.*) {
|
switch (child.*) {
|
||||||
.CharData => |cdata| self.ctok = CTokenizer{.source = cdata},
|
.CharData => |cdata| self.ctok = CTokenizer{.source = cdata, .in_comment = in_comment},
|
||||||
.Comment => {},
|
.Comment => {}, // xml comment
|
||||||
.Element => |elem| if (try elemToToken(elem)) |tok| return tok,
|
.Element => |elem| if (!in_comment) if (try elemToToken(elem)) |tok| return tok,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -198,7 +217,7 @@ pub const XmlCTokenizer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nextNoEof(self: *XmlCTokenizer) !Token {
|
fn nextNoEof(self: *XmlCTokenizer) !Token {
|
||||||
return (try self.next()) orelse return error.InvalidSyntax;
|
return (try self.next()) orelse return error.UnexpectedEof;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek(self: *XmlCTokenizer) !?Token {
|
fn peek(self: *XmlCTokenizer) !?Token {
|
||||||
@@ -211,7 +230,7 @@ pub const XmlCTokenizer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn peekNoEof(self: *XmlCTokenizer) !Token {
|
fn peekNoEof(self: *XmlCTokenizer) !Token {
|
||||||
return (try self.peek()) orelse return error.InvalidSyntax;
|
return (try self.peek()) orelse return error.UnexpectedEof;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expect(self: *XmlCTokenizer, id: Token.Id) !Token {
|
fn expect(self: *XmlCTokenizer, id: Token.Id) !Token {
|
||||||
@@ -491,6 +510,36 @@ fn parseArrayDeclarator(xctok: *XmlCTokenizer) !?ArraySize {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parseVersion(xctok: *XmlCTokenizer) ![3][]const u8 {
|
||||||
|
_ = try xctok.expect(.hash);
|
||||||
|
const define = try xctok.expect(.id);
|
||||||
|
if (!mem.eql(u8, define.text, "define")) {
|
||||||
|
return error.InvalidVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = try xctok.expect(.name);
|
||||||
|
const vk_make_version = try xctok.expect(.type_name);
|
||||||
|
if (!mem.eql(u8, vk_make_version.text, "VK_MAKE_VERSION")) {
|
||||||
|
return error.NotVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = try xctok.expect(.lparen);
|
||||||
|
var version: [3][]const u8 = undefined;
|
||||||
|
for (version) |*part, i| {
|
||||||
|
if (i != 0) {
|
||||||
|
_ = try xctok.expect(.comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tok = try xctok.nextNoEof();
|
||||||
|
switch (tok.id) {
|
||||||
|
.id, .int => part.* = tok.text,
|
||||||
|
else => return error.UnexpectedToken,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = try xctok.expect(.rparen);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
fn testTokenizer(tokenizer: var, expected_tokens: []const Token) void {
|
fn testTokenizer(tokenizer: var, expected_tokens: []const Token) void {
|
||||||
for (expected_tokens) |expected| {
|
for (expected_tokens) |expected| {
|
||||||
const tok = (tokenizer.next() catch unreachable).?;
|
const tok = (tokenizer.next() catch unreachable).?;
|
||||||
@@ -503,7 +552,7 @@ fn testTokenizer(tokenizer: var, expected_tokens: []const Token) void {
|
|||||||
|
|
||||||
test "CTokenizer" {
|
test "CTokenizer" {
|
||||||
var ctok = CTokenizer {
|
var ctok = CTokenizer {
|
||||||
.source = "typedef ([const)]** VKAPI_PTR 123,;aaaa"
|
.source = \\typedef ([const)]** VKAPI_PTR 123,;aaaa
|
||||||
};
|
};
|
||||||
|
|
||||||
testTokenizer(
|
testTokenizer(
|
||||||
@@ -529,7 +578,9 @@ test "CTokenizer" {
|
|||||||
test "XmlCTokenizer" {
|
test "XmlCTokenizer" {
|
||||||
const document = try xml.parse(
|
const document = try xml.parse(
|
||||||
testing.allocator,
|
testing.allocator,
|
||||||
"<root>typedef void (VKAPI_PTR *<name>PFN_vkVoidFunction</name>)(void);</root>"
|
\\<root>// comment <name>commented name</name> <type>commented type</type> trailing
|
||||||
|
\\ typedef void (VKAPI_PTR *<name>PFN_vkVoidFunction</name>)(void);
|
||||||
|
\\</root>
|
||||||
);
|
);
|
||||||
defer document.deinit();
|
defer document.deinit();
|
||||||
|
|
||||||
@@ -556,7 +607,11 @@ test "XmlCTokenizer" {
|
|||||||
test "parseTypedef" {
|
test "parseTypedef" {
|
||||||
const document = try xml.parse(
|
const document = try xml.parse(
|
||||||
testing.allocator,
|
testing.allocator,
|
||||||
"<root>typedef const struct <type>Python</type>* pythons[4];</root>"
|
\\<root> // comment <name>commented name</name> trailing
|
||||||
|
\\ typedef const struct <type>Python</type>* pythons[4];
|
||||||
|
\\ // more comments
|
||||||
|
\\</root>
|
||||||
|
\\
|
||||||
);
|
);
|
||||||
defer document.deinit();
|
defer document.deinit();
|
||||||
|
|
||||||
@@ -567,12 +622,9 @@ test "parseTypedef" {
|
|||||||
const decl = try parseTypedef(&arena.allocator, &xctok);
|
const decl = try parseTypedef(&arena.allocator, &xctok);
|
||||||
|
|
||||||
testing.expectEqualSlices(u8, "pythons", decl.name);
|
testing.expectEqualSlices(u8, "pythons", decl.name);
|
||||||
testing.expectEqual(TypeInfo.array, decl.decl_type);
|
const array = decl.decl_type.typedef.array;
|
||||||
testing.expectEqual(ArraySize{.int = 4}, decl.decl_type.array.size);
|
testing.expectEqual(ArraySize{.int = 4}, array.size);
|
||||||
const array_child = decl.decl_type.array.child.*;
|
const ptr = array.child.pointer;
|
||||||
testing.expectEqual(TypeInfo.pointer, array_child);
|
|
||||||
const ptr = array_child.pointer;
|
|
||||||
testing.expectEqual(true, ptr.is_const);
|
testing.expectEqual(true, ptr.is_const);
|
||||||
testing.expectEqual(TypeInfo.alias, ptr.child.*);
|
testing.expectEqualSlices(u8, "Python", ptr.child.name);
|
||||||
testing.expectEqualSlices(u8, "Python", ptr.child.alias);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -462,29 +462,74 @@ fn parseApiConstants(allocator: *Allocator, root: *xml.Element) ![]registry.ApiC
|
|||||||
return error.InvalidRegistry;
|
return error.InvalidRegistry;
|
||||||
};
|
};
|
||||||
|
|
||||||
const constants = try allocator.alloc(registry.ApiConstant, enums.children.count());
|
var types = root.findChildByTag("types") orelse return error.InvalidRegistry;
|
||||||
|
const n_defines = blk: {
|
||||||
|
var n_defines: usize = 0;
|
||||||
|
var it = types.findChildrenByTag("type");
|
||||||
|
while (it.next()) |ty| {
|
||||||
|
if (ty.getAttribute("category")) |category| {
|
||||||
|
if (mem.eql(u8, category, "define")) {
|
||||||
|
n_defines += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break :blk n_defines;
|
||||||
|
};
|
||||||
|
|
||||||
|
const constants = try allocator.alloc(registry.ApiConstant, enums.children.count() + n_defines);
|
||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
var it = enums.findChildrenByTag("enum");
|
var it = enums.findChildrenByTag("enum");
|
||||||
while (it.next()) |constant| {
|
while (it.next()) |constant| {
|
||||||
const value = if (constant.getAttribute("value")) |expr|
|
const expr = if (constant.getAttribute("value")) |expr|
|
||||||
registry.ApiConstant.Value{.expr = expr}
|
expr
|
||||||
else if (constant.getAttribute("alias")) |alias|
|
else if (constant.getAttribute("alias")) |alias|
|
||||||
registry.ApiConstant.Value{.alias = alias}
|
alias
|
||||||
else
|
else
|
||||||
return error.InvalidRegistry;
|
return error.InvalidRegistry;
|
||||||
|
|
||||||
constants[i] = .{
|
constants[i] = .{
|
||||||
.name = constant.getAttribute("name") orelse return error.InvalidRegistry,
|
.name = constant.getAttribute("name") orelse return error.InvalidRegistry,
|
||||||
.value = value,
|
.value = .{.expr = expr},
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i += try parseDefines(types, constants[i..]);
|
||||||
return allocator.shrink(constants, i);
|
return allocator.shrink(constants, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parseDefines(types: *xml.Element, out: []registry.ApiConstant) !usize {
|
||||||
|
var i: usize = 0;
|
||||||
|
var it = types.findChildrenByTag("type");
|
||||||
|
while (it.next()) |ty| {
|
||||||
|
const category = ty.getAttribute("category") orelse continue;
|
||||||
|
if (!mem.eql(u8, category, "define")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = ty.getCharData("name") orelse continue;
|
||||||
|
if (mem.eql(u8, name, "VK_HEADER_VERSION")) {
|
||||||
|
out[i] = .{
|
||||||
|
.name = name,
|
||||||
|
.value = .{.expr = mem.trim(u8, ty.children.at(2).CharData, " ")},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
var xctok = cparse.XmlCTokenizer.init(ty);
|
||||||
|
out[i] = .{
|
||||||
|
.name = name,
|
||||||
|
.value = .{
|
||||||
|
.version = cparse.parseVersion(&xctok) catch continue
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
fn parseTags(allocator: *Allocator, root: *xml.Element) ![]registry.Tag {
|
fn parseTags(allocator: *Allocator, root: *xml.Element) ![]registry.Tag {
|
||||||
var tags_elem = root.findChildByTag("tags") orelse return error.InvalidRegistry;
|
var tags_elem = root.findChildByTag("tags") orelse return error.InvalidRegistry;
|
||||||
const tags = try allocator.alloc(registry.Tag, tags_elem.children.count());
|
const tags = try allocator.alloc(registry.Tag, tags_elem.children.count());
|
||||||
|
|||||||
@@ -25,32 +25,38 @@ const preamble =
|
|||||||
\\ pub fn toInt(self: FlagsType) IntType {
|
\\ pub fn toInt(self: FlagsType) IntType {
|
||||||
\\ return @bitCast(IntType, self);
|
\\ return @bitCast(IntType, self);
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn fromInt(flags: IntType) FlagsType {
|
\\ pub fn fromInt(flags: IntType) FlagsType {
|
||||||
\\ return @bitCast(FlagsType, flags);
|
\\ return @bitCast(FlagsType, flags);
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn merge(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
\\ pub fn merge(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
||||||
\\ return fromInt(toInt(lhs) | toInt(rhs));
|
\\ return fromInt(toInt(lhs) | toInt(rhs));
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn intersect(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
\\ pub fn intersect(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
||||||
\\ return fromInt(toInt(lhs) & toInt(rhs));
|
\\ return fromInt(toInt(lhs) & toInt(rhs));
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn complement(self: FlagsType) FlagsType {
|
\\ pub fn complement(self: FlagsType) FlagsType {
|
||||||
\\ return fromInt(~toInt(lhs));
|
\\ return fromInt(~toInt(lhs));
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn subtract(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
\\ pub fn subtract(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
||||||
\\ return fromInt(toInt(lhs) & toInt(rhs.complement()));
|
\\ return fromInt(toInt(lhs) & toInt(rhs.complement()));
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ pub fn contains(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
\\ pub fn contains(lhs: FlagsType, rhs: FlagsType) FlagsType {
|
||||||
\\ return toInt(merge(lhs, rhs)) == toInt(rhs);
|
\\ return toInt(merge(lhs, rhs)) == toInt(rhs);
|
||||||
\\ }
|
\\ }
|
||||||
\\ };
|
\\ };
|
||||||
\\}
|
\\}
|
||||||
|
\\pub fn makeVersion(major: u10, minor: u10, patch: u12) u32 {
|
||||||
|
\\ return (@as(u32, major) << 22) | (@as(u32, minor) << 12) | patch;
|
||||||
|
\\}
|
||||||
|
\\pub fn versionMajor(version: u32) u10 {
|
||||||
|
\\ return @truncate(u10, version >> 22);
|
||||||
|
\\}
|
||||||
|
\\pub fn versionMinor(version: u32) u10 {
|
||||||
|
\\ return @truncate(u10, version >> 12);
|
||||||
|
\\}
|
||||||
|
\\pub fn versionPatch(version: u32) u12 {
|
||||||
|
\\ return @truncate(u12, version);
|
||||||
|
\\}
|
||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -260,16 +266,27 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
fn renderApiConstant(self: *Self, api_constant: reg.ApiConstant) !void {
|
fn renderApiConstant(self: *Self, api_constant: reg.ApiConstant) !void {
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.writeIdentifier(util.trimVkNamespace(api_constant.name));
|
try self.renderName(api_constant.name);
|
||||||
try self.writer.writeAll(" = ");
|
try self.writer.writeAll(" = ");
|
||||||
|
|
||||||
if (api_constant.value == .alias) {
|
switch (api_constant.value) {
|
||||||
try self.writeIdentifier(util.trimVkNamespace(api_constant.value.alias));
|
.expr => |expr| try self.renderApiConstantExpr(expr),
|
||||||
try self.writer.writeAll(";\n");
|
.version => |version| {
|
||||||
return;
|
try self.writer.writeAll("makeVersion(");
|
||||||
|
for (version) |part, i| {
|
||||||
|
if (i != 0) {
|
||||||
|
try self.writer.writeAll(", ");
|
||||||
|
}
|
||||||
|
try self.renderApiConstantExpr(part);
|
||||||
|
}
|
||||||
|
try self.writer.writeAll(")");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const expr = api_constant.value.expr;
|
try self.writer.writeAll(";\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn renderApiConstantExpr(self: *Self, expr: []const u8) !void {
|
||||||
const adjusted_expr = if (expr.len > 2 and expr[0] == '(' and expr[expr.len - 1] == ')')
|
const adjusted_expr = if (expr.len > 2 and expr[0] == '(' and expr[expr.len - 1] == ')')
|
||||||
expr[1 .. expr.len - 1]
|
expr[1 .. expr.len - 1]
|
||||||
else
|
else
|
||||||
@@ -287,7 +304,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
.id => {
|
.id => {
|
||||||
try self.writeIdentifier(util.trimVkNamespace(api_constant.value.alias));
|
try self.renderName(tok.text);
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
.int => {},
|
.int => {},
|
||||||
@@ -324,20 +341,18 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.writer.writeAll(";\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderTypeInfo(self: *Self, type_info: reg.TypeInfo) RenderTypeInfoError!void {
|
fn renderTypeInfo(self: *Self, type_info: reg.TypeInfo) RenderTypeInfoError!void {
|
||||||
switch (type_info) {
|
switch (type_info) {
|
||||||
.name => |name| try self.renderTypeName(name),
|
.name => |name| try self.renderName(name),
|
||||||
.command_ptr => |command_ptr| try self.renderCommandPtr(command_ptr, true),
|
.command_ptr => |command_ptr| try self.renderCommandPtr(command_ptr, true),
|
||||||
.pointer => |pointer| try self.renderPointer(pointer),
|
.pointer => |pointer| try self.renderPointer(pointer),
|
||||||
.array => |array| try self.renderArray(array),
|
.array => |array| try self.renderArray(array),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderTypeName(self: *Self, name: []const u8) !void {
|
fn renderName(self: *Self, name: []const u8) !void {
|
||||||
if (builtin_types.get(name)) |zig_name| {
|
if (builtin_types.get(name)) |zig_name| {
|
||||||
try self.writer.writeAll(zig_name);
|
try self.writer.writeAll(zig_name);
|
||||||
return;
|
return;
|
||||||
@@ -359,6 +374,10 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
// Function pointer type, render using same name for now
|
// Function pointer type, render using same name for now
|
||||||
try self.writeIdentifier(name);
|
try self.writeIdentifier(name);
|
||||||
return;
|
return;
|
||||||
|
} else if (mem.startsWith(u8, name, "VK_")) {
|
||||||
|
// Constants
|
||||||
|
try self.writeIdentifier(name[3..]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.writeIdentifier(name);
|
try self.writeIdentifier(name);
|
||||||
@@ -423,7 +442,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
try self.writer.writeByte('[');
|
try self.writer.writeByte('[');
|
||||||
switch (array.size) {
|
switch (array.size) {
|
||||||
.int => |size| try self.writer.print("{}", .{size}),
|
.int => |size| try self.writer.print("{}", .{size}),
|
||||||
.alias => |alias| try self.writeIdentifier(util.trimVkNamespace(alias)),
|
.alias => |alias| try self.renderName(alias),
|
||||||
}
|
}
|
||||||
try self.writer.writeByte(']');
|
try self.writer.writeByte(']');
|
||||||
try self.renderTypeInfo(array.child.*);
|
try self.renderTypeInfo(array.child.*);
|
||||||
@@ -445,7 +464,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
fn renderContainer(self: *Self, name: []const u8, container: reg.Container) !void {
|
fn renderContainer(self: *Self, name: []const u8, container: reg.Container) !void {
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = ");
|
try self.writer.writeAll(" = ");
|
||||||
|
|
||||||
for (container.fields) |field| {
|
for (container.fields) |field| {
|
||||||
@@ -503,7 +522,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = extern enum {");
|
try self.writer.writeAll(" = extern enum {");
|
||||||
|
|
||||||
for (enumeration.fields) |field| {
|
for (enumeration.fields) |field| {
|
||||||
@@ -538,7 +557,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
fn renderBitmaskBits(self: *Self, name: []const u8, bits: reg.Enum) !void {
|
fn renderBitmaskBits(self: *Self, name: []const u8, bits: reg.Enum) !void {
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = packed struct {");
|
try self.writer.writeAll(" = packed struct {");
|
||||||
|
|
||||||
if (bits.fields.len == 0) {
|
if (bits.fields.len == 0) {
|
||||||
@@ -566,7 +585,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try self.writer.writeAll("pub usingnamespace FlagsMixin(");
|
try self.writer.writeAll("pub usingnamespace FlagsMixin(");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(");\n};\n");
|
try self.writer.writeAll(");\n};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,13 +595,13 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
// output flags with no associated bits type.
|
// output flags with no associated bits type.
|
||||||
|
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(
|
try self.writer.writeAll(
|
||||||
\\ = packed struct {
|
\\ = packed struct {
|
||||||
\\_reserved_bits: Flags = 0,
|
\\_reserved_bits: Flags = 0,
|
||||||
\\pub usingnamespace FlagsMixin(
|
\\pub usingnamespace FlagsMixin(
|
||||||
);
|
);
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(
|
try self.writer.writeAll(
|
||||||
\\);
|
\\);
|
||||||
\\};
|
\\};
|
||||||
@@ -595,7 +614,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
const backing_type: []const u8 = if (handle.is_dispatchable) "usize" else "u64";
|
const backing_type: []const u8 = if (handle.is_dispatchable) "usize" else "u64";
|
||||||
|
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.print(" = extern enum({}) {{null_handle = 0, _}};\n", .{backing_type});
|
try self.writer.print(" = extern enum({}) {{null_handle = 0, _}};\n", .{backing_type});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,15 +627,15 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = ");
|
try self.writer.writeAll(" = ");
|
||||||
try self.renderTypeName(alias.name);
|
try self.renderName(alias.name);
|
||||||
try self.writer.writeAll(";\n");
|
try self.writer.writeAll(";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderOpaque(self: *Self, name: []const u8) !void {
|
fn renderOpaque(self: *Self, name: []const u8) !void {
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = @Type(.Opaque);\n");
|
try self.writer.writeAll(" = @Type(.Opaque);\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,7 +660,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
fn renderTypedef(self: *Self, name: []const u8, type_info: reg.TypeInfo) !void {
|
fn renderTypedef(self: *Self, name: []const u8, type_info: reg.TypeInfo) !void {
|
||||||
try self.writer.writeAll("const ");
|
try self.writer.writeAll("const ");
|
||||||
try self.renderTypeName(name);
|
try self.renderName(name);
|
||||||
try self.writer.writeAll(" = ");
|
try self.writer.writeAll(" = ");
|
||||||
try self.renderTypeInfo(type_info);
|
try self.renderTypeInfo(type_info);
|
||||||
try self.writer.writeAll(";\n");
|
try self.writer.writeAll(";\n");
|
||||||
@@ -875,6 +894,8 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
if (returns.len == 1) {
|
if (returns.len == 1) {
|
||||||
try self.writer.writeAll("var ");
|
try self.writer.writeAll("var ");
|
||||||
try self.writeIdentifierWithCase(.snake, returns[0].name);
|
try self.writeIdentifierWithCase(.snake, returns[0].name);
|
||||||
|
try self.writer.writeAll(": ");
|
||||||
|
try self.renderTypeInfo(returns[0].return_value_type);
|
||||||
try self.writer.writeAll(" = undefined;\n");
|
try self.writer.writeAll(" = undefined;\n");
|
||||||
} else if (returns.len > 1) {
|
} else if (returns.len > 1) {
|
||||||
try self.writer.writeAll("var return_values: ");
|
try self.writer.writeAll("var return_values: ");
|
||||||
|
|||||||
Reference in New Issue
Block a user