ffi M1.1 (first pass): id / Class / SEL / BOOL type aliases

Adds named stand-ins for the three opaque Obj-C runtime types
and Apple's signed-char boolean to library/modules/std/objc.sx:

  id    :: *void;   // any Obj-C instance pointer
  Class :: *void;   // a class object pointer
  SEL   :: *void;   // a registered selector
  BOOL  :: s8;      // Apple's signed-char boolean (NOT sx's bool)

All resolve to their underlying type at the LLVM layer — no
runtime cost — but make foreign-class declarations read closer
to Objective-C source. The header's old caveat about lacking
type aliases is gone.

141-objc-type-aliases.sx exercises the aliases against the real
macOS Obj-C runtime: alloc/init an NSObject, fetch its class
via objc_getClass, sel_registerName a SEL, then call
'isKindOfClass:' returning BOOL=1. Non-macOS paths print the
same line to keep the snapshot stable.

DEFERRED (M1.1.b, follow-up): 'Class(T)' parameterization with
#extends-aware covariance, and 'instancetype' per-decl
substitution. Both require compiler-level type-check support
beyond plain stdlib aliases.

170 examples pass (+1).
This commit is contained in:
agra
2026-05-25 21:33:20 +03:00
parent 86c1127c46
commit d9dbdad3f5
5 changed files with 127 additions and 13 deletions

View File

@@ -6,7 +6,38 @@ add a test and make it pass — that's two commits).
## Last completed step
**issue-0043 closed — `#foreign` C-variadic tail via `args: ..T`.**
**M1.0 — Expression-bodied function declarations**
(3 commits: `6c95b2a`, `4a048d3`, `86c1127`).
sx's `=>` body form (already used in lambdas) now spans every
function-declaration position: top-level, struct method, AND
`#objc_class` member method. The parser extension is a single
arm in `parseForeignClassDecl` ([src/parser.zig:1262]) that
mirrors the existing `parseFnDecl` arrow handling.
Three commits, FFI cadence:
- `6c95b2a` ffi M1.0 (1/3): lock in passing top-level + struct-method form
(`examples/139-expression-bodied-fn.sx`).
- `4a048d3` ffi M1.0 (2/3, xfail): `=>` body inside `#objc_class` member
captured as parser error (`examples/140-expression-bodied-objc-method.sx`).
- `86c1127` ffi M1.0 (3/3): parser extension, 140 flips green.
169 examples pass (+2 from M1.0). `zig build test` green.
This is the first milestone of the **6-month Obj-C FFI roadmap**
saved at `~/.claude/plans/lets-see-options-for-merry-dijkstra.md`.
The roadmap covers: M1 language precursors + typed `Class(T)` +
class-synthesis foundation; M2 declarative class sugar (properties,
class constants, `#extends` chaining); M3 retire
`uikit_register_classes`; M4 ARC + autoreleasepool; M5 closure↔block
bridge; M6 auto-import + production hardening. Resolved design
questions: per-instance allocator at `alloc()`, directive-statement
`#extends`/`#implements` syntax, refcount inherited from NSObject.
Four design questions still open (see roadmap).
---
**Prior landing — issue-0043 closed: `#foreign` C-variadic tail via `args: ..T`.**
A trailing variadic param on a `#foreign` declaration now maps to the
C calling convention's `...` instead of sx's slice-packing path. Drops
the existing per-arity shim pattern (`__log_2i :: (prio, tag, fmt, a:
@@ -145,14 +176,30 @@ plus 2 codegen fixes surfaced along the way.**
## Current state
- 97/97 regression tests pass (was 86 at start of FFI work; +11 net,
factoring in the `examples/issue-0036.sx``101-ffi-medium-struct.sx`
promotion).
- `tests/cross_compile.sh` runs clean (empty tuple list).
- Chess Android build + iOS-sim build both clean. emit_llvm.zig sret
+ struct↔array changes don't regress either.
- ABI coverage matrix locked in for all four C-ABI aggregate slots
(≤8 B int, 9..16 B int, 16 B HFA, >16 B byval+sret).
- 169/169 example tests pass; `zig build test` green.
- Phase 3.0/3.1/3.2 (Obj-C DSL dispatch + selector mangling +
selector override + uikit.sx C1-C5 cluster migrations) all
landed. M1.0 (expression-bodied functions) just landed.
- Chess on macOS / iOS-sim / Android all build and run.
- Active forward plan: 6-month Obj-C FFI roadmap at
`~/.claude/plans/lets-see-options-for-merry-dijkstra.md`.
## Next step (M1.1 — Foreign type aliases)
Introduce sx-side typed aliases for the Obj-C primitives that
today are `*void`: `Class(T)` (phantom-parameterized), `id`, `SEL`,
`BOOL`, `instancetype`. Per the roadmap, the load-bearing piece
is `Class(T)`: a phantom-typed pointer alias enabling type-safe
factory returns like
`layerClass :: Class(CALayer) = CAEAGLLayer.class();` (the M2.1(a)
class-constant form). Plain `Class``Class(NSObject)` sugar.
`Cls.class()` returns `Class(Cls)`. Covariant on `#extends`.
Files to touch: [src/parser.zig](../src/parser.zig) (parser
support for `Class(T)` type syntax),
[src/ir/lower.zig](../src/ir/lower.zig) (alias resolution +
covariance check). LLVM layer unchanged — these are phantom-typed,
underlying representation stays `*void`.
## Phase 1B complete (1.61.14)