Some fixes for BINSIC


I have made a few small, but important, fixes to BINSIC, the reimplementation of BASIC I have built using Groovy.

You can download the jar file (which can be run in any standard Java environment) from here: http://88.198.44.150/binsic.jar

Here’s another BASIC “game” (it’s amazing that this sort of thing used to fascinate those of us with these machines), for you to try – it was fixing this up that helped me find the bugs:

10 REM **DICE GAME**SLR/1983**
20 LET A=0
30 LET B=0
40 PRINT "DICE GAME"
60 PRINT "YOUR THROW="
70 GOSUB 160
80 PRINT "MY THROW="
90 GOSUB 220
100 IF A>B THEN PRINT "YOU WIN"
110 IF A<B THEN PRINT "I WIN"
120 IF A = B THEN PRINT "TIE"
130 LET X$ = INKEY$
132 IF X$ = "" THEN GOTO 130
136 CLS
140 IF X$ = "S" THEN STOP
150 GOTO 10
160 FOR G=1 TO 2
170 LET Z=INT (RND*6+1)
180 LET A=A+Z
190 GOSUB 280
195 PRINT
200 NEXT G
210 RETURN
220 FOR G=1 TO 2
230 LET Z=INT (RND*6+1)
240 LET B=B+Z
250 GOSUB 280
260 NEXT G
270 RETURN
280 REM Draw
282 PAUSE 100
285 IF Z = 1 THEN GOSUB 500
290 IF Z = 2 THEN GOSUB 600
300 IF Z = 3 THEN GOSUB 700
310 IF Z = 4 THEN GOSUB 800
320 IF Z = 5 THEN GOSUB 900
330 IF Z = 6 THEN GOSUB 1000
340 RETURN
400 PRINT "[ ][ ][ ]"
410 RETURN
420 PRINT "[*][ ][*]"
430 RETURN
440 PRINT "[ ][*][ ]"
450 RETURN
460 PRINT "[*][ ][ ]"
470 RETURN
480 PRINT "[ ][ ][*]"
490 RETURN
500 REM 1
510 GOSUB 400
520 GOSUB 440
530 GOSUB 400
540 RETURN
600 REM 2
610 GOSUB 460
620 GOSUB 400
630 GOSUB 480
640 RETURN
700 REM 3
710 GOSUB 460
720 GOSUB 440
730 GOSUB 480
740 RETURN
800 REM 4
810 GOSUB 420
820 GOSUB 400
830 GOSUB 420
840 RETURN
900 REM 5
910 GOSUB 420
920 GOSUB 440
930 GOSUB 420
940 RETURN
1000 REM 6
1010 GOSUB 420
1020 GOSUB 420
1030 GOSUB 420
1040 RETURN

The original game can be found here: http://zx81.reids4fun.com/zx81/dice/dice_list.html – I had to change it to cope with the main weakness of BINSIC – that GOTOs to lines inside loops fail.

Progress with BINSIC


BINSIC – Binsic Is Not Sinclair Instruction Code – my effort to re-implement Sinclair ZX80/ZX81 BASIC as a domain specific language via Groovy (and eventually a runnable Java JAR file), is making more progress.

ZX80 + bubble TV = modernist bliss (p1120918)
ZX80 + bubble TV = modernist bliss (p1120918) (Photo credit: acb)

Right now it supports:

IF ... THEN ... ELSE
GOTO
GOSUB ... RETURN
LET
FOR ... TO ... STEP ... NEXT
DIM A(x, y, z) (and array derefencing)
CLS
PRINT

Still one or two difficult areas to get through and I have had to make one compromise – unlike on the ZX80 one cannot have a variable and an array with the same letter designation – just too difficult to implement on Java/Groovy.

But, it’s getting there…

Just like 1980


The Sinclair ZX80 (1980). It was the immediate...
The Sinclair ZX80 (1980). It was the immediate predecessor of the ZX81 and shared many of the same design features. (Photo credit: Wikipedia)

There have been (conservatively) 16 “Moore generations” since 1980 – that is to say computing speed should have increased by 2^{16} – approximately 4 million times.

