# Compaq BASIC for OpenVMS
Alpha and VAX Systems
User Manual

Previous | Contents | Index

# Chapter 10
Program Control

BASIC normally executes statements sequentially. Control statements let you change this sequence of execution. BASIC control statements can alter the sequence of program execution at several levels:

- Statement modifiers control the execution of a single statement.
- Loops or decision blocks control the execution of a block of statements.
- Branching statements such as GOTO and ON GOTO pass control to statements or local subroutines.
- The EXIT and ITERATE statements explicitly control loops or decision blocks.
- The SLEEP, WAIT, STOP and END control statements suspend or halt the execution of your entire program.

This chapter describes the BASIC control statements.

# 10.1 Statement Modifiers

Statement modifiers are control structures that operate on a single statement. Statement modifiers let you execute a statement conditionally or create a loop. The following are BASIC statement modifiers:

> IF
> UNLESS
> FOR
> UNTIL
> WHILE

A statement modifier affects only the statement immediately preceding it. You can modify only executable statements; declarative statements cannot be modified.

## 10.1.1 IF Modifier

The IF modifier tests a conditional expression. If the conditional expression is true, BASIC executes the statement. If it is false, BASIC does not execute the modified statement but continues execution at the next program statement. The following is an example of a statement using the IF modifier:

    PRINT A IF (A < 5)

## 10.1.2 UNLESS Modifier

The UNLESS modifier tests a conditional expression. BASIC executes the modified statement only if the conditional expression is false.

    PRINT A UNLESS (A < 5)

This is equivalent to the following:

    PRINT A IF A >= 5

## 10.1.3 FOR Modifier

The FOR modifier creates a loop on a single line. The following is an example of a loop created using the FOR modifier:

    A = A + 1 FOR I% = 1% TO 10%

## 10.1.4 UNTIL Modifier

The UNTIL modifier, like the FOR modifier, creates a single-line loop. However, instead of using a formal loop variable, you specify the terminating condition with a conditional expression. The modified statement executes repeatedly as long as the condition is false. For example:

    B = B + 1 UNTIL (A  - B) < 0.0001

## 10.1.5 WHILE Modifier

The WHILE modifier repeats a statement as long as a conditional expression is true. Like the UNTIL and FOR modifiers, the WHILE modifier lets you create single-line loops. In the following example, BASIC replaces the value of A with A/2, as long as the absolute value of A is greater than one-tenth. Note that you can inadvertently create an infinite loop if the terminating condition is never reached.

    A = A / 2 WHILE ABS(A) > 0.1

## 10.1.6 Nesting Modifiers

If you append more than one modifier to a statement, you are nesting modifiers. BASIC evaluates nested modifiers from right to left. If the test of the rightmost modifier fails, control passes to the next statement, not to the preceding modifier on the same line.

In the following example, BASIC first tests the rightmost modifier of the first PRINT statement. Because this condition is false, BASIC executes the following PRINT statement and tests the rightmost modifier. Because this condition is met, BASIC tests the leftmost modifier of the same PRINT statement. This condition, however, is not met. Therefore, BASIC executes the following PRINT statement. Because both conditions are met in the third PRINT statement, BASIC prints the value of C.

    A = 5
    B = 10
    C = 15

    PRINT "A =";A IF A = 5 UNLESS C = 15
    PRINT "B =";B UNLESS C = 15 IF B = 10
    PRINT "C =";C IF B = 10 UNLESS C = 5
    END

Output

    C = 15

# 10.2 Loops

Loops allow you to repeat the execution of a set of statements. This set of statements is called a loop block. There are three types of BASIC program loops:

> FOR...NEXT
> WHILE...NEXT
> UNTIL...NEXT

Note that these types of loops can be nested, that is, lexically located one inside another.

## 10.2.1 FOR...NEXT Loops

In a FOR...NEXT loop, you specify a loop control variable (the loop index) that determines the number of loop iterations. This number must be a scalar (unsubscripted) variable. When BASIC begins execution of a FOR...NEXT loop, the starting and ending values of the loop control variable are known.

The FOR statement assigns the control variable a starting value and an ending value. You can use the optional STEP clause to specify the amount to be added to the loop control variable after each loop iteration.

When a FOR loop block executes, the BASIC compiler performs the following steps:

