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.

2 thoughts on “Line numbers problem solved, after a fashion

Comments are closed.