← board

bug: BASIC frontend's GOTO/GOSUB silently halt the program instead of jumping

What's broken

compiler/blexer.inc lexes GOTO and GOSUB straight to tkHalt (the Halt-statement token):

if lower = 'goto' then Result := tkHalt;   { line 37 }
...
if lower = 'gosub' then Result := tkHalt;  { line 46 }
...
if lower = 'return' then Result := tkExit; { line 49 — RETURN -> function exit,
                                              not a GOSUB return-address pop }

Every BASIC program containing a GOTO/GOSUB anywhere halts the whole program the instant it reaches that statement — no jump, no error, clean exit code 0. Confirmed minimal repro:

10 PRINT "A"
20 GOTO 40
30 PRINT "SKIPPED"
40 PRINT "B"

Output: A only. Line 40 (B) never prints — GOTO 40 doesn't jump forward, it just ends the program. Same result for a backward GOTO (a WHILE-style loop written with line numbers never loops — one pass, then exits clean).

This also silently breaks test/test_basic_comprehensive.bas, the frontend's own existing test file, which relies on GOTO/GOSUB for its first section (classic jump-style control flow) — it currently prints one line of ~15+ expected and exits 0, looking "successful" unless you check the output.

Why urgent, not just a bug

Silent-wrong is worse than a compile error here: the program builds cleanly, runs, exits 0 — nothing signals anything is wrong unless you read the output. Matches this project's own "correctness-sensitive, not a compile-error risk" bar used elsewhere (e.g. Rust drop/move-tracking).

Likely fix shape (not investigated further — Track A to size properly)

Log

Fixed (2026-07-06, combined-track session — Track A files, user-confirmed multi-track ok)

Verified: ticket repro prints A,B; backward-GOTO loop terminates; nested GOSUB (main→sub1→sub2, then main→sub2) returns correctly; 9-deep GOSUB recursion ok, 15-deep trips the guard; stray RETURN errors exit 1; test_basic_comprehensive.bas now runs its full ~21-line output (was 1 line + exit 0). New regression test test/test_basic_goto_gosub.bas + the comprehensive file wired into make test. Full suite + self-host fixedpoint byte-identical (build rule cmp).