Files
sx/examples/ffi-objc/1335-ffi-objc-call-09-in-construct.sx
agra 66bdc70bf1 test: group examples into per-category folders
Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
2026-06-21 14:41:34 +03:00

81 lines
2.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Phase 1 steps 1.111.13 (PLAN-FFI.md): `#objc_call` call sites
// embedded inside the sx surface constructs. None touch a new ABI
// path — the lowering routes the call identically regardless of
// the enclosing scope, and this test pins that lemma.
//
// 1. Struct method body Probe.fetch
// 2. Protocol impl method body impl Hashable for Probe
// 3. Closure value body closure that calls hash
//
// 1.14 (separate test): `inline if OS == { case }` gating across
// targets — verified by `tests/cross_compile.sh`.
#import "modules/std.sx";
#import "modules/build.sx";
#import "modules/ffi/objc.sx";
// ── 1. Struct method calling #objc_call ─────────────────────────────
Probe :: struct {
receiver: *void = null;
fetch :: (self: *Probe) -> i64 {
#objc_call(i64)(self.receiver, "hash")
}
}
// ── 2. Protocol impl method ────────────────────────────────────────
Hashable :: protocol {
sx_hash :: (self: *Self) -> i64;
}
impl Hashable for Probe {
sx_hash :: (self: *Probe) -> i64 {
#objc_call(i64)(self.receiver, "hash") * 2
}
}
// ── 3. Closure body invoking #objc_call ─────────────────────────────
// The closure captures `recv` from its enclosing function and
// references it inside the `#objc_call` arg list. Locked in by
// `examples/103-ffi-closure-capture.sx`.
make_hasher :: (recv: *void) -> Closure(i32) -> i64 {
closure((dummy: i32) -> i64 => #objc_call(i64)(recv, "hash"))
}
// ── 4. Generic function body — instantiated per call site ───────────
hash_through :: (recv: $T) -> i64 {
p : *void = xx recv;
#objc_call(i64)(p, "hash")
}
main :: () -> i32 {
inline if OS == .macos {
ns_object := objc_getClass("NSObject".ptr);
p : Probe = .{ receiver = ns_object };
// 1. struct method
h1 := p.fetch();
print("fetch != 0 = {}\n", h1 != 0);
// 2. protocol method (doubles the raw hash; mostly checking
// dispatch / arg threading, not the math)
h2 := p.sx_hash();
print("protocol h2 = {}\n", h2 == h1 * 2);
// 3. closure (receives a dummy arg to keep the `Closure(T) -> R`
// arity matching 35-closures.sx; `recv` is captured from
// `make_hasher`'s arg list and used inside the `#objc_call`).
hasher := make_hasher(ns_object);
h3 := hasher(0);
print("closure h3 = {}\n", h3 == h1);
// 4. generic function — instantiates with T = *void here
h4 := hash_through(ns_object);
print("generic h4 = {}\n", h4 == h1);
}
inline if OS != .macos {
print("skipped (not macos)\n");
}
0
}