From 6c34d4a66e26dd9aa52f8a7829ae34308ba1b8b2 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sat, 12 Sep 2026 03:50:48 +0700 Subject: [PATCH] Quote the compiler's own words for the index rule, and pin the Emacs keys The paraphrase of why a wide index is refused was shorter and said less than the message; and the keybinding table came from NEXT.md, which is two keys behind flan-mode.el, so it now reads the keymap instead. --- web/examples/quotes.sh | 31 +++++++++++++++++++++---------- web/index.html | 7 +++++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/web/examples/quotes.sh b/web/examples/quotes.sh index a9eaaa8..d7d26a5 100644 --- a/web/examples/quotes.sh +++ b/web/examples/quotes.sh @@ -11,14 +11,16 @@ FLAN=${FLAN:-$root/_build/default/bin/main.exe} page=$here/../index.html fail=0 -# Look for a literal string in the page, allowing for HTML escaping of < and >. +# 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' "$page" | tr '\n' ' ' | tr -s ' ') + want() { - esc=$(printf '%s' "$2" | sed -e 's/&/\&/g' -e 's//\>/g') - if grep -qF -- "$esc" "$page"; then echo "ok $1"; else - echo "FAIL $1" - echo " not on the page: $2" - fail=1 - 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. @@ -27,7 +29,8 @@ 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 refusal messages quoted in "Not implemented yet" and under defer. +# 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))' \ @@ -35,12 +38,13 @@ for pair in \ '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 (print-line "a")) x))' + 'deferblock:(defn f [] i32 (let [x 1] (defer (print-line "a")) x))' \ + '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" msg=$("$FLAN" check "$here/.q.flan" 2>&1 | sed 's/^[^ ]*: //') - want "refusal: $name" "$msg" + want "message: $name" "$msg" done rm -f "$here/.q.flan" @@ -59,4 +63,11 @@ want "agent declare" "$(grep -F 'flan_agent_poll' "$root/vendor/agent/agent.fla 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" "$k" +done + exit $fail diff --git a/web/index.html b/web/index.html index 82a7e9d..79b2343 100644 --- a/web/index.html +++ b/web/index.html @@ -372,8 +372,11 @@ and logical on an unsigned one.

An index converts from a narrower integer and never from a wider one. A u32 index is fine — anything above 231 truncates to a negative i32 and the unsigned bounds check rejects it. An i64 index is -refused, because 232+5 truncates to 5 and would read the wrong element with -no trap at all.

+refused, and the message is worth reading because it is the shape of most of them:

+ +
an index is an i32, and i64 is wider — write (i32 …), because a value that does
+not fit truncates to one that does and would read the wrong element without
+tripping the bounds check

Structs and enums