[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP BASIC for OpenVMS
User Manual


Previous Contents Index

9.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.

9.3 Unconditional Branching (GOTO Statement)

The GOTO statement specifies which program line the HP 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), HP 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.

9.4 Conditional Branching

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

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

9.4.1 ON...GOTO...OTHERWISE Statement

The ON...GOTO...OTHERWISE statement tests the value specified after the ON keyword. If the value is 1, HP 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, HP 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)".

9.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, HP BASIC executes the statements in the THEN clause. If the conditional expression is false, HP BASIC executes the statements in the ELSE clause, if one is present. If the conditional expression is false and there is no ELSE clause, HP BASIC executes the statement immediately following the END IF statement.

In the following example, HP BASIC evaluates the conditional expression number < 0. If the input value of number is less than zero, the conditional expression is true. HP 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. HP 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, HP 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 HP 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 HP 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

9.4.3 SELECT...CASE Statement

The SELECT...CASE statement lets you specify an expression (the SELECT expression), any number of possible values (cases) for the SELECT expression, and a list of statements (a CASE block) for each case. The SELECT expression can be a numeric or string value. CASE values can be single or multiple values, one or more ranges of values, or relationships. When a match is found between the SELECT expression and a CASE value, the statements in the following CASE block are executed. Control is then transferred to the statement following the END SELECT statement.

In the following example, the CASE values appear to overlap; that is, the CASE value that tests for values greater than or equal to 0.5 also includes the values greater than or equal to 1.0. However, HP BASIC executes the statements associated with the first matching CASE statement and then transfers control to the statement following END SELECT. In this program, each range of values is tested before it overlaps in the next range. Because the compiler executes the first matching CASE statement, the overlapping values do not matter.


DECLARE REAL Stock_change


INPUT "Please enter stock price change";Stock_change

SELECT Stock_change

CASE <= 0.5
     PRINT "Don't sell yet."

CASE <= 1.0
     PRINT "Sell today."

CASE ELSE
     PRINT "Sell NOW!"

END SELECT
END

Output


Please enter stock price change? 2.1
Sell NOW!

If no match is found for any of the specified cases and there is no CASE ELSE block, HP BASIC transfers control to the statement following END SELECT without executing any of the statements in the SELECT block.

SELECT...CASE lets you use run-time expressions for both SELECT expressions and CASE values. The following example uses HP BASIC built-in string functions to examine command input:


! This program is a skeleton command processor.
! It recognizes three VAX BASIC Environment commands:
!
!      SAVE
!      SCRATCH
!      OLD

DECLARE INTEGER CONSTANT True  = -1
DECLARE INTEGER CONSTANT False =  0

DECLARE STRING CONSTANT Null_input = ""   !This is the null string.

DECLARE STRING Command

! Main program logic starts here.

Command_loop:

WHILE True          ! This loop executes until the user types only a
                    ! carriage return in response to the prompt.

    PRINT
    PRINT "Please enter a command (uppercase only)."
    PRINT "Type a carriage return when finished."
    INPUT Command
    PRINT

    SELECT Command

    CASE Null_input                       ! If user types RETURN,
                                          ! exit from the loop
      GOTO Done                           ! and end the program.

    ! The next three cases use the SEG$ and LEN string functions.
    ! LEN returns the length of the typed string, and SEG$ searches
    ! the string literals ("SAVE", "SCRATCH", and "OLD") for a
    ! match up to that length.  Note that if the user types an "S",
    ! it is interpreted as a SAVE command only because SAVE is the
    ! first case tested.

    CASE SEG$ ( "SAVE", 1%, LEN (Command) )
      PRINT "That was a SAVE command."

    CASE SEG$ ( "SCRATCH", 1%, LEN (Command) )
      PRINT "That was a SCRATCH command."

    CASE SEG$( "OLD", 1%, LEN (Command) )
      PRINT "That was an OLD command."

    CASE ELSE
      PRINT "Invalid command, please try again."

    END SELECT
  NEXT

Done:
     END

9.5 EXIT and ITERATE Statements

