forked from mirror/vulkan-zig
begin work on new registry: api constants & tags
This commit is contained in:
@@ -1,7 +1,22 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const xml = @import("xml.zig");
|
const xml = @import("xml.zig");
|
||||||
const Registry = @import("registry.zig").Registry;
|
const parseXml = @import("spec-parse.zig").parseXml;
|
||||||
const vk_render = @import("render.zig").render;
|
const registry = @import("registry-new.zig");
|
||||||
|
|
||||||
|
pub fn dumpRegistry(reg: registry.Registry) void {
|
||||||
|
for (reg.tags) |tag| {
|
||||||
|
std.debug.warn("tag: name = {}, author = {}\n", .{tag.name, tag.author});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (reg.api_constants) |api_constant| {
|
||||||
|
std.debug.warn("constant: name = {}, ", .{api_constant.name});
|
||||||
|
switch (api_constant.value) {
|
||||||
|
.expr => |expr| std.debug.warn("expr = {}\n", .{expr}),
|
||||||
|
.alias => |alias| std.debug.warn("alias = {}\n", .{alias}),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
if (std.os.argv.len <= 1) {
|
if (std.os.argv.len <= 1) {
|
||||||
@@ -21,13 +36,10 @@ pub fn main() !void {
|
|||||||
const spec = try xml.parse(std.heap.page_allocator, source);
|
const spec = try xml.parse(std.heap.page_allocator, source);
|
||||||
defer spec.deinit();
|
defer spec.deinit();
|
||||||
|
|
||||||
const registry = Registry.fromXml(std.heap.page_allocator, spec.root);
|
const result = try parseXml(std.heap.page_allocator, spec.root);
|
||||||
defer registry.deinit();
|
defer result.deinit();
|
||||||
// registry.dump();
|
|
||||||
|
|
||||||
const stdout_file = std.io.getStdOut();
|
dumpRegistry(result.registry);
|
||||||
var stdout = stdout_file.outStream();
|
|
||||||
try vk_render(stdout, registry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "main" {
|
test "main" {
|
||||||
|
|||||||
106
generator/registry-new.zig
Normal file
106
generator/registry-new.zig
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
pub const Registry = struct {
|
||||||
|
decls: []Declaration,
|
||||||
|
api_constants: []ApiConstant,
|
||||||
|
tags: []Tag,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Declaration = struct {
|
||||||
|
name: []const u8,
|
||||||
|
decl_type: TypeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ApiConstant = struct {
|
||||||
|
pub const Value = union(enum) {
|
||||||
|
expr: []const u8,
|
||||||
|
alias: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
name: []const u8,
|
||||||
|
value: Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Tag = struct {
|
||||||
|
name: []const u8,
|
||||||
|
author: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TypeInfo = union(enum) {
|
||||||
|
Struct: Container,
|
||||||
|
Union: Container,
|
||||||
|
Enum: Enum,
|
||||||
|
Bitmask: Bitmask,
|
||||||
|
Handle: Handle,
|
||||||
|
FnPtr: Command,
|
||||||
|
Command: Command,
|
||||||
|
Alias: []const u8,
|
||||||
|
Pointer: Pointer,
|
||||||
|
Array: Array,
|
||||||
|
Opaque: void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Container = struct {
|
||||||
|
pub const Field = struct {
|
||||||
|
name: []const u8,
|
||||||
|
field_type: TypeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
fields: []Field,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Enum = struct {
|
||||||
|
pub const Value = union(enum) {
|
||||||
|
bitpos: u5, // 1 << bitpos
|
||||||
|
bitvector: u32, // Combined flags
|
||||||
|
int: i32,
|
||||||
|
alias: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Field = struct {
|
||||||
|
name: []const u8,
|
||||||
|
value: Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
fields: []Field,
|
||||||
|
is_bitmask_bits: bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Bitmask = struct {
|
||||||
|
bits_enum: ?[]const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Handle = struct {
|
||||||
|
is_dispatchable: bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Command = struct {
|
||||||
|
const Param = struct {
|
||||||
|
name: []const u8,
|
||||||
|
param_type: TypeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
params: []Param,
|
||||||
|
return_type: *TypeInfo,
|
||||||
|
success_codes: []const []const u8,
|
||||||
|
error_codes: []const []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Pointer = struct {
|
||||||
|
pub const PointerSize = enum {
|
||||||
|
one,
|
||||||
|
many, // The length is given by some expression
|
||||||
|
zero_terminated
|
||||||
|
};
|
||||||
|
|
||||||
|
is_const: bool,
|
||||||
|
child: *TypeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Array = struct {
|
||||||
|
pub const ArraySize = union(enum) {
|
||||||
|
int: usize,
|
||||||
|
alias: []const u8, // Field size is given by an api constant
|
||||||
|
};
|
||||||
|
|
||||||
|
size: ArraySize,
|
||||||
|
child: *TypeInfo,
|
||||||
|
};
|
||||||
90
generator/spec-parse.zig
Normal file
90
generator/spec-parse.zig
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const registry = @import("registry-new.zig");
|
||||||
|
const xml = @import("xml.zig");
|
||||||
|
const mem = std.mem;
|
||||||
|
const Allocator = mem.Allocator;
|
||||||
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
|
||||||
|
pub const ParseResult = struct {
|
||||||
|
arena: ArenaAllocator,
|
||||||
|
registry: registry.Registry,
|
||||||
|
|
||||||
|
pub fn deinit(self: ParseResult) void {
|
||||||
|
self.arena.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn parseXml(allocator: *Allocator, root: *xml.Element) !ParseResult {
|
||||||
|
var arena = ArenaAllocator.init(allocator);
|
||||||
|
errdefer arena.deinit();
|
||||||
|
|
||||||
|
var reg = registry.Registry{
|
||||||
|
.decls = &[_]registry.Declaration{},
|
||||||
|
.api_constants = &[_]registry.ApiConstant{},
|
||||||
|
.tags = &[_]registry.Tag{},
|
||||||
|
};
|
||||||
|
|
||||||
|
reg.api_constants = try parseApiConstants(&arena.allocator, root);
|
||||||
|
reg.tags = try parseTags(&arena.allocator, root);
|
||||||
|
|
||||||
|
return ParseResult{
|
||||||
|
.arena = arena,
|
||||||
|
.registry = reg,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseApiConstants(allocator: *Allocator, root: *xml.Element) ![]registry.ApiConstant {
|
||||||
|
var enums = blk: {
|
||||||
|
var it = root.elements();
|
||||||
|
while (it.next()) |child| {
|
||||||
|
const name = child.getAttribute("name") orelse continue;
|
||||||
|
if (mem.eql(u8, name, "API Constants")) {
|
||||||
|
break :blk child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.InvalidRegistry;
|
||||||
|
};
|
||||||
|
|
||||||
|
var constants = try allocator.alloc(registry.ApiConstant, enums.children.count());
|
||||||
|
errdefer allocator.free(constants);
|
||||||
|
|
||||||
|
var i: usize = 0;
|
||||||
|
var it = enums.findChildrenByTag("enum");
|
||||||
|
while (it.next()) |constant| {
|
||||||
|
const value = if (constant.getAttribute("value")) |expr|
|
||||||
|
registry.ApiConstant.Value{.expr = expr}
|
||||||
|
else if (constant.getAttribute("alias")) |alias|
|
||||||
|
registry.ApiConstant.Value{.alias = alias}
|
||||||
|
else
|
||||||
|
return error.InvalidRegistry;
|
||||||
|
|
||||||
|
constants[i] = .{
|
||||||
|
.name = constant.getAttribute("name") orelse return error.InvalidRegistry,
|
||||||
|
.value = value,
|
||||||
|
};
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocator.shrink(constants, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseTags(allocator: *Allocator, root: *xml.Element) ![]registry.Tag {
|
||||||
|
var tags_elem = root.findChildByTag("tags") orelse return error.InvalidRegistry;
|
||||||
|
var tags = try allocator.alloc(registry.Tag, tags_elem.children.count());
|
||||||
|
errdefer allocator.free(tags);
|
||||||
|
|
||||||
|
var i: usize = 0;
|
||||||
|
var it = tags_elem.findChildrenByTag("tag");
|
||||||
|
while (it.next()) |tag| {
|
||||||
|
tags[i] = .{
|
||||||
|
.name = tag.getAttribute("name") orelse return error.InvalidRegistry,
|
||||||
|
.author = tag.getAttribute("author") orelse return error.InvalidRegistry,
|
||||||
|
};
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocator.shrink(tags, i);
|
||||||
|
}
|
||||||
@@ -55,24 +55,29 @@ pub const Element = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elements(self: *Element) ChildElementIterator {
|
||||||
|
return .{
|
||||||
|
.inner = self.children.iterator(0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn findChildByTag(self: *Element, tag: []const u8) ?*Element {
|
pub fn findChildByTag(self: *Element, tag: []const u8) ?*Element {
|
||||||
return self.findChildrenByTag(tag).next();
|
return self.findChildrenByTag(tag).next();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn findChildrenByTag(self: *Element, tag: []const u8) FindChildrenByTagIterator {
|
pub fn findChildrenByTag(self: *Element, tag: []const u8) FindChildrenByTagIterator {
|
||||||
return .{
|
return .{
|
||||||
.inner = self.children.iterator(0),
|
.inner = self.elements(),
|
||||||
.tag = tag
|
.tag = tag
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FindChildrenByTagIterator = struct {
|
pub const ChildElementIterator = struct {
|
||||||
inner: ContentList.Iterator,
|
inner: ContentList.Iterator,
|
||||||
tag: []const u8,
|
|
||||||
|
|
||||||
pub fn next(self: *FindChildrenByTagIterator) ?*Element {
|
pub fn next(self: *ChildElementIterator) ?*Element {
|
||||||
while (self.inner.next()) |child| {
|
while (self.inner.next()) |child| {
|
||||||
if (child.* != .Element or !mem.eql(u8, child.*.Element.tag, self.tag)) {
|
if (child.* != .Element) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +87,23 @@ pub const Element = struct {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FindChildrenByTagIterator = struct {
|
||||||
|
inner: ChildElementIterator,
|
||||||
|
tag: []const u8,
|
||||||
|
|
||||||
|
pub fn next(self: *FindChildrenByTagIterator) ?*Element {
|
||||||
|
while (self.inner.next()) |child| {
|
||||||
|
if (!mem.eql(u8, child.tag, self.tag)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const XmlDecl = struct {
|
pub const XmlDecl = struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user