Fix 80-column fixtures and tutorial expectations
Some checks failed
akbasic CI Build / cmake_build (push) Successful in 3m35s
akbasic CI Build / sanitizers (push) Successful in 4m40s
akbasic CI Build / coverage (push) Successful in 3m56s
akbasic CI Build / akgl_build (push) Has been cancelled
akbasic CI Build / mutation_test (push) Has been cancelled

This commit is contained in:
2026-08-04 16:14:04 -04:00
parent 1e514f679b
commit bd63e3e9fa
18 changed files with 42 additions and 41 deletions

View File

@@ -685,9 +685,9 @@ seconds asks for fifty frames a second.
### Why `GOTO` rather than `DO ... LOOP`
A `DO ... LOOP` around the frame would read better, and it is not usable here: **a `GOTO`
that jumps out of a `FOR` or a `DO` does not release the loop's scope.** There are 32
that jumps out of a `FOR` or a `DO` does not release the loop's scope.** There are 12
scopes, so a game that leaves its main loop once per lost life stops on the
thirty-second one:
twelfth one:
```basic
N# = 0
@@ -700,7 +700,7 @@ PRINT "SURVIVED " + N#
```
```output
? 3 : PARSE ERROR Environment pool exhausted at line 3 (32 in use)
? 3 : PARSE ERROR Environment pool exhausted at line 3 (12 in use)
```

View File

