// issue-0030: Feature — support `extern` global declarations so a global // declared in one sx source file can be referenced from another without // parameter threading. // // ── Use case from the Metal port ────────────────────────────────────────── // // // game/main.sx // g_metal_gpu : *MetalGPU = null; // // // game/chess/pieces.sx // extern g_metal_gpu : *MetalGPU; // // load :: (self: *ChessPieces, path: [:0]u8) { // ... // inline if OS == .ios { // tex := g_metal_gpu.create_texture(w, h, .rgba8, xx pixels); // } else { // // GL path // } // } // // Today, pieces.load takes `has_gpu: bool, gpu: GPU` parameters and // game/main.sx threads them through. Cross-file `extern` globals would // let us drop those parameters. // // ── Implementation sketch ───────────────────────────────────────────────── // // Mirror how foreign function declarations work — declared in one file, // defined elsewhere, linker resolves. Globals already have first-class // addresses in the IR; just add an "extern" flag that says "don't emit // storage, emit a reference." // // Files: // - parser (sx surface syntax for `extern G : T;`) // - src/ir/lower.zig (record an extern global stub that resolves at // module-link time) // - src/ir/emit_llvm.zig (emit an `external` LLVM global) // // ── Syntax constraint ───────────────────────────────────────────────────── // // `extern G : T;` is a NEW top-level form. Must not clash with: // - `G :: T;` (type alias) // - `G : T = ---;` (uninitialized global with explicit type) // - `G : T;` (does this currently parse as anything?) // // The parser MUST reject `extern G : T = expr;` — extern cannot have an // initializer (the definition lives elsewhere). // // ── Caveat ──────────────────────────────────────────────────────────────── // // Encourages spaghetti globals. Documentation should steer callers toward // explicit parameter passing where reasonable. Useful for genuine // process-singletons (the active GPU, the active platform, etc.) where // threading them through every call site is more noise than signal. #import "modules/std.sx"; main :: () -> s32 { 0; }