dev/sdl3-parser #1
|
|
@ -376,8 +376,8 @@ pub const Scanner = struct {
|
||||||
const trimmed = std.mem.trim(u8, line, " \t\r");
|
const trimmed = std.mem.trim(u8, line, " \t\r");
|
||||||
if (trimmed.len == 0) continue;
|
if (trimmed.len == 0) continue;
|
||||||
|
|
||||||
// Track multi-line comments
|
// Track multi-line comments (both /** and /* styles)
|
||||||
if (std.mem.indexOf(u8, trimmed, "/**")) |_| {
|
if (std.mem.indexOf(u8, trimmed, "/*")) |_| {
|
||||||
in_multiline_comment = true;
|
in_multiline_comment = true;
|
||||||
}
|
}
|
||||||
if (in_multiline_comment) {
|
if (in_multiline_comment) {
|
||||||
|
|
@ -389,7 +389,6 @@ pub const Scanner = struct {
|
||||||
|
|
||||||
// Skip various comment/bracket/preprocessor lines
|
// Skip various comment/bracket/preprocessor lines
|
||||||
if (std.mem.startsWith(u8, trimmed, "//")) continue;
|
if (std.mem.startsWith(u8, trimmed, "//")) continue;
|
||||||
if (std.mem.startsWith(u8, trimmed, "/*")) continue;
|
|
||||||
if (std.mem.startsWith(u8, trimmed, "*")) continue; // Lines inside comments
|
if (std.mem.startsWith(u8, trimmed, "*")) continue; // Lines inside comments
|
||||||
if (std.mem.startsWith(u8, trimmed, "#")) continue; // Preprocessor directives
|
if (std.mem.startsWith(u8, trimmed, "#")) continue; // Preprocessor directives
|
||||||
if (std.mem.startsWith(u8, trimmed, "{")) continue;
|
if (std.mem.startsWith(u8, trimmed, "{")) continue;
|
||||||
|
|
@ -581,10 +580,54 @@ pub const Scanner = struct {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse "type name" - handle pointer types correctly
|
// Parse "type name" or "type name[size]" - handle pointer types and arrays correctly
|
||||||
// Examples:
|
// Examples:
|
||||||
// "SDL_GPUTransferBuffer *transfer_buffer" -> type:"SDL_GPUTransferBuffer *" name:"transfer_buffer"
|
// "SDL_GPUTransferBuffer *transfer_buffer" -> type:"SDL_GPUTransferBuffer *" name:"transfer_buffer"
|
||||||
// "Uint32 offset" -> type:"Uint32" name:"offset"
|
// "Uint32 offset" -> type:"Uint32" name:"offset"
|
||||||
|
// "Uint8 padding[2]" -> type:"Uint8[2]" name:"padding"
|
||||||
|
|
||||||
|
// Check if this is an array field (has brackets)
|
||||||
|
if (std.mem.indexOf(u8, field_trimmed, "[")) |bracket_pos| {
|
||||||
|
// Extract array size and append to type
|
||||||
|
// Pattern: "Uint8 padding[2]" -> parse as type="Uint8[2]" name="padding"
|
||||||
|
const before_bracket = std.mem.trimRight(u8, field_trimmed[0..bracket_pos], " \t");
|
||||||
|
const bracket_part = field_trimmed[bracket_pos..]; // "[2]"
|
||||||
|
|
||||||
|
// Split before_bracket into type and name
|
||||||
|
var tokens = std.mem.tokenizeScalar(u8, before_bracket, ' ');
|
||||||
|
var parts_list: [8][]const u8 = undefined;
|
||||||
|
var parts_count: usize = 0;
|
||||||
|
while (tokens.next()) |token| {
|
||||||
|
if (token.len > 0 and !std.mem.eql(u8, token, "const")) {
|
||||||
|
if (parts_count >= 8) return null;
|
||||||
|
parts_list[parts_count] = token;
|
||||||
|
parts_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts_count < 2) return null; // Need at least type and name
|
||||||
|
|
||||||
|
const name = parts_list[parts_count - 1];
|
||||||
|
const type_parts = parts_list[0..parts_count - 1];
|
||||||
|
|
||||||
|
// Reconstruct type with array notation
|
||||||
|
var type_buf: [128]u8 = undefined;
|
||||||
|
var fbs = std.io.fixedBufferStream(&type_buf);
|
||||||
|
const writer = fbs.writer();
|
||||||
|
for (type_parts, 0..) |part, i| {
|
||||||
|
if (i > 0) writer.writeByte(' ') catch return null;
|
||||||
|
writer.writeAll(part) catch return null;
|
||||||
|
}
|
||||||
|
writer.writeAll(bracket_part) catch return null;
|
||||||
|
|
||||||
|
const type_str = fbs.getWritten();
|
||||||
|
|
||||||
|
return FieldDecl{
|
||||||
|
.name = try self.allocator.dupe(u8, name),
|
||||||
|
.type_name = try self.allocator.dupe(u8, type_str),
|
||||||
|
.comment = comment,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Find last identifier by scanning backwards for alphanumeric/_
|
// Find last identifier by scanning backwards for alphanumeric/_
|
||||||
// The field name is the last contiguous sequence of [a-zA-Z0-9_]
|
// The field name is the last contiguous sequence of [a-zA-Z0-9_]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,19 @@ const Allocator = std.mem.Allocator;
|
||||||
pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 {
|
pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 {
|
||||||
const trimmed = std.mem.trim(u8, c_type, " \t");
|
const trimmed = std.mem.trim(u8, c_type, " \t");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
const array_part = trimmed[bracket_pos..]; // "[2]"
|
||||||
|
|
||||||
|
// Recursively convert the base type
|
||||||
|
const zig_base = try convertType(base_type, allocator);
|
||||||
|
defer allocator.free(zig_base);
|
||||||
|
|
||||||
|
// Return Zig array notation: [size]Type
|
||||||
|
return try std.fmt.allocPrint(allocator, "{s}{s}", .{array_part, zig_base});
|
||||||
|
}
|
||||||
|
|
||||||
// Primitives
|
// Primitives
|
||||||
if (std.mem.eql(u8, trimmed, "void")) return try allocator.dupe(u8, "void");
|
if (std.mem.eql(u8, trimmed, "void")) return try allocator.dupe(u8, "void");
|
||||||
if (std.mem.eql(u8, trimmed, "bool")) return try allocator.dupe(u8, "bool");
|
if (std.mem.eql(u8, trimmed, "bool")) return try allocator.dupe(u8, "bool");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue