Navigation Early exits from FOR-NEXT loops

From C64-Wiki
Jump to navigationJump to search

C64 BASIC permits both changing the loop-variable and using GOTO to jump out of a FOR-NEXT loop early. However, doing the latter creates a potential problem.

When a program encounters a FOR statement, BASIC pushes certain information about the loop onto the C64 return stack which is used by the NEXT statement (the FOR-NEXT stack frame). This information includes the loop variable, step size and where in the program the FOR was encountered. When FOR-NEXT finishes normally, this information is removed from the stack.

However, if the loop was exited early then the information remains on the return stack. Too many unfinished FOR-NEXT loops will then result in an ?OUT OF MEMORY ERROR. A depth of 10 nested loops can be achieved at best (fit on the return stack), but depending on the stack usage before and after the practical limit is 9 or even less if some arithmetic expression evaluation are expected to be still possible. Because of the way that C64 BASIC handles FOR-NEXT information on the return stack, puzzling behavior may arise.

C64 BASIC deals with information about FOR-NEXT loops on the return stack in one of four ways:

  1. When the FOR-NEXT loop terminates normally, the information is removed from the return stack.
  2. When a program encounters a NEXT statement with an explicit loop variable, all inner loops are cancelled and their information removed from the return stack.
  3. All FOR-NEXT loops commenced within a subroutine are terminated and their information removed from the return stack when the program encounters a RETURN statement.
  4. If a FOR statement is encountered, any existing loop using the same variable name along with any subsequent unfinished FOR-NEXT loops are terminated and their information removed from the return stack.

The fourth rule usually prevents the ?OUT OF MEMORY ERROR since loop variables tend to be reused in programs. However, sometimes an inner loop gets terminated when the programmer didn't want it to be resulting in the ?NEXT WITHOUT FOR ERROR. Because of rule 2, this will also happen if the NEXT statements are accidentally transposed in nested loops.

A statement like

100 FOR I=1 TO 1:NEXT I

can be used to force the termination of a loop with loop variable I (inclusive all nested loops) that was exited early.[1]