Chapter Nine

Program Flow Control Statements

Execution Control always processes the statement in the Statement Table that follows the one it thinks it has just finished. This means that statements in a BASIC program are usually processed in sequential order. Several statements, however, can change that order: GOTO, IF, TRAP, FOR, NEXT, GOSUB, RETURN, POP, and ON. They trick Execution Control by changing the parameters that it maintains. Simple Flow Control Statements XGOTO ($BGA3) The simplest form of flow control transfer is the GOTO statement, simulated by the XGOTO routine. Following the GOTO token in the tokenized line is an expression representing the line number of the statement that the user wishes to execute next. The first thing the XGOTO routine does is ask Execute Expression to evaluate the expression and convert it to a positive integer. XGOTO then calls the GETSTMT routine to find this line number in the Statement Table and change Execution Control's line parameters to indicate this line. If the line number does not exist, XGOTO restores the line parameters to indicate the line containing the original GOTO, and transfers to the Error Handling Routine via the ERNOLN entry point. The Error Handling Routine processes the error and jumps to the start of the editor. If the line number was found, XGOTO jumps to the beginning of Execution Control (EXECNL) rather than returning to the point in the routine from which it was called. This leaves garbage on the 6502 CPU stack, so XGOTO first pulls the return address off the stack. 75


Chapter Nine XIF($8778) The IF statement changes the statement flow based on a condition. The simulatiQn routine, xw, begins by calling a subroutine of Execute Expressionto evaluate the condition. Since this is a logical (rather than an arithmetic) operation, we are only interested in whether the value is zero or non-zero. If the expression was false (non-zero), XIF modifies Execution Control's line parameters to indicate the end of this line and then returns. Execution Control moves to the next line, skipping any remaining statements on the original IF statement line. If the expression is true (zero), things get a little more complicated. Back during syntaxing, when a statement of the form IF <expression> THEN <statement> was encountered, the pre-compiler generated an end-of-statement token after THEN. XIF now tests for this token. If we are at the end of the statement, XIF returns to Execution Control, which processes what it thinks is the next statement in the current line, but which is actually the THEN <statement> part of the IF statement. If XIF does not find the end-of-statement token, then the statement must have had the form IF <expression> THEN <line number>. XIF jumps to XGOTO, which finishes processing by changing Execution Control's line parameters to indicate the new line. XTRAP ($B7E1) The TRAP statement does not actually change the program flow when it is executed. Instead, the XTRAP simulation routine calls a subroutine of Execute Expression to evaluate the line number and then saves the result in TRAPLN ($BC). The program flow is changed only if there is an error. The Error Handling Routine checks TRAPLN. If it contains a valid line number, the error routine does some initial set-up and joins the XGOTO routine to transfer to the new line. Runtime Stack Routines The rest of the Program Flow Control Statements use the Runtime Stack. They put items on the stack, inspect them, and/or remove them from the stack. Every item on the Runtime Stack contains a four-byte header. This header consists of a one-byte type indication, a 76
Chapter Nine two-byte line number, and a one-byte displacement to the Statement Name Token. (See pages 18-19.) The type byte is the last byte placed on the stack for each entry. This means that the pointer to the top of the Runtime Stack (RUNSTK) points to the type byte of the most recent entry on the stack. A zero type byte indicates a GOSUB-type entry. Any non-zero type byte represents a FOR-type entry A GOSUB entry consists solely of the four-byte header. A FOR entry contains twelve additional bytes: a six-byte limit value and a six-byte step value. Several routines are used by more than one of the statement simulation routines. PSHRSTK ($B683) This routine expands the Runtime Stack by calling EXPLOW and then storing the type byte, line number, and displacement of the Statement Name Token on the stack. POPRSTK ($B841) This routine makes sure there really is an entry on the Runtime Stack. POPRSTK saves the displacement to the statement name token in SVI)ISP, saves the line number in TSLNUM, and puts the type/variable number in the 6502 accumulator. It then removes the entry by calling the CONTLOW routine. :GETTOK ($B737) This routine first sets up Execution Control's line parameters to point to the line whose number is in the entry just pulled from the Runtime Stack. If the line was found, : GETTOK updates the line parameters to indicate that the statement causing this entry is now the current statement. Finally, it loads the 6502 accumulator with the statement name token from the statement that created this entry and returns to its caller. If the line number does not exist, : GETTOK restores the current statement address and exits via the ERGFDEL entry point in the Error Handling Routine. Now let's look at the simulation routines for the statements that utilize the Runtime Stack. XFOR ($B64B) XFOR is the name of the simulation routine which executes a FOR statement. In the statement FOR 1=1 TO 10 STEP 2: I is the loop control variable 77
Chapter Nine 1 is its initial value 10 is the limit value 2 is the step value XFOR calls Execute Expression, which evaluates the initial value and puts it in the loop control variable's entry in the Variable Value Table. Then it calls a routine to remove any currently unwanted stack entries for example, a previous FOR statement that used the same loop control variable as this one. XFOR calls a subroutine of Execute Expression to evaluate the limit and step values. If no step value was given, a value of 1 is assigned. It expands the Runtime Stack using EXPLOW and puts the values on the stack. XFOR uses PSHRSTK to put the header entry on the stack. It uses the variable number ofthe loop control variable (machine-language ORed with $80) as the type byte. XFOR now returns to Execution Control, which processes the statement following the FOR statement. The FOR statement does not change program flow. It just sets up an entry on the Runtime Stack so that the NEXT statement can change the flow. XNEXT ($B6CF) The XNEXT routine decides whether to alter the program flow, depending on the top Runtime Stack entry. XNEXT calls the POPRSTK routine repeatedly to remove four-byte header entries from the top of the stack until an entry is found whose variable number (type) matches the NEXT statement's variable token. If the top-of-stack or GOSUB-type entry is encountered, XNEXT transfers control to an Error Handling Routine via the ERNOFOR entry point. To compute the new value of the loop variable, XNEXT calls a subroutine of Execute Expression to retrieve the loop control variable's current value from the Variable Value Table, then gets the step value from the Runtime Stack, and finally adds the step value to the variable value. XNEXT again calls an Execute Expression subroutine to update the variable's value in the Variable Value Table. XNEXT gets the limit value from the stack to determine if the variable's value is at or past the limit. If so, XNEXT returns to Execution Control without changing the program flow, and the next sequential statement is processed. 78
Chapter Nine If the variable's value has not reached the limit, XNEXT returns the entry to the Runtime Stack and changes the program flow. POPRSTK already saved the line number of the FOR statement in TSLNUM and the displacement to the statement name token in SVDISP. XNEXT calls the GETTOK routine to indicate the FOR statement as the current statement. If the token at the saved displacement is not a FOR statement name token, then the Error Handling Routine is given control at the ERGFDEL entry point. Otherwise, XNEXT returns to Execution Control, which starts processing with the statement following the FOR statement. XGOSUB ($BGA0) The GOSUB statement causes an entry to be made on the Runtime Stack and also changes program flow. The XGOSUB routine puts the GOSUB type indicator (zero) into the 6502 accumulator and calls PSHRSTK to put a four-byte header entry on the Runtime Stack for later use by the simulation routine for RETURN. XGOSUB then processes exactly like XGOTO. XRTN ($B719) The RETURN statement causes an entry to be removed from the Runtime Stack. The XRTN routine uses the information in this entry to determine what statement should be processed next. The XRTN first calls POPRSTK to remove a GOSUB-type entry from the Runtime Stack. If there are no GOSUB entries on the stack, then the Error Handling Routine is called at ERBRTN. Otherwise, XRTN calls GETTOK to indicate that the statement which created the Runtime Stack entry is now the current statement. If the statement name token at the saved displacement is not the correct type, then XRTN exits via the Error Handling Routine's ERGFDEL entry point. Otherwise, control is returned to the caller. When Execution Control was the caller, then GOSUB must have created the stack entry, and processing will start at the statement following the GOSUB. Several other statements put a GOSUB-type entry on the stack when they need to mark their place in the program. They do not affect program flow and will be discussed in later chapters. 79
Chapter Nine XPOP ($B841) The XPOP routine uses POPRSTK to remove an entry from the Runtime Stack. A user might want to do this il he decided not to RETURN from a GOSUB. XON ($B7ED) The ON statement comes in two versions: ON-GOTO and ON— GOSUB. Only ON-GOSUB uses the Runtime Stack. The XON routine evaluates the variable and converts it to an integer (MOD 256). If the value is zero, XON returns to Execution Control without changing the program flow. If the value is non-zero and this is an ON-GOSUB statement, XON puts a GOSUB-type entry on the Runtime Stack for RETURN to use later. From this point, ON-GOSUB and ON-GOTO perform in exactly the same manner. XON uses the integer value calculated earlier to index into the tokenized statement line to the correct GOTO or GOSUB line number. If there is no line number corresponding to the index, XON returns to Execution Control without changing program flow. Otherwise, XON joins XGOTO to finish processing. 80

<-Chapter 08Chapter 10->