Document every error code a script can see, as chapter 15

ER# held numbers nothing explained. The appendix lists the four error classes
the interpreter prints, the eight codes it owns and what raises each, and the
codes that reach ER# from errno, libakerror and libakgl underneath it.

The table is not asserted. A program in the chapter trips seven of the eight and
prints what it got, and docs_examples byte-compares the result -- so the numbers
are checked rather than claimed. The eighth, 516, is not usefully trappable and
the chapter says why: entering a handler takes a scope, and the pool being empty
is what raised it.

Two things worth a reader's attention came out of writing it. Two codes register
the same ERR() text, so a program must compare the number and print the text.
And VAL reports libakerror's Value Error rather than the interpreter's 517,
which makes that number the platform's rather than ours -- filed as section 6
item 21, not fixed here, because deciding which libakstdlib failures to
translate is a boundary question and ENOENT out of DOPEN is the counter-case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 07:36:36 -04:00
parent 48f650c3af
commit 737fdc760f
8 changed files with 210 additions and 6 deletions

32
TODO.md
View File

@@ -1502,6 +1502,27 @@ the reference's semantics reproduced faithfully; the third is the port's own.
listings read it there. Same known-failing test as item 19; the fix is a scoping decision
about where a loop counter is created, not an ordering one.
### Found while writing the error-code appendix
21. **A dependency's status code reaches `ER#` where the interpreter has one of its own.**
`VAL("XYZ")` reports `AKERR_VALUE` — 144 on this machine — rather than
`AKBASIC_ERR_VALUE` (517), because `akbasic_fn_val()` (`src/runtime_functions.c:261`)
hands the string to `aksl_atof()` and returns whatever comes back. Both register the
name `Value Error`, so `ERR(ER#)` cannot tell them apart and only the number can.
**The consequence is that the number is not portable.** `libakerror`'s codes are offsets
from the platform's largest `errno`, so a program testing `IF ER# = 144` is right on one
machine and wrong on the next, where 517 — which is absolute — is what it should have
been able to test. `docs/15-error-codes.md` documents the behaviour as it stands and
tells a program to compare the code rather than the text.
Not fixed here because it is a decision about a boundary rather than a patch: every
place the interpreter calls into `libakstdlib` on a *program's* behalf could translate
the failure into the akbasic band, and the list of those places wants collecting before
the first one is changed. The disk verbs are the interesting counter-case — `ENOENT` out
of `DOPEN` is genuinely more useful to a program than a flat 519 — so this is not
"translate everything", which is exactly why it needs deciding rather than doing.
## 7. Filing gaps against `libakgl`
When phase 7 or phase 8 needs something `libakgl` does not have, **stop and file it** in
@@ -1824,9 +1845,16 @@ What remains, in priority order:
read the size. 320x200 is now the fallback for a backend that will not answer. Deviation 18
in §5 has the whole of it, including the off-by-one it fixed on the way.
11. Error codes are undefined for the user
11. ~~**Error codes are undefined for the user.**~~ **Done** — `docs/15-error-codes.md`, an
appendix covering the four error classes the interpreter prints, the eight codes it owns
with what raises each, and the codes that reach `ER#` from `errno`, `libakerror` and
`libakgl` underneath it. The table is not asserted: a program in the chapter trips seven
of the eight and prints what it got, and `docs_examples` byte-compares the result.
In the documentation, include a complete table of all possible values of ER# and EL# in the documentation in an appendix.
**It found three things rather than documenting eight.** A parse error under an armed
`TRAP` vanished entirely and a trapped parse error reported `ER# 0` — both fixed, both
recorded above. And `VAL` reports a dependency's status code where the interpreter has
one of its own, which is §6 item 21 and is filed rather than fixed.
12. Screenshots for graphics operations