1. Evaluates the starting value and assigns it to the control variable.
2. Evaluates the ending value and the step value and assigns these results to temporary storage locations.
3. Tests whether the ending value has been exceeded. If the ending value has already been exceeded, BASIC executes the statement following the NEXT statement. If the ending value has not been exceeded, BASIC executes the statements in the loop.
4. Adds the step value to the control variable and transfers control to the FOR statement, which tests whether the ending value has been exceeded. Steps 3 and 4 are repeated until the ending value is exceeded.

Note that BASIC performs the test before the loop executes. When the control variable exceeds the ending value, BASIC exits the loop, and then subtracts the step value from the control variable. This means that after loop execution, the value of the control variable is the value last used in the loop, not the value that caused loop termination.

Example 10-1 assigns the values 1 to 10 to consecutive array elements 1 to 10 of New_array, and Example 10-2 assigns consecutive multiples of 2 to the odd-numbered elements of New_array.

Example 10-1 Assigning Values to Consecutive Array Elements

    FOR I% = 1% TO 10%
        New_array(I%) = I%
    NEXT I%

Example 10-2 Assigning Consecutive Multiples to Odd-Numbered Elements of Array

    FOR I% = 1% TO 10% STEP 2
        New_array(I%) = I% + 1%
    NEXT I%

Note that the starting, ending, and step values can be run-time expressions. You can have BASIC calculate these values when the program runs, as opposed to using a constant value. For instance, the following example assigns sales information to array Sales_data. The number of iterations depends on the value of the variable Days_in_month, which represents the number of days in that particular month.

    FOR I% = 1% TO Days_in_month
        Sales_data(I%) = Quantity_sold
    NEXT I%

Because the starting, ending, and step values can be numeric expressions, they are not evaluated until the program runs. This means that you can have a FOR...NEXT loop that does not execute. The following example prompts the user for the starting, ending, and step values for a loop, and then tries to execute that loop. The loop executes zero times because it is impossible to go from 0 to 5 using a step value of -1.

    counter% = 0%

    INPUT "Start"; start%
    INPUT "Finish"; finish%
    INPUT "Step value"; step_val%

    FOR I% = start% TO finish% STEP step_val%
        counter% = counter% + 1%
    NEXT I%

    PRINT "This loop executed"; counter%; "times."

Output

    Start? 0
    Finish? 5
    Step value? -1
    This loop executed 0 times.

Whenever possible, you should use integer variables to control the execution of FOR...NEXT loops because some decimal fractions cannot be represented exactly in a binary computer, and the calculation of floating-point control variables is subject to this inherent imprecision.

In the following example, the first loop uses an integer control variable while the second uses a floating-point control variable. The first loop executes 100 times and the second 99 times. After the ninety-ninth iteration of the second loop, the internal representation of the value of Floating_point_variable exceeds 10 and BASIC exits the loop. Because the first loop uses integer values to control execution, BASIC does not exit the loop until Integer_variable equals 100.

    Loop_count_1 = 0%
    Loop_count_2 = 0%

    FOR Integer_variable = 1% to 100% STEP 1%
        Loop_count_1 = Loop_count_1 + 1%
    NEXT Integer_variable

    FOR Floating_point_variable = 0.1 to 10 STEP 0.1
        Loop_count_2 = Loop_count_2 + 1%
    NEXT Floating_point_variable

    PRINT "Integer loop count:"; Loop_count_1
    PRINT "Integer loop end  :"; Integer_variable
    PRINT "Real loop count:   "; Loop_count_2
    PRINT "Real loop end:     "; Floating_point_variable

Output

    Integer loop count:  100
    Integer loop end:    100
    Real loop count:     99
    Real loop end:       9.9

Although it is not recommended programming practice, you can assign a value to a FOR...NEXT loop's control variable while in the loop. This affects the number of times a loop executes. For example, assigning a value that exceeds the ending value of a loop will cause the loop's execution to end as soon as BASIC performs the termination test in the FOR statement. Assigning values to ending or step variables, however, has no effect at all on the loop's execution.

## 10.2.2 WHILE...NEXT Loops

A WHILE...NEXT statement uses a conditional expression to control loop execution; the loop is executed as long as a given condition is true. A WHILE...NEXT loop is useful when you do not know how many loop iterations are required.

