print and println had no line anywhere on index.html — a builtin the reader meets in the first example and is never told about. There is a section for them now, between arrays and the prelude: what the walk covers, that an enum comes back as its name and a Ptr does not get followed, that a string is raw at the top and quoted inside a structure, and that the depth and span caps are what keep a grid from printing a screenful. printing.flan is beside the other examples so check.sh has been green on every line of it. The prelude's table loses its output row, because the prelude has no output functions left, and the fifty-odd example blocks follow the files they quote. Two pinned things moved. sand-headless prints 15595743031174623232 where it printed -2851001042534928384: same bits, read unsigned, because the cast that made it signed is gone. bounds.flan's trap moved from column 28 to 19, which is where (at xs i) now starts on that line. And the indirection-cell illustration is defer.flan rather than hello.flan. hello.flan cannot show a cell any more: its one call was to a prelude function, and println is compiler-provided, so the smallest program makes no Flan-to-Flan call at all. defer.flan's main calls work, and is already on the page a few sections up.
95 lines
4.2 KiB
Bash
95 lines
4.2 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.
|
|
for pair in \
|
|
'vec:(defvar xs (Vec i32))' \
|
|
'map:(defvar m (Map string i32))' \
|
|
'result:(defn f [] (Result i32 i32) None)' \
|
|
'handle:(defvar h (Handle i32))' \
|
|
'fnty:(defn f [g (Fn [i32] i32)] i32 (g 1))' \
|
|
'quoted:(defn f [] i32 (quote a))' \
|
|
'deferblock:(defn f [] i32 (let [x 1] (defer (println "a")) x))' \
|
|
'i64index:(defconst xs [3 i32] [1 2 3]) (defn main [] i32 (let [i (i64 1)] (at xs i)))' \
|
|
'break:(defn main [] (let [i 0] (while (< i 3) (break))))'
|
|
do
|
|
name=${pair%%:*}; src=${pair#*:}
|
|
printf '%s\n' "$src" > "$here/.q.flan"
|
|
msg=$("$FLAN" check "$here/.q.flan" 2>&1 | sed 's/^[^ ]*: //')
|
|
want "message: $name" "$msg"
|
|
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")"
|
|
want "renderer" "$(grep -F ':r 17 :g 34 :b 51 :a 68' "$root/NEXT.md")"
|
|
|
|
# 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
|