112 lines
2.9 KiB
Markdown
112 lines
2.9 KiB
Markdown
# SDL3 Parser - Overview
|
|
|
|
## What It Does
|
|
|
|
Automatically generates type-safe Zig bindings and C mock implementations from SDL3 C headers.
|
|
|
|
## How It Works
|
|
|
|
### 1. Lexical Analysis (patterns.zig)
|
|
- Scans C header files for SDL API patterns
|
|
- Extracts 5 declaration types:
|
|
- **Opaque types**: `typedef struct SDL_Type SDL_Type;`
|
|
- **Enums**: `typedef enum { ... } SDL_Type;`
|
|
- **Structs**: `typedef struct { ... } SDL_Type;`
|
|
- **Flags**: Packed bitfields from enums
|
|
- **Functions**: `extern SDL_DECLSPEC RetType SDLCALL SDL_Func(...);`
|
|
|
|
### 2. Type Conversion (types.zig)
|
|
- Maps C types to Zig equivalents:
|
|
- `bool` → `bool`
|
|
- `Uint32` → `u32`
|
|
- `SDL_Type*` → `?*Type` (nullable) or `*Type` (non-null)
|
|
- `void*` → `?*anyopaque`
|
|
- `const char*` → `[*c]const u8`
|
|
|
|
### 3. Naming Convention (naming.zig)
|
|
- Strips `SDL_` prefix
|
|
- Removes first underscore for grouping: `SDL_GPU_Device` → `GPUDevice`
|
|
- Converts to camelCase: `SDL_CreateGPUDevice` → `createGPUDevice`
|
|
|
|
### 4. Code Generation (codegen.zig)
|
|
- **Groups methods**: Functions with matching first parameter go inside opaque type
|
|
- **Generates inline wrappers**: Handle casting between Zig and C types
|
|
- **Formats output**: Uses Zig AST for proper formatting
|
|
|
|
### 5. Mock Generation (mock_codegen.zig)
|
|
- Creates C stub implementations for testing
|
|
- Includes actual SDL headers for type definitions
|
|
- Returns null/0/false for all functions
|
|
|
|
## Example
|
|
|
|
**Input** (SDL_gpu.h):
|
|
```c
|
|
typedef struct SDL_GPUDevice SDL_GPUDevice;
|
|
extern SDL_DECLSPEC SDL_GPUDevice* SDLCALL SDL_CreateGPUDevice(bool debug);
|
|
```
|
|
|
|
**Output Zig** (gpu.zig):
|
|
```zig
|
|
pub const GPUDevice = opaque {};
|
|
|
|
pub inline fn createGPUDevice(debug: bool) ?*GPUDevice {
|
|
return c.SDL_CreateGPUDevice(debug);
|
|
}
|
|
```
|
|
|
|
**Output Mock** (gpu_mock.c):
|
|
```c
|
|
#include <SDL3/SDL_gpu.h>
|
|
|
|
SDL_GPUDevice* SDL_CreateGPUDevice(bool debug) {
|
|
(void)debug;
|
|
return NULL;
|
|
}
|
|
```
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
# Generate bindings only
|
|
zig build run -- SDL_gpu.h --output=gpu.zig
|
|
|
|
# Generate bindings + mocks
|
|
zig build run -- SDL_gpu.h --output=gpu.zig --mocks=gpu_mock.c
|
|
|
|
# Test with SDL_gpu.h
|
|
zig build test-mocks
|
|
```
|
|
|
|
## Architecture
|
|
|
|
```
|
|
C Header → Scanner → AST → Type Mapper → Code Generator → Zig Bindings
|
|
↓
|
|
Mock Generator → C Mocks
|
|
```
|
|
|
|
## Statistics (SDL_gpu.h)
|
|
|
|
- **Input**: 169 declarations
|
|
- **Output**: 1,229 lines of Zig, 577 lines of C mocks
|
|
- **Compilation**: 71KB static library, 94 exported functions
|
|
- **Tests**: 7/7 passing
|
|
|
|
## Key Features
|
|
|
|
✅ Type-safe pointer handling (nullable vs non-null)
|
|
✅ Automatic method grouping in opaque types
|
|
✅ Minimal casting (only where needed)
|
|
✅ AST-based formatting
|
|
✅ C mocks with real SDL headers
|
|
✅ Handles large headers (169+ declarations)
|
|
|
|
## Limitations
|
|
|
|
- No dependency resolution (types from other headers)
|
|
- No `#define` parsing (except simple enums)
|
|
- No function pointer types
|
|
- No union types
|
|
- Requires manual `c.zig` for imports
|