In the following example, the first statement instructs the user to input data and then type DONE when finished. After the user enters the first piece of input, BASIC executes the WHILE...NEXT loop. If the first input value is not "DONE", the loop executes and prompts the user for another input value. Once the user enters this input value, the WHILE...NEXT loop once again checks to see if this value corresponds to "DONE". The loop will continue executing until the user types "DONE" in response to the prompt.

    INPUT 'Type "DONE" when finished'; Answer

    WHILE (Answer <> "DONE")
       .
       .
       .
          INPUT "More data"; Answer
    NEXT

Note that the NEXT statement in the WHILE...NEXT and UNTIL...NEXT loops does not increment a control variable; your program must change a variable in the conditional expression or the loop will execute indefinitely.

The evaluation of the conditional expression determines whether the loop executes. The test is performed (that is, the conditional expression is evaluated) before the first iteration; if the value is false (0), the loop does not execute.

It can be useful to intentionally create an infinite loop by coding a WHILE...NEXT loop whose conditional expression is always true. When doing this you must take care to provide a way out of the loop. You can do this with an EXIT statement or by trapping a run-time error. See Chapter 16 for more information about trapping run-time errors.

## 10.2.3 UNTIL...NEXT Loops

The UNTIL...NEXT loop performs like a WHILE...NEXT loop, except that the logical sense of the conditional expression is reversed; that is, the UNTIL...NEXT loop executes until a given condition is true.

An UNTIL...NEXT loop executes repeatedly for as long as the conditional expression is false. Note that in UNTIL...NEXT loops, the NEXT statement does not increment a control variable. You must explicitly change a variable in the conditional expression or the loop will execute indefinitely.

It is possible to code the WHILE...NEXT loop with a UNTIL...NEXT loop, as shown in the following example. These loops are equivalent except for the logical sense of the termination test (WHILE Answer <> "DONE" as opposed to UNTIL Answer = "DONE").

    INPUT 'Type "DONE" when finished.'; Answer

    UNTIL (Answer = "DONE")
       .
       .
       .
          INPUT "More data"; Answer
    NEXT

## 10.2.4 Nesting Loops

When a loop block is entirely contained in another loop block, it is called a nested loop.

The following example declares a two-dimensional array and uses nested FOR...NEXT loops to fill the array elements with sales information. The inner loop executes 16 times for each iteration of the outer loop. This example assigns a value to each of the 256 elements of the array.

    DECLARE
       INTEGER
          Column_number,
          Row_number
       REAL
          Sales_info,
          Two_dim_array (15%, 15%)

    FOR Row_number = 0% TO 15%
        FOR Column_number = 0% to 15%
            INPUT "Please enter the sales information";Sales_info
            Two_dim_array (Row_number, Column_number) = Sales_info
        NEXT Column_number
    NEXT Row_number

Note that in nested loops the inner loop is entirely contained in the outer loop; nested loops cannot overlap.

# 10.3 Unconditional Branching (GOTO Statement)

The GOTO statement specifies which program line the BASIC compiler is to execute next, regardless of that line's position in the program. If the statement at the target line number or label is nonexecutable (such as an REM statement), BASIC transfers control to the next executable statement following the target line number.

You can use a GOTO statement to exit from a loop; however, it is better programming practice to use the EXIT statement.

# 10.4 Conditional Branching

Conditional branching is the transfer of program control only when specified conditions are met. There are three BASIC statements that let you conditionally transfer control to a target statement in your program:

- ON...GOTO...OTHERWISE
- IF...THEN...ELSE
- SELECT...CASE

## 10.4.1 ON...GOTO...OTHERWISE Statement

The ON...GOTO...OTHERWISE statement tests the value specified after the ON keyword. If the value is 1, BASIC transfers control to the first target in the list; if the value is 2, control passes to the second target, and so on. If the value is less than 1 or greater than the number of targets in the list, BASIC transfers control to the target specified in the OTHERWISE clause. For example:

    Menu:
      PRINT "Would you like to change:"
      PRINT "1.  First name"
      PRINT "2.  Last name"

    INPUT CHOICE%

    ON CHOICE% GOTO First_name, Last_name OTHERWISE Other_choice

    First_name:
       INPUT "First name"; firstname$
       GOTO Done

    Last_name:
       INPUT "Last name"; lastname$
       GOTO Done

    Other_choice:
        PRINT "Invalid choice"
        PRINT "Let's try again"
        GOTO Menu

    Done:
        END