But computation requirements grow to fill the computing power available and BINSIC now runs at about the same speed, when executing the same code, as my ZX80 did when hacking its way through BASIC programs 32 years ago.

It’s a strange sight to see, because it is so evocative of that period.

The code runs slowly largely, I think, because of the way that I have chosen to handle GOTO statements (not that I could think of any other way) – essentially the whole or at least a substantial part, of the program is reparsed every time a GOTO is issued.

Anyway, it adds to the sense of realism!

Line numbers problem solved, after a fashion


I am currently working on BINSIC – Binsic Is Not Sinclair Instruction Code – a reimplementation of ZX80/ZX81 BASIC in the form of a “domain specific language” coded in Groovy.

basic coding
basic coding (Photo credit: Terry Freedman)

The biggest problem so far has been the issue of GOTOs and line numbers. BASIC, at least classic BASIC, relied on line numbers and GOTO commands (and the related GOSUB) to control the order of statement execution – a simple, endless, Fibonacci sequence generating example is below (unfortunately wordpress.com does not appear to offer support for BASIC code listings):

10 REM Fibonacci sequence
20 LET x = 0
30 LET y = 1
40 LET i = 0
50 PRINT “Iteration “, i, ” value is “, x
60 LET temp = x
70 LET x = y
80 LET y = y + temp
90 LET i = i + 1
100 GOTO 50

But such code constructs are completely alien to Java/Groovy. Indeed the point of ‘object orientation’, as with procedural coding before it, is often said to be the removal of the GOTO: “Goto considered harmful” as one famous paper put it.

But there may be a solution: Stripping off the line numbers is the easy bit – and line numbers can then be mapped, using the map class, to lines in the file. Then the file can be reprised from the mapped in line number – in this case that means when the code got to the line numbered 100 (line 9 in computer-scientists-start-from-zero form) the code can be reprised from line 4 (i.e. the line numbered 50).

This actually works, and was not too difficult to implement: but there is a problem. The call to line 50 works like a form of recursion, creating a stack entry and awaiting further execution i.e. we pile uncompleted scripts one on top of the other after every GOTO.

A simpler piece of code might make this plainer

10 PRINT “Hello World”
20 GOTO 40
30 PRINT “Should never get here.”
40 PRINT “Finishing.”

This should generate the output:
“Hello World”
“Finishing”

But, instead, without outside intervention, would give me:

“Hello World”
“Finishing”
“Should never get here”
“Finishing”

– as once the first path of execution gets to line 40, the stacked up code is then called.

The answer is to halt or pause execution when the code returns from the GOTO. But I cannot kill the thread of execution as then the output window would also disappear. Instead I just pause it waiting for some form of input:

def getTo(def lineNo)
{binsicEngine.getTo(lineNo)
       System.in.withReader { println (it.readLine()) }
}

It’s a long way from pretty, but it works: the Fibonacci sequence generator above runs into problems with MAX_INT before it crashes due to running out of stack space, for instance. But I hope I can find a better solution.

Struggling with line number problem


Having line numbers is pretty much essential for BASIC. This, and its half-brother FORTRAN were, after all, the inspiration for Djikstra’s “Goto considered harmful” – GOTO and the (later addition) GOSUBwere what we used before we had procedures and functions, never mind classes and methods.

Punch card from a typical Fortran program.
Punch card from a typical Fortran program. (Photo credit: Wikipedia)

But Java (and hence Groovy) has no support for goto statements (it is a reserved word in the language though – but presumably to stop someone actually implementing it.) And labelling support, which might offer an alternative, is absolutely minimal and inflexible.

I thought about parsing the BASIC file line by line – code lines could be in an array and a GOTO interpreted as a signal to process the array for a different starting point. But that is not easy – each line is treated as a stand alone script if that way is chosen and so I would have to set up the environment every time (or, maybe, I could get round that with the binding – I will have to explore that).

There is a Scala BASIC DSL that I could study further, but I don’t know any Scala (beyond its apparent C/C++/Java heritage) – but it seems to process the input line by line, certainly it seems to have a line class.

Subroutines ought to be a bit easier – they can be closures I suspect.