David Hembrow noted on Mastodon that you can do some very odd things in Sinclair BASIC with code “hidden” after a REM statement:
10 LET three=3
20 FOR f=1 TO 0
30 REM hello again: NEXT f: FOR g=SGN f TO three: PRINT g: NEXT g: PRINT "woops": INPUT
40 NEXT g
50 PRINT f
60 NEXT f
Entering a colon in a REM statement will put you in command entry mode, except not quite enough to parse constants correctly. Hence the need for SGN f TO three to make the loop in the REM statement run.
This will run on a ZX Spectrum 128 if you load it from tape, but not if you enter it from the keyboard in 128 mode. It won’t work at all on a ZX81 as multiple BASIC commands on a line aren’t allowed.
That half-baked state of the tokeniser is quite special.
As to whether it’s expected or not to see a NEXT that’s behind a REM, that very much depends on where your expectations come from!
In BBC Basic, DATA is a token which needs to be scanned for, and it has to be the first token on the line. Similarly, DEF. And in both cases, they also act like REM in that the rest of the line is skipped at execution time. One way to look at that picture is that the program is line-oriented, even though it allows for multi statement lines.
I’m unfamiliar with the ZX Spectrum, so had to do some looking to find out that the error message is not a language war commentary. ‘C’ is an error code that happens to mean a statement wasn’t valid BASIC code.
It’s slightly half-baked, but if you watch the cursor while entering a line of BASIC, it starts in Keywords mode, goes into Letters mode after REM, and goes back into Keywords mode after you type a colon in the same line:
It’s trying to do a lot with a little code, and always switching to Keywords after a colon makes some sense. It also helps to explain why some keywords (such as TO) are entered like punctuation: they force the parser out of Letters mode and back into Keywords mode.
The Mastodon link gave a 404.
I haven’t worked with a Sinclair for years.
Not sure if “LET three=3” works or if three results just in a “t”
Or F=1 needs a space.
The output: Nonsense in BASIC.. is also not standard.
Yes, sorry about that. Seems my friend keeps their feed private.
LET three=3 defines the variable named ‘three’ with value 3. Code after a REM statement doesn’t tokenize constants, so you have to use workarounds like SGN f for 1 and the variable three.
BASIC doesn’t define standard error messages. Sinclair’s ones are unusual, but likely encoded to be small. Better than the two letter codes from PDP-8 BASIC.
Could one have used INT PI instead of the intermediate variable ‘three’?
Not quite on topic, in this multi-part article on Efficient Basic Coding (which is specifically about ZX Basic) I see something most unexpected:
Another special case of expression with numeric values occurs when we wish to increment a variable cyclically , that is, to assign increasing values from 1 to n and then to 1 again. This can be done without IF in this way: LET v = v + 1 OR v = n
Not sure where I’ve explored this before, but I remembered I’d previously thought about using conditional NEXT statements. I’d hoped it could be faster than GOTO - not sure I ever tested that. But they do allow conditional jumps without executing GOTO each time. Here’s a test I did today. I can use conditional NEXT to restart the current loop or jump into another loop.
I hadn’t worked out if conditional FOR could be useful - maybe you have “FOR x” in two places, and whichever had been executed would be jumped to when you do “NEXT x” - but I haven’t tested it.
I had a brainwave and came to understand something I’ve seen once or twice done in BBC Basic - the deliberate use of a non-anonymous NEXT to act as a break:
PROCstopat3
PRINT ;"stopped at "N
END
DEFPROCstopat3
FOR I=1 TO 0
FOR N=1 TO 10
IF N=3 THEN NEXT I:ENDPROC
PRINT N
NEXT
NEXT
ENDPROC
Without something like this, we need to set the loop variable to something which will exit and then do NEXT, which is a bit clunky:
IF N=3 THEN N=11:NEXT:ENDPROC
This idiom as written does rely on FOR I running at least once, but it also works with