Files
sx/examples/1337-ffi-objc-call-11-bool-return.sx
agra 4e942b5373 test: migrate examples to XXXX-category-name layout + split expected streams
Rename all example tests/companions to the XXXX-category-test-name scheme
(per-category 100-blocks: basic 0010, types 0100, ... errors 1000,
diagnostics 1100, ffi 1200, ffi-objc 1300, ffi-jni 1400, vectors 1500,
platform 1600). Companions and dir/C fixtures move in lockstep with their
parent test; #import/#source/#include paths rewritten to match.

Expected output now lives in examples/expected/ (a sibling dir of the
tests) split into three streams per the new convention:
  <name>.exit / <name>.stdout / <name>.stderr  (+ optional <name>.ir)

run_examples.sh rewritten: scans examples/ and issues/ for an
expected/<name>.exit marker, captures stdout and stderr separately (no
more 2>&1), compares each stream + exit + optional IR snapshot.

Behavior validated unchanged: every renamed test reproduces its prior
merged output + exit (diffs limited to file paths/basenames embedded in
diagnostics + traces, which correctly reflect the new names). Suite:
292 passed, 0 failed. 50-smoke.sx split + issue relocation + docs follow
in subsequent commits.
2026-06-01 19:05:15 +03:00

49 lines
1.9 KiB
Plaintext

// Backfill for Phase 1D cluster 1.28 (PLAN-FFI.md): `#objc_call(bool)`
// against `BOOL`-returning selectors. Obj-C `BOOL` is single-byte on
// every Apple ABI we ship to (signed char on i386, native `bool` on
// arm64), so the slot shape is identical to `#objc_call(u8)` — this
// test is about the source-level type being meaningful, not a
// distinct ABI path.
//
// Two IMPs are installed: `yes_imp` returns true, `no_imp` returns
// false. Both are dispatched through `#objc_call(bool)` and the
// results are checked.
#import "modules/std.sx";
#import "modules/compiler.sx";
#import "modules/std/objc.sx";
yes_imp :: (self: *void, _cmd: *void) -> bool callconv(.c) { true; }
no_imp :: (self: *void, _cmd: *void) -> bool callconv(.c) { false; }
main :: () -> s32 {
inline if OS == .macos {
// Nil-recv: libobjc returns a zeroed slot, which decodes as false.
nil_b := #objc_call(bool)(null, "isEqual:");
print("nil bool = {}\n", nil_b);
ns_object := objc_getClass("NSObject".ptr);
my_cls := objc_allocateClassPair(ns_object, "SxBoolProbe".ptr, 0);
// BOOL type-encoded as `B` (C99 _Bool) in `B@:` — implicit
// (self: id, _cmd: SEL) return BOOL. Some toolchains prefer
// `c` (signed char) for BOOL on i386, but `B` is unambiguous
// on arm64 and works for runtime-registered IMPs.
sel_yes := sel_registerName("yes".ptr);
sel_no := sel_registerName("no".ptr);
class_addMethod(my_cls, sel_yes, xx yes_imp, "B@:".ptr);
class_addMethod(my_cls, sel_no, xx no_imp, "B@:".ptr);
objc_registerClassPair(my_cls);
instance := class_createInstance(my_cls, 0);
y := #objc_call(bool)(instance, "yes");
n := #objc_call(bool)(instance, "no");
print("yes = {}\n", y);
print("no = {}\n", n);
}
inline if OS != .macos {
print("skipped (not macos)\n");
}
0;
}