Files
akbasic/tests/reference
Andrew Kesterson 8bc253ebbf Give a loaded line a number when it arrives without one
A script written against LABEL and GOTO NAME never names a line number, so
the numbers it had to carry were decoration. akbasic_runtime_load(),
RUNSTREAM and DLOAD now file an unnumbered line one slot after the last one
filed; a numbered line is filed under its number and moves the cursor, so
the two mix. akbasic_runtime_file_line() is the one implementation of that
rule, so the three paths cannot drift.

The prompt is untouched. A line typed without a number is still direct mode
and still runs now -- that is the only thing separating program text from a
statement at a REPL, and it is why this is a loading feature.

What this replaces was silent data loss: an unnumbered line was filed under
the cursor unchanged, on top of the line before it. A blank line therefore
erased whatever preceded it, and RUNSTREAM did not skip blank lines the way
the other two paths did.

That moves one golden file, and the reference had the same defect.
language/arithmetic/integer.bas has four PRINT statements, an expectation
with three values, and a trailing blank line that erased 40 PRINT 4 - 2
before the program ran. The expectation is now 4 4 2 2.
tests/reference/README.md records the divergence and TODO.md section 5 item
63 says why.

akbasic_SourceLine grows a `numbered` flag so an assigned number can be told
from a written one. RENUMBER sets it on every line it touches; NEW, DELETE
and DLOAD clear it. hadlinenumber moves to akbasic_scanner_scan(), so it
always describes the line just scanned rather than only the REPL's.

Two lines carrying the same written number still keep the last, as they
always have. That is a separate decision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 16:33:27 -04:00
..

The reference interpreter's own test corpus

These 41 .bas files and their 41 .txt expectations are not this project's tests. They are a byte-for-byte copy of the acceptance corpus belonging to the Go implementation this interpreter was ported from:

Source https://source.starfort.tech/andrew/basicinterpreter, tests/
Copied at commit d76162cb37eeaccddae2cf6cab7af7bc8175d6d2 ("Update README.md")
Copied on 2026-07-31
Verified every file cmp-identical to the submodule at the time of the copy

They are registered as the golden_* CTest cases and run against basic on every build, in both the default and the -DAKBASIC_WITH_AKGL=ON configurations.

Why they are a copy, when they deliberately were not

Until 2026-07-31 these were driven in place out of deps/basicinterpret, and the reasoning was written down in CMakeLists.txt: the corpus is a submodule, and copying a submodule's corpus guarantees drift.

That reasoning was sound and it stopped applying. The Go project is deprecated and will not be updated, so there is nothing left to drift from — and a build that cannot run its own acceptance suite without cloning the implementation it replaced is not finished.

What these are for now

A regression suite, not a specification. That distinction is the whole of how to treat them, and it changed on 2026-07-31 (TODO.md §0.1): matching the Go implementation is no longer a goal, so a difference between it and this interpreter is not automatically a bug in this one.

What they are still good for is unchanged and is worth a lot: forty-one real BASIC programs with known-good output, covering arithmetic, arrays, flow control, every builtin function, READ/DATA, labels and three worked examples. That catches regressions whatever its provenance.

The rule for editing these

Diverge deliberately, never by accident.

A failure here means this interpreter's behaviour changed. Nine times in ten that is a bug you just introduced and the answer is to fix the code. The tenth time it is an improvement on the reference, and then the answer is:

  1. Change the expectation in the same commit as the code.
  2. Say why in the commit message.
  3. Add a line to TODO.md §5, which is the list of deliberate deviations.

What is not acceptable is editing a .txt to make a red suite green without deciding which of the two you are doing.

New cases for this project's own behaviour go in tests/language/, registered under local_*. The prefix says which corpus a failure came from, and a diff touching tests/reference/ stands out as the thing it is.

Divergences so far

Case Change Why
language/arithmetic/integer.txt Expectation grew from 4 4 2 to 4 4 2 2 The program has four PRINT statements and the expectation had three values. The file ends in a blank line, and both interpreters filed a blank line under the loader's cursor — which for a line with no number of its own is the number of the line before it. So 40 PRINT 4 - 2 was erased before the program ran. The reference lost it the same way, which is why the expectation was written short. Fixed by skipping blank lines in RUNSTREAM, as akbasic_runtime_load() and DLOAD already did. TODO.md §5.
examples/strreverse.bas Variable INPUT$ renamed to SOURCE$ INPUT$ is a reserved word with a type suffix, which a real C128 refuses and which this interpreter now refuses too (TODO.md §6 item 16). The reference accepted it only because its own reserved-word check never fired. The expectation is byte-for-byte unchanged — the program still prints REVERSED: OLLEH — so the case keeps all of its value.