A statement containing a failed multi-line DEF call still completes, and prints a junk value #7

Open
opened 2026-08-02 19:04:13 -04:00 by tachikoma · 0 comments
Collaborator

Source: TODO.md §6 item 25 (at 9151438)

The call's error is reported and the run stops, but the enclosing statement carries on with
whatever *dest was left holding:

10 DEF BAD(N#)
20 RETURN N# / 0
30 PRINT 99
40 PRINT BAD(1)

prints 99, the division-by-zero line, and then (UNDEFINED STRING REPRESENTATION FOR 0).

Pre-existing, and measured as such: identical before and after the re-entrancy fix, on a build
stashed back to compare. It is visible more often now only because runaway recursion reaches it
where it used to hang instead.

The cause is that akbasic_runtime_process_line_run() swallows a script's error by design --
goal 3 -- so the loop inside akbasic_runtime_user_function() sees the run end normally and hands
back a value nobody should use.

The fix is for the multi-line path to notice the run did not return through RETURN and refuse
rather than produce a value.
Not done because it is a decision about what a failed call
evaluates to, and tests/language/functions/recursion.bas deliberately does not pin the current
answer.

Files: src/runtime.c (akbasic_runtime_user_function)


Filed by Tachikoma (Claude Code, Opus 5, 1M context)

**Source:** TODO.md §6 item 25 (at 9151438) The call's error is reported and the run stops, but the *enclosing* statement carries on with whatever `*dest` was left holding: ```basic 10 DEF BAD(N#) 20 RETURN N# / 0 30 PRINT 99 40 PRINT BAD(1) ``` prints `99`, the division-by-zero line, and then `(UNDEFINED STRING REPRESENTATION FOR 0)`. **Pre-existing, and measured as such**: identical before and after the re-entrancy fix, on a build stashed back to compare. It is visible more often now only because runaway recursion reaches it where it used to hang instead. **The cause** is that `akbasic_runtime_process_line_run()` swallows a script's error by design -- goal 3 -- so the loop inside `akbasic_runtime_user_function()` sees the run end normally and hands back a value nobody should use. **The fix is for the multi-line path to notice the run did not return through `RETURN` and refuse rather than produce a value.** Not done because it is a decision about what a failed call *evaluates to*, and `tests/language/functions/recursion.bas` deliberately does not pin the current answer. **Files:** `src/runtime.c` (`akbasic_runtime_user_function`) --- Filed by Tachikoma (Claude Code, Opus 5, 1M context)
tachikoma added this to the 0.1.x milestone 2026-08-02 19:04:13 -04:00
tachikoma added the defectblast-radius:mediumstatus::grooming labels 2026-08-02 19:04:13 -04:00
Sign in to join this conversation.