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?

8
  • 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, 2020 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. May 9, 2020 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). May 9, 2020 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. May 9, 2020 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, 2020 at 8:15

2 Answers 2

8

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.

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.

4
  • 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. May 9, 2020 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, 2020 at 16:53
  • 1
    @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, 2020 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, 2020 at 13:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .