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 xml = @import("xml.zig");
|
||||
const Registry = @import("registry.zig").Registry;
|
||||
const vk_render = @import("render.zig").render;
|
||||
const parseXml = @import("spec-parse.zig").parseXml;
|
||||
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 {
|
||||
if (std.os.argv.len <= 1) {
|
||||
@@ -21,13 +36,10 @@ pub fn main() !void {
|
||||
const spec = try xml.parse(std.heap.page_allocator, source);
|
||||
defer spec.deinit();
|
||||
|
||||
const registry = Registry.fromXml(std.heap.page_allocator, spec.root);
|
||||
defer registry.deinit();
|
||||
// registry.dump();
|
||||
const result = try parseXml(std.heap.page_allocator, spec.root);
|
||||
defer result.deinit();
|
||||
|
||||
const stdout_file = std.io.getStdOut();
|
||||
var stdout = stdout_file.outStream();
|
||||
try vk_render(stdout, registry);
|
||||
dumpRegistry(result.registry);
|
||||
}
|
||||
|
||||
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 {
|
||||
return self.findChildrenByTag(tag).next();
|
||||
}
|
||||
|
||||
pub fn findChildrenByTag(self: *Element, tag: []const u8) FindChildrenByTagIterator {
|
||||
return .{
|
||||
.inner = self.children.iterator(0),
|
||||
.inner = self.elements(),
|
||||
.tag = tag
|
||||
};
|
||||
}
|
||||
|
||||
pub const FindChildrenByTagIterator = struct {
|
||||
pub const ChildElementIterator = struct {
|
||||
inner: ContentList.Iterator,
|
||||
tag: []const u8,
|
||||
|
||||
pub fn next(self: *FindChildrenByTagIterator) ?*Element {
|
||||
pub fn next(self: *ChildElementIterator) ?*Element {
|
||||
while (self.inner.next()) |child| {
|
||||
if (child.* != .Element or !mem.eql(u8, child.*.Element.tag, self.tag)) {
|
||||
if (child.* != .Element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -82,6 +87,23 @@ pub const Element = struct {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user