Backlog/lib/sdl3/parser/parser.zig

111 lines
3.8 KiB
Zig

const std = @import("std");
const patterns = @import("patterns.zig");
const codegen = @import("codegen.zig");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len < 2) {
std.debug.print("Usage: {s} <header-file>\n", .{args[0]});
std.debug.print("Example: {s} ../SDL/include/SDL3/SDL_gpu.h\n", .{args[0]});
return error.MissingArgument;
}
const header_path = args[1];
std.debug.print("SDL3 Header Parser\n", .{});
std.debug.print("==================\n\n", .{});
std.debug.print("Parsing: {s}\n\n", .{header_path});
// Read the header file
const source = try std.fs.cwd().readFileAlloc(allocator, header_path, 10 * 1024 * 1024); // 10MB max
defer allocator.free(source);
// Parse declarations
var scanner = patterns.Scanner.init(allocator, source);
const decls = try scanner.scan();
defer {
for (decls) |decl| {
switch (decl) {
.opaque_type => |opaque_decl| allocator.free(opaque_decl.name),
.enum_decl => |enum_decl| {
allocator.free(enum_decl.name);
for (enum_decl.values) |val| {
allocator.free(val.name);
if (val.value) |v| allocator.free(v);
}
allocator.free(enum_decl.values);
},
.struct_decl => |struct_decl| {
allocator.free(struct_decl.name);
for (struct_decl.fields) |field| {
allocator.free(field.name);
allocator.free(field.type_name);
}
allocator.free(struct_decl.fields);
},
.flag_decl => |flag_decl| {
allocator.free(flag_decl.name);
allocator.free(flag_decl.underlying_type);
for (flag_decl.flags) |flag| {
allocator.free(flag.name);
allocator.free(flag.value);
}
allocator.free(flag_decl.flags);
},
.function_decl => |func| {
allocator.free(func.name);
allocator.free(func.return_type);
for (func.params) |param| {
allocator.free(param.name);
allocator.free(param.type_name);
}
allocator.free(func.params);
},
}
}
allocator.free(decls);
}
std.debug.print("Found {d} declarations\n", .{decls.len});
// Count each type
var opaque_count: usize = 0;
var enum_count: usize = 0;
var struct_count: usize = 0;
var flag_count: usize = 0;
var func_count: usize = 0;
for (decls) |decl| {
switch (decl) {
.opaque_type => opaque_count += 1,
.enum_decl => enum_count += 1,
.struct_decl => struct_count += 1,
.flag_decl => flag_count += 1,
.function_decl => func_count += 1,
}
}
std.debug.print(" - Opaque types: {d}\n", .{opaque_count});
std.debug.print(" - Enums: {d}\n", .{enum_count});
std.debug.print(" - Structs: {d}\n", .{struct_count});
std.debug.print(" - Flags: {d}\n", .{flag_count});
std.debug.print(" - Functions: {d}\n\n", .{func_count});
// Generate Zig code
const output = try codegen.CodeGen.generate(allocator, decls);
defer allocator.free(output);
// Write to stdout
_ = try std.posix.write(std.posix.STDOUT_FILENO, output);
}
test "basic test" {
try std.testing.expect(true);
}