dev/sdl3-parser #1

Open
peterino wants to merge 51 commits from dev/sdl3-parser into dev/variant-engine
3 changed files with 845 additions and 0 deletions
Showing only changes of commit 00b6b73889 - Show all commits

View File

@ -655,6 +655,7 @@ pub const Scanner = struct {
fn parseStructField(self: *Scanner, line: []const u8) !?FieldDecl {
const trimmed = std.mem.trim(u8, line, " \t\r");
std.debug.print("DEBUG parseStructField: trimmed='{s}'\n", .{trimmed});
if (trimmed.len == 0) return null;
if (std.mem.startsWith(u8, trimmed, "//")) return null;
if (std.mem.startsWith(u8, trimmed, "/*")) return null;
@ -677,6 +678,40 @@ pub const Scanner = struct {
}
}
std.debug.print("DEBUG parseStructField: field_part='{s}'\n", .{field_part});
// Check for function pointer field: RetType (SDLCALL *field_name)(params)
if (std.mem.indexOf(u8, field_part, "(SDLCALL *")) |sdlcall_pos| {
std.debug.print("DEBUG: Found SDLCALL function pointer in: {s}\n", .{field_part});
// Find the * after SDLCALL
const after_sdlcall = field_part[sdlcall_pos + 10..]; // Skip "(SDLCALL *"
std.debug.print("DEBUG: after_sdlcall: {s}\n", .{after_sdlcall});
if (std.mem.indexOf(u8, after_sdlcall, ")")) |close_paren| {
const field_name = std.mem.trim(u8, after_sdlcall[0..close_paren], " \t");
std.debug.print("DEBUG: field_name extracted: {s}\n", .{field_name});
// The entire thing is the type (we'll convert to Zig function pointer syntax later)
return FieldDecl{
.name = try self.allocator.dupe(u8, field_name),
.type_name = try self.allocator.dupe(u8, std.mem.trim(u8, field_part, " \t")),
.comment = comment,
};
}
} else if (std.mem.indexOf(u8, field_part, "(*")) |star_pos| {
// Handle non-SDLCALL function pointers: RetType (*field_name)(params)
const after_star = field_part[star_pos + 2..]; // Skip "(*"
if (std.mem.indexOf(u8, after_star, ")")) |close_paren| {
const field_name = std.mem.trim(u8, after_star[0..close_paren], " \t");
// The entire thing is the type (we'll convert to Zig function pointer syntax later)
return FieldDecl{
.name = try self.allocator.dupe(u8, field_name),
.type_name = try self.allocator.dupe(u8, std.mem.trim(u8, field_part, " \t")),
.comment = comment,
};
}
}
// Check if this line contains multiple comma-separated fields (e.g., "int x, y;")
// Only split on commas that are not inside nested structures (ignore for now)
const field_trimmed = std.mem.trim(u8, field_part, " \t");

View File

@ -6,6 +6,11 @@ const Allocator = std.mem.Allocator;
pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 {
const trimmed = std.mem.trim(u8, c_type, " \t");
// Handle function pointers: RetType (SDLCALL *name)(params) -> *const fn(params) callconv(.C) RetType
if (std.mem.indexOf(u8, trimmed, "(SDLCALL *") orelse std.mem.indexOf(u8, trimmed, "(*")) |star_pos| {
return try convertFunctionPointerType(trimmed, allocator);
}
// Handle array types: "Uint8[2]" -> "[2]u8"
if (std.mem.indexOf(u8, trimmed, "[")) |bracket_pos| {
const base_type = std.mem.trim(u8, trimmed[0..bracket_pos], " \t");
@ -141,6 +146,77 @@ pub fn getCastType(zig_type: []const u8) CastType {
return .none;
}
/// Convert C function pointer type to Zig function pointer syntax
/// Example: Sint64 (SDLCALL *size)(void *userdata) -> *const fn (?*anyopaque) callconv(.C) i64
fn convertFunctionPointerType(c_type: []const u8, allocator: Allocator) ![]const u8 {
// Pattern: ReturnType (SDLCALL *name)(params) or ReturnType (*name)(params)
// Find the return type (everything before the opening paren)
const open_paren = std.mem.indexOf(u8, c_type, "(") orelse return try allocator.dupe(u8, c_type);
const return_type_str = std.mem.trim(u8, c_type[0..open_paren], " \t");
// Find the parameters (between the last ( and the last ))
const last_open_paren = std.mem.lastIndexOf(u8, c_type, "(") orelse return try allocator.dupe(u8, c_type);
const last_close_paren = std.mem.lastIndexOf(u8, c_type, ")") orelse return try allocator.dupe(u8, c_type);
if (last_close_paren <= last_open_paren) return try allocator.dupe(u8, c_type);
const params_str = std.mem.trim(u8, c_type[last_open_paren + 1 .. last_close_paren], " \t");
// Convert return type
const zig_return = try convertType(return_type_str, allocator);
defer allocator.free(zig_return);
// Convert parameters
var params_list = std.ArrayList([]const u8).init(allocator);
defer {
for (params_list.items) |param| {
allocator.free(param);
}
params_list.deinit();
}
// Parse comma-separated parameters
var param_iter = std.mem.splitScalar(u8, params_str, ',');
while (param_iter.next()) |param| {
const trimmed_param = std.mem.trim(u8, param, " \t");
if (trimmed_param.len == 0) continue;
// Extract just the type (remove parameter name if present)
// Pattern: "void *userdata" -> "void *"
// Pattern: "Sint64 offset" -> "Sint64"
var param_type: []const u8 = trimmed_param;
// Find the last space that separates type from name
if (std.mem.lastIndexOf(u8, trimmed_param, " ")) |space_pos| {
// Check if what comes after is an identifier (not a *)
const after_space = trimmed_param[space_pos + 1 ..];
if (after_space.len > 0 and after_space[0] != '*') {
param_type = std.mem.trimRight(u8, trimmed_param[0..space_pos], " \t");
}
}
const zig_param = try convertType(param_type, allocator);
try params_list.append(zig_param);
}
// Build Zig function pointer type
var result = std.ArrayList(u8).init(allocator);
defer result.deinit();
try result.appendSlice("?*const fn (");
for (params_list.items, 0..) |param, i| {
if (i > 0) try result.appendSlice(", ");
try result.appendSlice(param);
}
try result.appendSlice(") callconv(.C) ");
try result.appendSlice(zig_return);
return try result.toOwnedSlice();
}
pub const CastType = enum {
none,
ptr_cast,

734
lib/sdl3/test-iostream.json vendored Normal file
View File

@ -0,0 +1,734 @@
{
"header": "SDL_iostream.h",
"opaque_types": [
{
"name": "SDL_IOStream"
}
],
"typedefs": [],
"function_pointers": [],
"enums": [
{
"name": "SDL_IOStatus",
"values": []
},
{
"name": "SDL_IOWhence",
"values": []
}
],
"structs": [
{
"name": "SDL_IOStreamInterface",
"fields": [
{
"name": "version",
"type": "Uint32"
},
{
"name": "userdata",
"type": "Sint64 (SDLCALL *size)(void *"
},
{
"name": "whence",
"type": "Sint64 (SDLCALL *seek)(void *userdata, Sint64 offset, SDL_IOWhence"
},
{
"name": "status",
"type": "size_t (SDLCALL *read)(void *userdata, void *ptr, size_t size, SDL_IOStatus *"
},
{
"name": "status",
"type": "size_t (SDLCALL *write)(void *userdata, const void *ptr, size_t size, SDL_IOStatus *"
},
{
"name": "status",
"type": "bool (SDLCALL *flush)(void *userdata, SDL_IOStatus *"
},
{
"name": "userdata",
"type": "bool (SDLCALL *close)(void *"
}
]
}
],
"unions": [],
"flags": [],
"functions": [
{
"name": "SDL_IOFromFile",
"return_type": "SDL_IOStream *",
"parameters": [
{
"name": "file",
"type": "const char *"
},
{
"name": "mode",
"type": "const char *"
}
]
},
{
"name": "SDL_IOFromMem",
"return_type": "SDL_IOStream *",
"parameters": [
{
"name": "mem",
"type": "void *"
},
{
"name": "size",
"type": "size_t"
}
]
},
{
"name": "SDL_IOFromConstMem",
"return_type": "SDL_IOStream *",
"parameters": [
{
"name": "mem",
"type": "const void *"
},
{
"name": "size",
"type": "size_t"
}
]
},
{
"name": "SDL_IOFromDynamicMem",
"return_type": "SDL_IOStream *",
"parameters": []
},
{
"name": "SDL_OpenIO",
"return_type": "SDL_IOStream *",
"parameters": [
{
"name": "iface",
"type": "const SDL_IOStreamInterface *"
},
{
"name": "userdata",
"type": "void *"
}
]
},
{
"name": "SDL_CloseIO",
"return_type": "bool",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_GetIOProperties",
"return_type": "SDL_PropertiesID",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_GetIOStatus",
"return_type": "SDL_IOStatus",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_GetIOSize",
"return_type": "Sint64",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_SeekIO",
"return_type": "Sint64",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
},
{
"name": "offset",
"type": "Sint64"
},
{
"name": "whence",
"type": "SDL_IOWhence"
}
]
},
{
"name": "SDL_TellIO",
"return_type": "Sint64",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_ReadIO",
"return_type": "size_t",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
},
{
"name": "ptr",
"type": "void *"
},
{
"name": "size",
"type": "size_t"
}
]
},
{
"name": "SDL_WriteIO",
"return_type": "size_t",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
},
{
"name": "ptr",
"type": "const void *"
},
{
"name": "size",
"type": "size_t"
}
]
},
{
"name": "SDL_IOprintf",
"return_type": "size_t",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
},
{
"name": "fmt",
"type": "const char *"
},
{
"name": "",
"type": "..."
}
]
},
{
"name": "SDL_IOvprintf",
"return_type": "size_t",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
},
{
"name": "fmt",
"type": "const char *"
},
{
"name": "ap",
"type": "va_list"
}
]
},
{
"name": "SDL_FlushIO",
"return_type": "bool",
"parameters": [
{
"name": "context",
"type": "SDL_IOStream *"
}
]
},
{
"name": "SDL_LoadFile_IO",
"return_type": "void *",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "datasize",
"type": "size_t *"
},
{
"name": "closeio",
"type": "bool"
}
]
},
{
"name": "SDL_LoadFile",
"return_type": "void *",
"parameters": [
{
"name": "file",
"type": "const char *"
},
{
"name": "datasize",
"type": "size_t *"
}
]
},
{
"name": "SDL_SaveFile_IO",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "data",
"type": "const void *"
},
{
"name": "datasize",
"type": "size_t"
},
{
"name": "closeio",
"type": "bool"
}
]
},
{
"name": "SDL_SaveFile",
"return_type": "bool",
"parameters": [
{
"name": "file",
"type": "const char *"
},
{
"name": "data",
"type": "const void *"
},
{
"name": "datasize",
"type": "size_t"
}
]
},
{
"name": "SDL_ReadU8",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint8 *"
}
]
},
{
"name": "SDL_ReadS8",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint8 *"
}
]
},
{
"name": "SDL_ReadU16LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint16 *"
}
]
},
{
"name": "SDL_ReadS16LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint16 *"
}
]
},
{
"name": "SDL_ReadU16BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint16 *"
}
]
},
{
"name": "SDL_ReadS16BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint16 *"
}
]
},
{
"name": "SDL_ReadU32LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint32 *"
}
]
},
{
"name": "SDL_ReadS32LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint32 *"
}
]
},
{
"name": "SDL_ReadU32BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint32 *"
}
]
},
{
"name": "SDL_ReadS32BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint32 *"
}
]
},
{
"name": "SDL_ReadU64LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint64 *"
}
]
},
{
"name": "SDL_ReadS64LE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint64 *"
}
]
},
{
"name": "SDL_ReadU64BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint64 *"
}
]
},
{
"name": "SDL_ReadS64BE",
"return_type": "bool",
"parameters": [
{
"name": "src",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint64 *"
}
]
},
{
"name": "SDL_WriteU8",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint8"
}
]
},
{
"name": "SDL_WriteS8",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint8"
}
]
},
{
"name": "SDL_WriteU16LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint16"
}
]
},
{
"name": "SDL_WriteS16LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint16"
}
]
},
{
"name": "SDL_WriteU16BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint16"
}
]
},
{
"name": "SDL_WriteS16BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint16"
}
]
},
{
"name": "SDL_WriteU32LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint32"
}
]
},
{
"name": "SDL_WriteS32LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint32"
}
]
},
{
"name": "SDL_WriteU32BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint32"
}
]
},
{
"name": "SDL_WriteS32BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint32"
}
]
},
{
"name": "SDL_WriteU64LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint64"
}
]
},
{
"name": "SDL_WriteS64LE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint64"
}
]
},
{
"name": "SDL_WriteU64BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Uint64"
}
]
},
{
"name": "SDL_WriteS64BE",
"return_type": "bool",
"parameters": [
{
"name": "dst",
"type": "SDL_IOStream *"
},
{
"name": "value",
"type": "Sint64"
}
]
}
]
}