This section describes the EXIT and ITERATE statements and shows their use with nested control structures.

The ITERATE and EXIT statements let you explicitly control loop execution. These statements can be used to transfer control to the top or bottom of a control structure.

You can use EXIT to transfer control out of any of these structures:

  • FOR...NEXT loops
  • WHILE...NEXT loops
  • UNTIL...NEXT loops
  • IF...THEN...ELSE blocks
  • SELECT...CASE blocks
  • SUB, FUNCTION, and PICTURE subprograms
  • DEF functions, and programs

In the case of control structures, EXIT passes control to the first statement following the end of the control structure.

You can use ITERATE to explicitly reexecute a FOR...NEXT, WHILE...NEXT, or UNTIL...NEXT loop. EXIT and ITERATE statements can appear only within the code blocks you want to leave or reexecute.

Executing the ITERATE statement is equivalent to transferring control to the loop's NEXT statement. The termination test is still performed when the NEXT statement transfers control to the top of the loop. In addition, transferring control to the NEXT statement means that a FOR loop's control variable is incremented by the STEP value.

Supplying a label for every loop lets you state explicitly which loop to leave or reexecute. If you do not supply a label for the ITERATE statement, HP BASIC reexecutes the innermost active loop. For example, if an ITERATE statement (that does not specify a label) is executed in the innermost of three nested loops, only the innermost loop is reexecuted.

In contrast, labeling each loop and supplying a label argument to the ITERATE statement lets you reexecute any of the loops. A label name also helps document your code. Because you must use a label with EXIT and it is sometimes necessary to use a label with ITERATE, you should always label the structures you want to control with these statements.

The following example shows the use of both the EXIT and ITERATE statements. This program explicitly exits the loop if you type a carriage return in response to the prompt. If you type a string, the program prints the length of the string and explicitly reexecutes the loop.


DECLARE STRING User_string

Read_loop:
WHILE 1% = 1%
      LINPUT "Please type a string"; User_string

      IF User_string == ""
         THEN
            EXIT Read_loop
         ELSE
            PRINT "Length is ";LEN(User_string)
            ITERATE Read_loop
       END IF
NEXT
END

9.6 Executing Local Subroutines

In HP BASIC, a subroutine is a block of code accessed by a GOSUB or ON GOSUB statement. It must be in the same program unit as the statement that calls it. The RETURN statement in the subroutine returns control to the statement immediately following the GOSUB.

The first line of a subroutine can be any valid HP BASIC statement, including a REM statement. You do not have to transfer control to the first line of the subroutine. Instead, you can include several entry points into the same subroutine. You can also reference subroutines by using a GOSUB or ON GOSUB statement to another subroutine.

Variables and data in a subroutine are global to the program unit in which the subroutine resides.

9.6.1 GOSUB and RETURN Statements

The GOSUB statement unconditionally transfers control to a line in a subroutine. The last statement in a subroutine is a RETURN statement, which returns control to the first statement after the calling GOSUB. A subroutine can contain more than one RETURN statement so you can return control conditionally, depending on a specified condition.

The following example first assigns a value of 5 to the variable A, then transfers control to the subroutine labeled Times_two. This subroutine replaces the value of A with A multiplied by 2. The subroutine's RETURN statement transfers control to the first PRINT statement, which displays the changed value. The program calls the subroutine two more times, with different values for A. Each time, the RETURN transfers control to the statement immediately following the corresponding GOSUB.


A = 5
GOSUB Times_two
PRINT A

A = 15
GOSUB Times_two
PRINT A

A = 25
GOSUB Times_two
PRINT A

GOTO Done

Times_two:
    !This is the subroutine entry point
    A = A * 2
    RETURN

Done:
    END

Output


10
30
50

Note that HP BASIC signals "RETURN without GOSUB" if it encounters a RETURN statement without first having encountered a GOSUB or ON GOSUB statement.

9.6.2 ON...GOSUB...OTHERWISE Statement

