The renderer check greps a line out of NEXT.md, and NEXT.md is a scratch document
that gets rewritten. The line went, the grep went empty, and the empty-needle guard
did its job and said so -- into a report nobody was reading. Behind that noise the
page was genuinely wrong: the colon-to-dot sweep rewrote every field label in the
corpus and lib/render.ml writes .field today, so the inspector block on the page had
been showing {:x 1.5 :y 0} for a renderer that prints {.x 1.5 .y 0}. test_repl.ml's
fixtures are the authority and they are dots throughout, with an enum member still a
colon; the page now matches. The anchor moves to test/programs/raylib-imported.flan,
which dune test builds and runs, so it cannot quietly stop saying it.
The LLVM excerpt beside it moved too: a --dev main pushes a condition frame before
anything else now, which shifted the SSA numbering by one. The three quoted lines are
what flan emit --dev prints today, with the frame push marked as elided rather than
silently dropped.
120 lines
6.0 KiB
Bash
120 lines
6.0 KiB
Bash
#!/bin/sh
|
|
# The blocks on index.html that are not programs in this directory are quoted
|
|
# from somewhere: a repository file, or the output of a command. Each one is
|
|
# re-derived here and looked for in the page, so a quote cannot go stale
|
|
# quietly. check.sh covers the runnable blocks; this covers the rest.
|
|
#
|
|
# $ dune build && sh web/examples/quotes.sh
|
|
here=$(cd "$(dirname "$0")" && pwd)
|
|
root=$(cd "$here/../.." && pwd)
|
|
FLAN=${FLAN:-$root/_build/default/bin/main.exe}
|
|
page=$here/../index.html
|
|
fail=0
|
|
|
|
# The page is compared with its whitespace collapsed, so that a long compiler
|
|
# message may be wrapped in the HTML and still be recognised as the same text.
|
|
flat=$(sed -e 's/</</g' -e 's/>/>/g' -e 's/&/\&/g' "$page" | tr '\n' ' ' | tr -s ' ')
|
|
|
|
want() {
|
|
# An empty needle would match anything — `case $x in **)` is always true — so
|
|
# every check whose text comes from a grep would go green the moment the line
|
|
# it greps for was renamed. That is the one failure this script exists to
|
|
# catch, so the empty case is a failure and not a match.
|
|
if [ -z "$2" ]; then
|
|
echo "FAIL $1"
|
|
echo " nothing to compare against — whatever this quotes has moved"
|
|
fail=1
|
|
return
|
|
fi
|
|
needle=$(printf '%s' "$2" | tr '\n' ' ' | tr -s ' ')
|
|
case $flat in
|
|
*"$needle"*) echo "ok $1" ;;
|
|
*) echo "FAIL $1"; echo " not on the page: $2"; fail=1 ;;
|
|
esac
|
|
}
|
|
|
|
# The usage text, from the binary itself.
|
|
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. Each is a program the compiler must reject, and
|
|
# what is compared is the first line of the rejection -- the message itself.
|
|
# Not the whole of what `flan check` prints: it grew a source excerpt with a
|
|
# caret under the offending form, and a needle that swallowed the excerpt was
|
|
# comparing three lines against a page that quotes one.
|
|
#
|
|
# Six probes that used to live here are gone, and it is worth saying why rather
|
|
# than leaving the next reader to wonder what the list once covered. (Vec T),
|
|
# (Map K V), (Handle T), an (Fn ...) parameter, a defer inside a let, and break
|
|
# were each refused as "not implemented yet" when this loop was written. All six
|
|
# work now, the page's table lost their rows as they landed, and the probes were
|
|
# the only thing left asserting a claim nobody makes any more. A probe for a
|
|
# refusal that no longer happens cannot go green, and keeping it would have meant
|
|
# a permanently red script -- which is the same as no script at all.
|
|
for pair in \
|
|
'result:(defn f [] (Result i32 i32) None)' \
|
|
'quoted:(defn f [] i32 (quote a))' \
|
|
'i64index:(defconst xs [3 i32] [1 2 3]) (defn main [] i32 (let [i (i64 1)] (at xs i)))'
|
|
do
|
|
name=${pair%%:*}; src=${pair#*:}
|
|
printf '%s\n' "$src" > "$here/.q.flan"
|
|
out=$("$FLAN" check "$here/.q.flan" 2>&1)
|
|
# A probe that compiles is the failure this loop is most likely to meet, and
|
|
# it is the one that used to be unreadable: `flan check` answers a clean
|
|
# program with its whole symbol table, so the needle became eighty lines of
|
|
# prelude signatures and the diff said nothing. Say what actually happened.
|
|
if "$FLAN" check "$here/.q.flan" >/dev/null 2>&1; then
|
|
echo "FAIL message: $name"
|
|
echo " this program compiles now — the page still says it is refused"
|
|
fail=1
|
|
continue
|
|
fi
|
|
want "message: $name" "$(printf '%s\n' "$out" | sed 's/^[^ ]*: //' | sed -n 1p)"
|
|
done
|
|
rm -f "$here/.q.flan"
|
|
|
|
# The cell and the transfer channel, from a real --dev emit. hello.flan cannot
|
|
# show a cell any more: println is compiler-provided rather than a Flan
|
|
# function, so the smallest program makes no Flan-to-Flan call at all. defer.flan
|
|
# is the smallest one on the page that does — its main calls work.
|
|
ir=$("$FLAN" emit --dev "$here/defer.flan" 2>/dev/null)
|
|
want "cell global" "$(printf '%s\n' "$ir" | grep '^@"flan.cell.work"')"
|
|
want "cell load" "$(printf '%s\n' "$ir" | grep 'load ptr, ptr @"flan.cell.work"')"
|
|
want "xfer channel" "$(printf '%s\n' "$ir" | grep 'define {} @"flan.main"')"
|
|
|
|
# The generated C, from flan shim.
|
|
want "shim wrapper" "$("$FLAN" shim "$here/shimdemo.flan" | grep 'GetMousePosition();')"
|
|
|
|
# Lines quoted verbatim from repository files.
|
|
want "raylib binding" "$(grep -F 'unload-texture' "$root/vendor/raylib/raylib.flan")"
|
|
want "agent declare" "$(grep -F 'flan_agent_poll' "$root/vendor/agent/agent.flan" | head -1)"
|
|
want "conditions.org" "$(grep -F 'Innermost frame offering the name wins' "$root/conditions.org")"
|
|
# The value renderer, anchored in the test corpus rather than in NEXT.md. It
|
|
# used to grep NEXT.md for this line, and NEXT.md is a rolling scratch document:
|
|
# the line was rewritten out of it, the grep went empty, and the check spent
|
|
# weeks reporting "whatever this quotes has moved" while the page really had
|
|
# gone stale -- the colon-to-dot sweep rewrote every field label in the corpus
|
|
# and left the renderer's own output on this page spelled the old way. An anchor
|
|
# has to be somewhere that cannot quietly stop saying the thing, and the corpus
|
|
# is such a place, because `dune test` builds and runs it.
|
|
want "renderer" "$(grep -oF '{.r 17 .g 34 .b 51 .a 68}' "$root/test/programs/raylib-imported.flan" | head -1)"
|
|
|
|
# The Emacs bindings, from the keymap rather than from any prose about it.
|
|
for k in "C-c C-c" "C-c C-k" "C-x C-e" "C-c C-b" "C-c C-v" "C-c C-x"; do
|
|
grep -qF "(kbd \"$k\")" "$root/emacs/flan-mode.el" || {
|
|
echo "FAIL keybinding $k is not in flan-mode.el"; fail=1; continue; }
|
|
want "keybinding $k" "<kbd>$k</kbd>"
|
|
done
|
|
|
|
exit $fail
|