@@ -1423,7 +1423,8 @@ IF STATE# = 2 THEN GOSUB UNSTICK
RETURN
LABEL PRESSPAUSE
IF STATE# = 2 THEN STATE# = 6 : GMTYP# = 0 : BAN$ = "PAUSED" : GOSUB SETBANNER : RETURN
IF STATE# = 2 THEN STATE# = 6 : GMTYP# = 0 : BAN$ = "PAUSED"
IF STATE# = 6 THEN GOSUB SETBANNER : RETURN
IF STATE# = 6 THEN STATE# = 2 : BAN$ = "" : GOSUB SETBANNER
RETURN
```

View File

@@ -1,6 +1,6 @@
10 REM An array reference used as a function argument, and as one of several.
20 REM An identifier's subscript list used to hang off .right, which is also
30 REM where an argument list chains its arguments -- so the arity counter walked
30 REM where an argument list chains its arguments; the arity counter walked
40 REM straight into the subscripts and refused the call. TODO.md section 4.
50 DIM C#(4)
60 C#(1) = -9

View File

@@ -1,6 +1,6 @@
10 REM FILTER has no device capability behind it -- akgl_audio_* synthesises and
20 REM mixes but has no filter stage, and SDL3 supplies no primitive to build one
30 REM from. It is refused rather than silently ignored, so a program that asked
10 REM FILTER has no device capability; akgl_audio_* synthesises and mixes but
20 REM has no filter stage, and SDL3 supplies no primitive to build one from.
30 REM It is refused rather than silently ignored, so a program that asked
40 REM for a low-pass finds out it did not get one.
50 PRINT "BEFORE"
60 FILTER 1000, 1, 0, 0, 5

View File

@@ -1,4 +1,4 @@
10 REM The standalone driver lends the script no audio device. ENVELOPE, VOL and
10 REM The standalone driver lends the script no audio device. ENVELOPE, VOL,
20 REM TEMPO only change interpreter state, so they work regardless; SOUND and
30 REM PLAY need the device and must name themselves when there is none.
40 ENVELOPE 1, 5, 9, 12, 2

View File

@@ -1,6 +1,6 @@
10 REM A DEF call takes its environment from the pool, one per call, exactly as
10 REM A DEF call takes one environment from the pool, exactly as
20 REM GOSUB does. It used to be owned by the funcdef and reset on every call,
30 REM which cost two silent defects: two calls in one expression shared a slot,
30 REM which cost two silent defects: calls in one expression shared a slot,
40 REM and recursion never came back at all.
50 DEF FACT(N#)
60 IF N# <= 1 THEN RETURN 1
@@ -15,9 +15,9 @@
150 DEF DBL(N#) = N# * 2
160 PRINT DBL(10) + DBL(1)
170 PRINT DBL(1) + DBL(10) + DBL(100)
180 REM Depth answers to the environment pool now, so runaway recursion reports
190 REM "Environment pool exhausted" rather than hanging. It is not exercised here
200 REM because the statement containing a failed call still prints a junk value
210 REM afterwards -- a separate, pre-existing defect recorded in TODO.md, and one
220 REM this golden file would pin if it went in. tests/user_functions.c asserts
180 REM Depth answers to the environment pool, so runaway recursion reports
190 REM "Environment pool exhausted" rather than hanging. It is not exercised
200 REM here because the failed statement still prints junk afterwards;
210 REM this is a separate defect in TODO.md, and one this golden file
220 REM would pin if it went in. tests/user_functions.c asserts
230 REM the message instead.

View File

@@ -1,4 +1,4 @@
10 REM A range check reported through the driver, end to end. The program stops
10 REM A range check reported through the driver, end to end. The program
20 REM at the first error, so this file covers one; the rest of the checks are
30 REM asserted in tests/graphics_verbs.c against the recording backend.
40 PRINT "BEFORE"

View File

@@ -1,5 +1,5 @@
10 REM The standalone driver lends the script no graphics device.
20 REM COLOR, LOCATE and SCALE only touch interpreter state and must still work.
20 REM COLOR, LOCATE and SCALE touch interpreter state and must still work.
30 COLOR 1, 3
40 LOCATE 40, 50
50 SCALE 1, 640, 400

View File

@@ -1,5 +1,5 @@
10 REM Group B: the housekeeping verbs. None of these is in the Go reference --
20 REM they are on its own unimplemented list -- so what each one means here is
10 REM Group B: housekeeping verbs. None is in the Go reference --
20 REM they are on its unimplemented list -- so each meaning here is
30 REM a decision, recorded in src/runtime_housekeeping.c beside the verb.
40 A# = 1 : B# = 2
50 PRINT A# : PRINT B#
@@ -11,7 +11,7 @@
110 P#(2) = 7 : Q#(2) = 9
120 SWAP P#, Q#
130 PRINT P#(2) : PRINT Q#(2)
140 REM TRON prints each line number inline before the line runs, as a C128 does.
140 REM TRON prints each line number inline, as a C128 does.
150 TRON
160 PRINT "TRACED"
170 TROFF

View File

@@ -1,7 +1,7 @@
10 REM A leading zero is padding, not a radix. The reference selects base 8 for
20 REM any lexeme starting with 0, so 010 printed 8 and 08 was a parse error --
30 REM TODO.md section 6 item 10, fixed. Commodore BASIC has no octal literals.
40 REM 0x is the one prefix that changes the base, and it now reaches the scanner
10 REM A leading zero is padding, not a radix. The reference selected base 8
20 REM for lexemes starting with 0; 010 printed 8 and 08 was a parse error --
30 REM TODO.md section 6 item 10 is fixed; Commodore BASIC has no octal.
40 REM 0x is the one prefix that changes the base, and now reaches the scanner
50 REM whole: that was section 6 item 15.
60 PRINT 010
70 PRINT 08

View File

@@ -1,12 +1,12 @@
10 REM A truth value carries its payload in boolvalue, not floatval. The three
20 REM numeric operators were `if ( INTEGER ) ... else <treat as float>`, and
30 REM that else was a catch-all rather than a float branch -- so a truth value
30 REM that else was a catch-all, not a float branch -- so a truth value
40 REM on the LEFT computed 0 - 1 into a field nothing reads, kept its BOOLEAN
50 REM type, and printed `true` instead of -2. Silent, and wrong twice over.
60 A# = 1
70 PRINT (A# == 1)
80 REM On the RIGHT it stays legal and stays -1, which is the same property that
90 REM lets AND and OR double as logical operators. Refusing it here would have
80 REM On the RIGHT it stays legal and stays -1, the same property that
90 REM lets AND and OR act as logical operators. Refusing it would have
100 REM broken every condition in the language.
110 PRINT 5 - (A# == 1)
120 PRINT 5 * (A# == 1)

View File

@@ -1,11 +1,11 @@
10 REM Statements separated by colons. The COLON token existed from the start of
20 REM the port and nothing consumed it, so a line could hold only one statement.
10 REM Statements separated by colons. The COLON token existed from the start;
20 REM nothing consumed it, so a line could hold only one statement.
30 PRINT "A" : PRINT "B"
40 A# = 1 : B# = 2 : PRINT A# + B#
50 REM An empty statement is not an error: a trailing separator, or a run of them.
50 REM Empty statements are valid: a trailing separator or runs of them.
60 PRINT "C" :
70 PRINT "D" :: PRINT "E"
80 REM Everything after THEN belongs to the condition, which is BASIC 7.0 and is
80 REM Everything after THEN belongs to the condition, as in BASIC 7.0, and is
90 REM not something the reference had an opinion about -- it never got here.
100 IF 1 == 1 THEN PRINT "TRUE-1" : PRINT "TRUE-2"
110 IF 1 == 0 THEN PRINT "NEVER-1" : PRINT "NEVER-2"

View File

@@ -1,5 +1,5 @@
10 REM A field name is checked against a closed set the program declared, which
20 REM is the one thing in this language whose valid spellings are written down.
10 REM A field name is checked against the closed set the program declared;
20 REM this is the one thing whose valid spellings are written down.
30 REM A misspelled *variable* is still silent -- see the last two lines.
40 TYPE RECT
50 W#

View File

@@ -17,7 +17,7 @@
170 RETURN B@.W#
180 PRINT WIDEN(A@)
190 PRINT A@.W#
200 REM To change one on purpose, pass a pointer. Assignment copies a pointer's
200 REM To change one on purpose, pass a pointer. Assignment copies its
210 REM reference, so the callee is looking at the caller's own record.
220 DIM Q@ AS PTR TO CRATE
230 POINT Q@ AT A@
@@ -37,7 +37,7 @@
370 N2@.COUNT# = 20
380 POINT N1@.TAIL@ AT N2@
390 DEF TOTAL(P@ AS PTR TO NODE)
395 REM A pointer is true when it points at something, which is how a walk knows
395 REM A pointer is true when it points at something, so a walk knows
396 REM where the list ends. NOT is the bitwise operator here, so the test is
397 REM written the positive way round.
400 IF P@->TAIL@ THEN RETURN P@->COUNT# + TOTAL(P@->TAIL@)

View File

@@ -1,4 +1,4 @@
10 REM A TYPE declares its fields; each takes its own type from its own suffix,
10 REM A TYPE declares its fields; each takes its type from its own suffix,
20 REM which is the same rule every other name in this language follows.
30 TYPE COORD
40 X#

View File

@@ -1,6 +1,6 @@
10 REM A type name and a field name are bare words, and so is every verb, so
20 REM they share a namespace whether we like it or not. Both are refused with
30 REM the same rule the scanner already applies to variable names -- and a type
30 REM the scanner applies the same rule to variable names -- and a type
40 REM name is refused by the prescan, which can say so plainly rather than
50 REM leaving the parser to report "Expected expression or literal".
60 TYPE POINT

View File

@@ -1,6 +1,6 @@
10 REM This shows the waitingForCommand utility in the BasicEnvironment
11 REM when we have a nested for loop. The inner loop SHOULD execute, but
12 REM the outer loop should NOT execute. Therefore, neither loop should execute.
12 REM the outer loop should NOT execute; neither loop should execute.
20 FOR I# = 1 TO 0
25 FOR J# = 2 TO 4
30 PRINT "waitingForCommand FAILS if this is seen"
@@ -8,4 +8,4 @@
35 NEXT J#
40 NEXT I#
50 PRINT "SUCCESS"
80 QUIT
80 QUIT

View File

@@ -1,6 +1,6 @@
10 PRINT MOD(10, 3)
20 PRINT MOD(12, 5)
30 PRINT MOD(4, 2)
40 REM MOD() ONLY WORKS WITH INTEGERS - RESULTS WITH FLOATING POINT ARE UNRELIABLE
40 REM MOD() ONLY WORKS WITH INTEGERS; FLOATING POINT RESULTS ARE UNRELIABLE
50 REM PRINT MOD(1.2, 0.4)
60 REM THERE IS NO ERROR THROWN HERE. JUST DONT DO IT.