The ON...GOSUB...OTHERWISE statement transfers control to one of several target subroutines depending on the value of a numeric expression. A RETURN statement returns control to the first statement after the calling ON GOSUB. A subroutine can contain more than one RETURN statement so that you can return control conditionally, depending on a specified condition.

HP BASIC tests the value of the integer expression. If the value is 1, control transfers to the first line number or label in the list; if the value is 2, control passes to the second line number or label, and so on. If the control variable's value is less than 1 or greater than the number of targets in the list, HP BASIC transfers control to the line number or label specified in the OTHERWISE clause. If you do not supply an OTHERWISE clause and the control variable's value is less than 1 or greater than the number of targets, BASIC signals "ON statement out of range (ERR=58)". For example:


INPUT "Please enter first integer value"; First_value%
INPUT "Please enter second integer value"; Second_value%

Choice:
    PRINT "Do you want to perform:"
    PRINT "1.  Multiplication"
    PRINT "2.  Division"
    PRINT "3.  Exponentiation"

INPUT Selection%

ON Selection% GOSUB Mult, Div, Expon OTHERWISE Wrong
GOTO Done

Mult:
    Result% = First_value% * Second_value%
    PRINT Result%
    RETURN

Div:
    Result% = First_value / Second_value%
    PRINT Result%
    RETURN

Expon:
    Result% = First_value% ** Second_value%
    PRINT Result%
    RETURN

Wrong:
    PRINT "Invalid selection"
    RETURN

Done:
    END

9.7 Suspending and Halting Program Execution

The following HP BASIC statements suspend program execution:

SLEEP
WAIT

These statements cause HP BASIC either to suspend program execution for a specified time or to wait a certain period of time for user input.

After execution of the last statement, a HP BASIC program automatically halts and closes all files. However, you can explicitly halt program execution by using one of the following statements:

STOP
END

The STOP statement does not close files. It can appear anywhere in a program. The END statement closes files and must be the last statement in a main program.

9.7.1 SLEEP Statement

The SLEEP statement suspends program execution for a specified number of seconds. The following program waits two minutes (120 seconds) after receiving the input string, and then prints it:


INPUT "Type a string of characters"; C$
SLEEP 120%
PRINT C$
END

The SLEEP statement is useful if you have a program that depends on another program for data. Instead of constantly checking for a condition, the SLEEP statement lets you check the condition at specified intervals.

9.7.2 WAIT Statement

You use the WAIT statement only with terminal input statements such as INPUT, INPUT LINE, and LINPUT. For example, the following program prompts for input, then waits 30 seconds for your response. If the program does not receive input in the specified time, HP BASIC signals "Keyboard wait exhausted (ERR=15)" and exits the program.


WAIT 30%
INPUT "You have 30 seconds to type your password"; PSW$
END

The WAIT statement affects all subsequent INPUT, INPUT LINE, LINPUT, MAT INPUT, and MAT LINPUT statements. To disable a previously specified WAIT statement, use WAIT 0%.

In the following example, the first WAIT statement causes the first INPUT statement to wait 30 seconds for a response. The WAIT 0% statement disables this 30-second requirement for all subsequent INPUT statements.


WAIT 30%
INPUT "You have 30 seconds to type your  password"; PSW$
WAIT 0%
INPUT "What directory do you want to go to"; DIR$

9.7.3 STOP Statement

The STOP statement is a debugging tool that lets you check the flow of program logic. STOP suspends program execution but does not close files.

When HP BASIC executes a STOP statement, it signals "STOP at line <line-num>."

If you compile, link, and execute a program containing a STOP statement, HP BASIC displays a number sign (#) prompt when the STOP statement is encountered. At this point, you can enter:

  • CONTINUE (to continue program execution)
  • EXIT (to return to DCL command level)

9.7.4 END Statement

The END statement marks the end of a main program. When HP BASIC executes an END statement, it closes all files and halts program execution.

The END statement is optional in HP BASIC programs. However, it is good programming practice to include it. The END statement must be the last statement in the main program.

The END statement returns you to DCL command level.


Previous Next Contents Index