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>
This commit is contained in:
30
TODO.md
30
TODO.md
@@ -1355,6 +1355,36 @@ deviations from the reference's *program*: `main.go` and the SDL half of
|
||||
it had not been used for, and both were filed rather than worked around silently. One came
|
||||
back fixed.
|
||||
|
||||
63. **Line numbers are optional in a loaded program, and a blank line is not a program line.**
|
||||
**This one moved a golden file.** A line with no number used to be filed under the loader's
|
||||
cursor unchanged — that is, on top of the line before it — so two unnumbered lines in a row
|
||||
silently lost the first, and a *blank* line erased whatever preceded it. The reference does
|
||||
the same, and `tests/reference/language/arithmetic/integer.bas` is the proof: 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` and
|
||||
`tests/reference/README.md` records it.
|
||||
|
||||
In its place: `akbasic_runtime_file_line()` (`src/runtime.c`) is the one implementation of
|
||||
the rule, shared by `akbasic_runtime_load()`, RUNSTREAM and `DLOAD`. A numbered line is
|
||||
filed under its number and moves the cursor; an unnumbered one takes the slot after it;
|
||||
blank lines are skipped by all three. A collision involving an assigned number is refused
|
||||
with `AKBASIC_ERR_BOUNDS` rather than overwriting. `akbasic_SourceLine` grew a `numbered`
|
||||
flag so deviation 64 can tell the two apart.
|
||||
|
||||
**The prompt is deliberately untouched.** A line typed without a number is direct mode and
|
||||
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 rather than a language-wide one. `AUTO` remains the way
|
||||
to enter program text without typing numbers.
|
||||
|
||||
Consequence worth stating: an unnumbered program is capped at 9998 lines, the cap that
|
||||
already existed, and its assigned numbers are increment-1 — so `LIST` and `DSAVE` show a
|
||||
listing with no gaps to insert into. `RENUMBER` before `DSAVE` gives the gaps back, and
|
||||
marks every line numbered.
|
||||
|
||||
**Not changed:** two lines that both carry the *same* written number still silently keep
|
||||
the last, as they always have. That is a separate decision with its own corpus risk and it
|
||||
is not this one.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user