Skip to content

Commit eec7d55

Browse files
P1: fix Zig FFI to build and match the Idris2 ABI (#37)
## Summary The Zig FFI (`src/interface/ffi/src/main.zig`) failed to compile under **Zig 0.14.0**. This PR fixes the two compile errors with minimal, behaviour-preserving changes. Only `src/interface/ffi/src/main.zig` is touched; the **Idris2 ABI is the source of truth** and was left untouched. ## Errors (from `zig test src/main.zig -lc`) 1. `src/main.zig:118` — `@bitCast size mismatch: destination type 'u64' has 64 bits but source type 'i128' has 128 bits`. In `betlangiser_init`, `std.time.nanoTimestamp()` returns `i128`, but it was `@bitCast` directly into the `u64` PRNG seed. 2. `src/main.zig:558` — `name shadows primitive 'u1'`. In `sampleDistribution` (Box-Muller normal sampling), the locals `u1`/`u2` shadow the built-in primitive type `u1`, which is an error in Zig 0.14. ## Fixes 1. Reinterpret the `i128` timestamp as `u128`, then truncate to `u64`: `@truncate(@as(u128, @bitcast(std.time.nanoTimestamp())))`. 2. Rename the Box-Muller locals `u1`/`u2` → `unif1`/`unif2`. Net diff: 4 insertions, 4 deletions in one file. ## ABI fidelity (preserved) No exported C symbol names, signatures, or integer encodings changed: - All 26 `C:betlangiser_*` symbols in `Foreign.idr` still map to matching `export fn`s. - `Result` enum `ok=0 … sampling_failed=6` matches `Types.idr` `resultToInt`. - `TernaryBool` encoding `t_false=0, t_true=1, t_unknown=2` matches `ternaryToInt`. - `DistributionTag` encoding `normal=0 … custom=4` matches `distributionTag`. ## Verification - `cd src/interface/ffi && zig test src/main.zig -lc` → **all 9 tests pass**, zero errors/warnings, exit 0. - `cd src/interface/abi && idris2 --build betlangiser-abi.ipkg` → **exit 0** (build dir removed afterwards). - Symbol-coverage check: every `C:<name>` in `Foreign.idr` has a matching `export fn <name>` in `main.zig` (26/26 OK). Note: any rust-ci / Hypatia / governance red checks are pre-existing estate-infra issues unrelated to this Zig-only change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH --- _Generated by [Claude Code](https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent bf59a6c commit eec7d55

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

src/interface/ffi/src/main.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export fn betlangiser_init() ?*anyopaque {
115115
engine.* = .{
116116
.allocator = allocator,
117117
.initialized = true,
118-
.prng = std.Random.DefaultPrng.init(@bitCast(std.time.nanoTimestamp())),
118+
.prng = std.Random.DefaultPrng.init(@truncate(@as(u128, @bitCast(std.time.nanoTimestamp())))),
119119
.distributions = std.ArrayList(*Distribution).init(allocator),
120120
};
121121

@@ -555,9 +555,9 @@ fn sampleDistribution(engine: *Engine, dist: *const Distribution) f64 {
555555
return switch (dist.tag) {
556556
.normal => blk: {
557557
// Box-Muller transform for normal sampling
558-
const u1 = random.float(f64);
559-
const u2 = random.float(f64);
560-
const z = @sqrt(-2.0 * @log(u1)) * @cos(2.0 * std.math.pi * u2);
558+
const unif1 = random.float(f64);
559+
const unif2 = random.float(f64);
560+
const z = @sqrt(-2.0 * @log(unif1)) * @cos(2.0 * std.math.pi * unif2);
561561
break :blk dist.param1 + dist.param2 * z;
562562
},
563563
.uniform => dist.param1 + (dist.param2 - dist.param1) * random.float(f64),

0 commit comments

Comments
 (0)