Note that if you do not supply an OTHERWISE clause and the control variable is less than 1 or greater than the number of targets, BASIC signals "ON statement out of range (ERR = 58)".

## 10.4.2 IF...THEN...ELSE Statement

The IF...THEN...ELSE statement evaluates a conditional expression and uses the result to determine which block of statements to execute next. If the conditional expression is true, BASIC executes the statements in the THEN clause. If the conditional expression is false, BASIC executes the statements in the ELSE clause, if one is present. If the conditional expression is false and there is no ELSE clause, BASIC executes the statement immediately following the END IF statement.

In the following example, BASIC evaluates the conditional expression number < 0. If the input value of number is less than zero, the conditional expression is true. BASIC then executes the statements in the THEN clause, skips the statement in the ELSE clause, and transfers control to the statement following the END IF. If the value of number is greater than or equal to zero, the conditional expression is false. BASIC then skips the statements in the THEN clause and executes the statement in the ELSE clause.

    INPUT "Input number"; number

    IF (number < 0)
    THEN
       number = - number
       PRINT "That square root is imaginary"
       PRINT "The square root of its absolute value is";
       PRINT SQR(number)
    ELSE
       PRINT "The square root is"; SQR(number)
    END IF
    END

Output

    Input number? -9
    That square root is imaginary
    The square root of its absolute value is 3

Do not neglect to end an IF...THEN...ELSE statement. After an IF block is executed, control is transferred to the statement immediately following the END IF. If there is no END IF, BASIC transfers control to the next line number. Code between the keyword ELSE and the next line number becomes part of the ELSE clause. If there are no line numbers, the BASIC compiler ignores the remaining program code from the keyword ELSE to the end of the program. Therefore, it is important to end IF statements.

IF...THEN...ELSE statements can be nested. In an inner nesting level, if an END IF is not present, the BASIC compiler treats the presence of an ELSE clause for an IF statement in an outer nesting level as an implicit END IF for all unterminated IF statements at that point. For example, in the following construction, the third ELSE terminates both inner IFs:

    IF expression
    THEN
        IF expression
        THEN
            statement-list
        ELSE
            IF expression
            THEN
                statement-list
            ELSE
                statement-list
    ELSE

In the following example, the first IF...THEN...ELSE statement is ended by END IF, and works as expected. Because the second IF...THEN...ELSE statement is not terminated by END IF, the BASIC compiler assumes that the last PRINT statement in the program is part of the second ELSE clause.

    10  DECLARE INTEGER light_bulb
        DECLARE INTEGER circuit_switch
        DECLARE INTEGER CONSTANT Opened  = 0
        DECLARE INTEGER CONSTANT Closed =  1

        PRINT "Please enter zero or one, corresponding to the circuit"
        PRINT "switch being open or closed"
        INPUT On_off_val
    (1)    IF On_off_val = Opened
          THEN
            PRINT "The light bulb is off."
          ELSE
            PRINT "The light bulb is on."
        END IF
        IF On_off_val = Closed
          THEN
            PRINT "The light bulb is on."
          ELSE
            PRINT "The light bulb is off."
    (2)    PRINT "That's all for now."
    20  END

1. When you run the program, the first IF...THEN...ELSE statement will always execute correctly.
2. The final PRINT statement will execute only when the value of On_off_val is 1 (that is, closed), because the compiler considers this PRINT statement to be part of the second ELSE clause.

Output 1

    Please enter zero or one, corresponding to the circuit
    switch being open or closed
    ? 0
    The light bulb is off.
    The light bulb is off.
    That's all for now.

Output 2

    Please enter zero or one, corresponding to the circuit
    Switch being open or closed
    ? 1
    The light bulb is on.
    The light bulb is on.

Note that a statement in a THEN or ELSE clause can be followed by a modifier. In this case, the modifying IF applies only to the statement that immediately precedes it.

    IF A = B
    THEN
       PRINT A IF A = 3
    ELSE
       PRINT B IF B > 0
    END IF

Previous | Next | Contents | Index