FIX.org: the break-loop display pass, dated

This commit is contained in:
Joseph Ferano 2026-09-20 22:25:38 +07:00
parent 3a9dbea20a
commit 7ebb97d327

45
FIX.org
View File

@ -4047,3 +4047,48 @@ so an unprintable second argument underlines that argument, not the form —
pinned in test_flan.ml. Output pinned by test/programs/println-variadic.flan pinned in test_flan.ml. Output pinned by test/programs/println-variadic.flan
and its acceptance row (LLVM), spacing exact, "|" markers so a leaked and its acceptance row (LLVM), spacing exact, "|" markers so a leaked
trailing space is a visible red. trailing space is a visible red.
* Break-loop display pass, 2026-09-20
Off a dogfooding session that hit BoundsError: "can I get a better error
message? I don't see a precise line number anywhere, what is s1 and s3? the
condition field messages are weird, the continue message is weird too, do a
full pass and reword things."
** Built
- Condition values render. The break loop stashes the condition pointer in
the agent's snapshot (it used to discard it); [flan_agent_condition] hands
it back on the stopped thread; a new daemon op =condition= builds a render
thunk over the struct's fields — render_locals pointed at the condition —
and delivers it at-stop, so resume-and-restop cannot read the old type over
the new pointer. The buffer's headline now reads the fields inline:
"BoundsError — low 648, high 648, length 100", nothing hardcoding any one
condition. Works for user =error= conditions and for the trap-built ones,
on both backends.
- Precise location. The bounds/slice/arith trap sites publish their loc
around the break-hook call ([flan_break_site] in flan_rt.c), the snapshot
copies it, agent verb =site= serves it, and =break= answers =:site= plus
the line's text as =:source=. The buffer draws "at file:line:col" under the
headline with the source line and a caret at the column.
- Compiler temps are hidden from the locals listing rather than refused as
=s4=; a shadowing rebind strips its =~N= except when the outer binding is
on the same list, where both keep their raw spelling ([Session.shown_names]).
- Rewording. Every bracketed implementation note is gone from the buffer
(they were implemented anyway); the refusal table is one short sentence per
section; the abort line says what abort does ("end the program here; the
dev session ends with it" — true: abort is _exit(134) and merged flan dev
is that process). A shadowed restart is now *takeable*: the buffer sends
=restart-at= with the index for every choice, name as receipt, so the
shadowed line just says "same name as N; taken by its number".
** Deferred, ready to build
- Restart locations. The =%restart= frame is mirrored across emit.ml, x86.ml
and flan_rt.c (fields 0-9 today), so giving =continue= a file:line:col
means: two fields (loc ptr + i64 len, the module's own string, like the
shadow frame's), stores emitted at emit_restart_case in both backends, a
[flan_restart_loc] accessor, the agent snapshot copying it beside each
name, =restarts= growing a loc column, and the buffer printing
"0: [continue] sand.flan:52". Cross-backend ABI change; do it as one lane,
not as a rider.
- A site for user =error= calls. flan_error has no loc parameter; threading
one through means both backends' call emission. Same lane as above if the
frame is being touched anyway.