Build sand for wasm32 and compare the hash, rather than repeat the number

It is the project's headline cross-target claim and the page was asserting it
second-hand. Both targets print 2256461126764447066 on this machine, so the
transcript is now what the page shows.
This commit is contained in:
Joseph Ferano 2026-09-12 03:53:38 +07:00
parent 23601f382d
commit 4d1a0c7807
2 changed files with 34 additions and 6 deletions

View File

@ -29,6 +29,13 @@ want "flan usage" "$("$FLAN" 2>&1 | sed -n 2p)"
# calc-me, the first acceptance program, still answers what the page says.
want "calc-me" "$("$FLAN" run "$root/calc-me.flan" '1 + 2 * (3 - 0.5) / 2')"
# The sand hash. The page shows it twice — native and wasm32 — and the claim is
# that the two agree; only the native half is cheap enough to check here.
want "sand hash" "$("$FLAN" run "$root/test/programs/sand-headless.flan")"
# The two cross-target refusals, in the compiler's own words.
want "run --target" "$("$FLAN" run "$here/hello.flan" --target=wasm32-wasi 2>&1)"
# The refusal and diagnostic messages quoted in the prose and in the
# "Not implemented yet" table.
for pair in \

View File

@ -905,6 +905,8 @@ is generated; a Flan string crosses as ptr+len, exactly as it is stored.</p>
<pre><code class="sh">1</code></pre>
<p>That is 1.0, printed by the same rule as before.</p>
<p><code>declare-c</code> names the C library's own function in the C library's own
signature, and the compiler writes the wrapper. This is what raylib's package is made
of — one line per binding:</p>
@ -927,7 +929,8 @@ full of garbage rather than as a link error.</p>
<p>So the boundary has one wrapper per binding, each flattening the aggregates: a struct
returns through an out-pointer, a struct argument is passed by pointer, and clang
classifies all of it, per target, for free. <code>flan shim &lt;file&gt;</code> prints
the whole generated file:</p>
the whole generated file, of which this is the end — the rest is the typedefs
and a comment saying not to edit it:</p>
<pre><code>(defstruct Vector2 [x f32 y f32])
@ -1170,8 +1173,19 @@ uses; it is program-scoped, so in sand you write <code>sim/settle</code> and not
<p>Native x86-64 is the development target. <code>--target=wasm32-wasi</code> produces a
module, and the headless sand acceptance program prints the same 64-bit hash under it as
natively, byte for byte, at <code>-O2</code> and at <code>-O0</code>. That is the
milestone the RNG is written in Flan for.</p>
it does natively:</p>
<pre><code class="sh">$ flan run test/programs/sand-headless.flan
2256461126764447066
$ flan build test/programs/sand-headless.flan --target=wasm32-wasi -o sand.wasm
$ node --no-warnings test/wasm-run.mjs sand.wasm
2256461126764447066</code></pre>
<p>That number is the whole point of writing the RNG in Flan rather than calling libc's:
a grid hash is only a regression test if the sequence is byte-identical on both targets.
It holds at <code>-O2</code> and at <code>-O0</code>. The wasm side needs a
<code>wasm32</code> builtins archive — from wasi-sdk, or emscripten's substituting for
it — and the compiler names every path it looked in when it cannot find one.</p>
<p>Dev and release builds are deliberately different. <code>--dev</code> means
indirection cells and <code>-rdynamic</code>, which is what exports the cells for a loaded
@ -1179,9 +1193,16 @@ module to bind to; release builds call directly, emit constants as constants, an
the folding back. Dev builds are not pruned by reachability, because what a REPL may
redefine next is not a function of what has been called so far.</p>
<p>Some things are refused by name rather than half-supported:
<code>--dev</code> with a wasm target and <code>flan run --target=</code>, both because a
cross-built module is not something this host can <code>dlopen</code> or exec.</p>
<p>Some things are refused by name rather than half-supported, and both cross-target
refusals say why:</p>
<pre><code class="sh">$ flan run hello.flan --target=wasm32-wasi
flan run: --target is refused — a cross-built module is not something this host
can exec. Use flan build --target=... and a wasm runtime.
$ flan build hello.flan --dev --target=wasm32-wasi
wasm32: --dev is native only — the reload path is dlopen, which wasm32 has no
equivalent of</code></pre>
<p>Build time for <code>calc-me.flan</code> is about 110ms, of which the frontend — read,
parse, load, check, emit — is under 10ms. Every C translation unit goes through an object