# Dependency Resolution - Visual Flow Diagram ## High-Level Flow ``` ┌─────────────────────────────────────────────────────────────────┐ │ USER INVOKES PARSER │ │ zig build run -- SDL_gpu.h --output=gpu.zig │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 1: PRIMARY PARSING │ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │ │ │ Read Header │───▶│ Scanner │───▶│ Declarations │ │ │ │ SDL_gpu.h │ │ (patterns) │ │ (169 items) │ │ │ └──────────────┘ └──────────────┘ └─────────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 2: DEPENDENCY ANALYSIS │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ DependencyResolver.analyze(decls) │ │ │ └───┬─────────────────────────────────────────────────┬───┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────────────┐ ┌────────────────────┐ │ │ │ collectDefinedTypes│ │collectReferencedTypes│ │ │ │ │ │ │ │ │ SDL_GPUDevice ✓ │ │ SDL_Window ✗ │ │ │ │ SDL_GPUTexture ✓ │ │ SDL_Rect ✗ │ │ │ │ ... (166 more) │ │ SDL_FColor ✗ │ │ │ └────────────────────┘ └────────────────────┘ │ │ │ │ referenced_types - defined_types = missing_types │ │ ↓ │ │ ┌─────────────────────────┐ │ │ │ Missing: 6 unique types│ │ │ └─────────────────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 3: INCLUDE DIRECTIVE PARSING │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ parseIncludes(source) → Extract #include directives │ │ │ └──────────────────┬───────────────────────────────────────┘ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ SDL_stdinc.h SDL_pixels.h SDL_properties.h │ │ │ │ SDL_rect.h SDL_surface.h SDL_video.h │ │ │ └──────────────────────────────────────────────────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 4: TYPE EXTRACTION │ │ │ │ For each missing_type in [SDL_Window, SDL_Rect, ...] │ │ For each header in [SDL_stdinc.h, SDL_pixels.h, ...] │ │ │ │ ┌────────────────────────────────────────────────┐ │ │ │ 1. Read dependency header │ │ │ │ 2. Parse with Scanner │ │ │ │ 3. Search for matching type │ │ │ │ 4. If found: │ │ │ │ - Clone declaration (deep copy) │ │ │ │ - Break (stop searching this type) │ │ │ └────────────────────────────────────────────────┘ │ │ │ │ Results: │ │ ✓ SDL_FColor (from SDL_pixels.h) │ │ ✓ SDL_Rect (from SDL_rect.h) │ │ ✓ SDL_Window (from SDL_video.h) │ │ ✓ SDL_FlipMode (from SDL_surface.h) │ │ ⚠ SDL_PropertiesID (not found - typedef) │ │ ⚠ SDL_GPUShaderFormat (not found - #define) │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 5: DECLARATION COMBINING │ │ │ │ all_decls = dependency_decls + primary_decls │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ DEPENDENCIES (4 items - placed FIRST) │ │ │ │ pub const FColor = extern struct {...} │ │ │ │ pub const FlipMode = enum {...} │ │ │ │ pub const Rect = extern struct {...} │ │ │ │ pub const Window = opaque {}; │ │ │ ├──────────────────────────────────────────────────────────┤ │ │ │ PRIMARY DECLARATIONS (169 items) │ │ │ │ pub const GPUDevice = opaque { │ │ │ │ pub fn claimWindow(device: *GPUDevice, │ │ │ │ window: ?*Window) bool { │ │ │ │ // ✓ Window is defined above! │ │ │ │ } │ │ │ │ }; │ │ │ │ ... (168 more) │ │ │ └──────────────────────────────────────────────────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 6: CODE GENERATION │ │ │ │ CodeGen.generate(all_decls) → Zig source code │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ For each declaration: │ │ │ │ - Strip SDL_ prefix │ │ │ │ - Convert types (SDL_Type * → ?*Type) │ │ │ │ - Generate inline wrappers │ │ │ │ - Group methods in opaque types │ │ │ └──────────────────────────────────────────────────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 7: VALIDATION & FORMATTING │ │ │ │ ┌────────────────┐ ┌────────────────┐ ┌──────────────┐ │ │ │ Parse as Zig │───▶│ Check for │───▶│ Format with │ │ │ │ AST │ │ syntax errors │ │ Zig renderer │ │ │ └────────────────┘ └────────────────┘ └──────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE 8: OUTPUT │ │ │ │ Write to: gpu.zig │ │ │ │ ✅ 1,242 lines generated │ │ ✅ All dependencies included │ │ ✅ Properly formatted │ │ ⚠ Some manual fixes needed (multi-field structs) │ └─────────────────────────────────────────────────────────────────┘ ``` ## Type Extraction Detail ``` Missing Type: "SDL_Window" │ ├─ Try: SDL_stdinc.h │ └─ Parse → 50 declarations │ └─ Search for "SDL_Window" → NOT FOUND │ ├─ Try: SDL_pixels.h │ └─ Parse → 20 declarations │ └─ Search for "SDL_Window" → NOT FOUND │ ├─ Try: SDL_properties.h │ └─ Parse → 15 declarations │ └─ Search for "SDL_Window" → NOT FOUND │ ├─ Try: SDL_rect.h │ └─ Parse → 14 declarations │ └─ Search for "SDL_Window" → NOT FOUND │ ├─ Try: SDL_surface.h │ └─ Parse → 30 declarations │ └─ Search for "SDL_Window" → NOT FOUND │ └─ Try: SDL_video.h └─ Parse → 80 declarations └─ Search for "SDL_Window" → FOUND! ✓ └─ Clone declaration └─ Return to caller ``` ## Type String Normalization ``` Input Type String Processing Steps Output ────────────────────────────────────────────────────────────────────────── "SDL_Window *" → Trim spaces → "SDL_Window" → Remove trailing "*" → Trim again "?*SDL_GPUDevice" → Trim → "SDL_GPUDevice" → Remove "?" → Remove "*" → Trim "*const SDL_Rect" → Trim → "SDL_Rect" → Remove "*" → Remove "const" → Trim "SDL_Buffer *const *" → Trim → "SDL_Buffer" → Remove trailing "*" → Remove trailing "const" → Remove trailing "*" → Trim "[*c]const u8" → Find "[*c]" → "u8" → Extract after "[*c]" → Remove "const" → Trim ``` ## Memory Ownership ``` ┌─────────────────────────────────────────────────────────────────┐ │ MEMORY LIFECYCLE │ └─────────────────────────────────────────────────────────────────┘ PRIMARY PARSING: Scanner.init(allocator, source) │ └─ scanner.scan() │ └─ Returns: []Declaration │ ├─ .name (allocated from scanner's allocator) │ ├─ .fields (allocated from scanner's allocator) │ └─ All strings owned by scanner │ └─ Freed at end of main() with deep free DEPENDENCY RESOLVER: DependencyResolver.init(allocator) │ ├─ referenced_types: StringHashMap(void) │ └─ Keys are OWNED (allocated with dupe()) │ └─ Freed in resolver.deinit() │ ├─ defined_types: StringHashMap(void) │ └─ Keys are BORROWED (pointers into declarations) │ └─ No free needed │ └─ getMissingTypes() returns OWNED array └─ Caller must free array and each string DEPENDENCY EXTRACTION: extractTypeFromHeader(allocator, source, type_name) │ ├─ Temporary Scanner (local scope) │ └─ all_decls freed before return │ └─ Returns: CLONED Declaration ├─ Deep copy of all strings ├─ Owned by caller └─ Freed when dependency_decls is freed COMBINED DECLARATIONS: all_decls = dependency_decls + primary_decls │ ├─ dependency_decls items: OWNED (cloned) │ └─ Freed with freeDeclDeep() at end of scope │ └─ primary_decls items: OWNED (from scanner) └─ Freed with existing cleanup code CODE GENERATION: CodeGen.generate(allocator, all_decls) │ └─ Returns: OWNED string (formatted Zig code) └─ Freed after writing to file ``` ## Error Handling Paths ``` ┌─────────────────────────────────────────────────────────────────┐ │ ERROR SCENARIOS │ └─────────────────────────────────────────────────────────────────┘ FATAL ERRORS (Exit immediately): ┌─────────────────────────────────────────────────────┐ │ • Primary header not found │ │ • Out of memory │ │ • Invalid command line arguments │ │ • Cannot write output file │ └─────────────────────────────────────────────────────┘ ↓ Print error message → Exit with code 1 NON-FATAL ERRORS (Continue with warnings): ┌─────────────────────────────────────────────────────┐ │ • Dependency header not readable │ │ → Skip header, try next one │ │ │ │ • Type not found in any header │ │ → Print warning, continue │ │ │ │ • Struct parsing error (multi-field) │ │ → Generate partial struct, continue │ │ │ │ • Syntax errors in generated code │ │ → Print errors, write file anyway │ └─────────────────────────────────────────────────────┘ ↓ Generate output with partial results ``` ## Performance Characteristics ``` ┌─────────────────────────────────────────────────────────────────┐ │ TIMING BREAKDOWN │ │ (SDL_gpu.h as example) │ └─────────────────────────────────────────────────────────────────┘ Phase 1: Primary Parsing ~50ms └─ Read file (50KB) 5ms └─ Scan/parse (169 decls) 45ms Phase 2: Dependency Analysis ~10ms └─ Collect defined types (169) 5ms └─ Collect referenced types 5ms Phase 3: Include Parsing ~1ms └─ String search (6 includes) 1ms Phase 4: Type Extraction ~300ms └─ For each missing type (6): └─ For each header tried (~3 avg): └─ Read file ~10ms └─ Parse declarations ~30ms └─ Search for type ~10ms Phase 5: Declaration Combining ~1ms └─ Array operations 1ms Phase 6: Code Generation ~50ms └─ String building (1,242 lines) 50ms Phase 7: Validation & Formatting ~100ms └─ Parse as AST 50ms └─ Format with renderer 50ms Phase 8: Output Writing ~10ms └─ Write file (53KB) 10ms ────────────────────────────────────────────── TOTAL: ~520ms Without dependency resolution: ~220ms Overhead from dependencies: ~300ms (acceptable) ``` --- ## Quick Reference: Key Functions | Function | Input | Output | Purpose | |----------|-------|--------|---------| | `Scanner.scan()` | `source: []const u8` | `[]Declaration` | Parse C header into declarations | | `DependencyResolver.analyze()` | `decls: []Declaration` | `void` | Build defined/referenced type sets | | `getMissingTypes()` | `allocator` | `[][]const u8` | Calculate missing = referenced - defined | | `parseIncludes()` | `source: []const u8` | `[][]const u8` | Extract #include directives | | `extractTypeFromHeader()` | `source, type_name` | `?Declaration` | Find and clone specific type | | `extractBaseType()` | `type_str: []const u8` | `[]const u8` | Strip pointer/const decorators | | `isSDLType()` | `type_str: []const u8` | `bool` | Check if SDL type | | `cloneDeclaration()` | `decl: Declaration` | `Declaration` | Deep copy declaration | | `CodeGen.generate()` | `decls: []Declaration` | `[]const u8` | Generate Zig source code | --- This visual guide provides a comprehensive overview of how data flows through the dependency resolution system from start to finish.