5

I have a subroutine with a for/next loop in Extended Color BASIC on the TRS-80 Color Computer that I would like, sometimes, to return early from. That is, to return from the subroutine from within the for/next loop and before the for/next loop is completed.

My question is, what effect does exiting a FOR/NEXT loop early have on the TRS-80 Color Computer in Extended Color BASIC?

I thought that exiting from a for/next loop early is bad because it leaves a FOR on a stack, and eventually that stack will fill up if the loops aren’t allowed to complete.

My first experiment was:

1 REM TEST FOR/NEXT WITH RETURN
10 PRINT "HELLO"
20 GOSUB 100
30 PRINT "FINISHED", MEM
40 NEXT I
99 END
100 FOR I=1 TO 20
110 IF I>10 THEN RETURN
120 PRINT I,
130 NEXT I

The NEXT I on line 40 generates an NF error. That is, Next without For. Thinking that perhaps the For/Next stack was cleared on a RETURN to the point it was at the time of the GOSUB, I tried another experiment using nothing but GOTO to exit the loop:

10 CLS
20 FOR I=1 TO 3
30 FOR J=1 TO 3
40 FOR K=1 TO 3
50 PRINT@128,L,MEM
60 GOTO 80
70 END
80 L=L+1
90 GOTO 20

I let this run all night in XRoar; L reached 766750 and the program was still running in the morning. (MEM didn’t change from the second iteration on to the end.)

For/Next break experiment

What are the effects of exiting a For/Next loop early in Extended Color BASIC? How can I see these effects in a program? And, what, if any, are the side effects of returning from a subroutine from inside an unfinished For/Next loop?

  • Can you not just use GOTO to exit a loop, then RETURN from your sub-routine in the target of the GOTO? – Brian H May 9 at 15:16
  • That would still be exiting the FOR/NEXT without completing it, wouldn’t it? That’s what my first test code is doing. What I don’t understand is why that doesn’t appear to leave anything on the FOR/NEXT stack. – Jerry Stratton May 9 at 16:07
  • Though I know nothing about the TRS-80, ir would surely be a remarkably defective implementation of BASIC that did not let you break out of a loop by GOTO. This 1964 description of Dartmouth BASIC - the mother of all BASICs - shows an example doing just that (page 22 but note it's part of a debugging example). – another-dave May 9 at 16:42
  • Actually I'm surprised the first example did not complain prior to execution that line 40 cannot possibly match any FOR. FOR/NEXT pairing has to be statically determined -- even a FOR loop that executes 0 times needs to know where its NEXT is, so it can immediately jump to the line after. – another-dave May 9 at 16:45
  • 1
    @another-dave It would be pretty sophisticated for a BASIC to statically determine "next without for". For a start, it would imply a compilation phase. Secondly, a programmer could write a goto that jumps into the middle of the loop, or write a goto that jumps to a FOR defined elsewhere and then jumps back in front of the Next. – JeremyP May 11 at 8:15
7

The BASIC in question (and many Microsoft BASIC versions) use a single stack to track both FOR/NEXT loops and GOSUBs. Here's a first approximation of the rules:

  • FOR x puts a loop record on the stack
  • GOSUB puts a return location on the stack
  • RETURN pops down the stack and goes back to the return location
  • NEXT x pops down the stack to find the loop record for x and continues or exits the loop based on the counters
  • NEXT continues or exits the loop at the top of the stack

These rules have some implications which you've noticed. A RETURN will end any FOR loops in progress as it searches for a location record. NEXT x will end other FOR loops in progress searching for the x loop. However, it won't look past a location record.

In addition, FOR x will look down the stack for an existing x loop and replace it thus ending and nested FOR loops below it. But it won't look past location records.

Whenever a RETURN can't find a location record you get the ?RG return without gosub error. And similarly if NEXT can't find a loop record you get the ?NF next without for error.

The main thing to remember is that FOR x, NEXT x and GOSUB can end FOR loops in operation but limit their scope to the current subroutine.

| improve this answer | |
2

I can't speak on the inner workings of this BASIC. But perhaps you can force the for/next to end "naturally" by manipulating i directly. I don't have a CoCo to test this on, but something like:

100 FOR I=1 TO 20
110 REM IF I>10 THEN RETURN
120 PRINT I,
125 IF I>9 THEN I=20
130 NEXT I
140 RETURN

BASICally you set up the comparison at line 100 to flag completion. I don't see that this would have any side effects. The FOR loop completes, and the subroutine has only one exit point.

| improve this answer | |
  • That’s the sort of thing I was thinking about doing. But if it isn’t necessary, why do it? That’s my question: what are the side effects of not doing it that way? I tried very hard to get an error by exiting in what I thought was the incorrect manner, and the only error I got—next without for—indicates that I don’t need to do anything special to exit a for/next loop “incorrectly”. Which goes against what I remember from the day. – Jerry Stratton May 9 at 16:47
  • 1
    That was the usual way to avoide complications without knowing the interpreter. It not only keeps the little 'structured' programming BASIC got intact, but as well offers a way to transmit abort codes by setting I to values higher den the regular last iteration. So here it may end with I=20 when all iterations were successful, and values above 20 for various kind of abort reasons. – Raffzahn May 9 at 16:53
  • @JerryStratton I studied programming before "object-oriented" was a thing. In my day, structured programming was the way. One of its tenets is that subroutines and other control structures should always have exactly one entry and one exit. (This was effectively mellowed a bit, as exemplified by the break keyword in C.) Is it necessary? No. But it is a means of minimizing possible side effects by designing up-front with a little discipline. – RichF May 9 at 17:03
  • This is quite dependent on the interpreter. In the ANSI/ECMA standard, you can't change the index variable. In others, obviously, you can. – scruss May 10 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.