Compaq BASIC for OpenVMS
Alpha and VAX Systems
User Manual


Previous Contents Index

10.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, 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, 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 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 

10.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:

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, 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 

10.6 Executing Local Subroutines

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

10.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 BASIC signals "RETURN without GOSUB" if it encounters a RETURN statement without first having encountered a GOSUB or ON GOSUB statement.

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

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, 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 

10.7 Suspending and Halting Program Execution

The following BASIC statements suspend program execution:

SLEEP
WAIT

These statements cause 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 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.

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

10.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, 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$ 

10.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 BASIC executes a STOP statement, it signals "STOP at line <line-num>". If the program executes in the VAX BASIC Environment, BASIC prompts with the Ready command level prompt. In response, you can enter the following:

You use the STOP statement when debugging in immediate mode in the VAX BASIC Environment. For more information about immediate mode statements, see Chapter 2.

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

10.7.4 END Statement

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

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

If you run your program in the VAX BASIC Environment, the END statement returns you to BASIC command level. If you execute the program outside the VAX BASIC Environment, the END statement returns you to DCL command level.


Chapter 11
Functions

A function is a single statement or group of statements that perform operations on operands and return the result to your program. BASIC has built-in functions that perform numeric and string operations, conversions, and date and time operations. This chapter describes only a selected group of built-in functions. For a complete description of all BASIC built-in functions, see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.

This chapter also describes user-defined functions. BASIC lets you define your own functions in two ways:

DEF function definitions are local to a program module, while external functions can be accessed by any program module. You create local functions with the DEF statement and optionally declare them with the DECLARE statement. You create external functions with the FUNCTION statement and declare them with the EXTERNAL statement. For more information about creating external functions with the FUNCTION statement, see Chapter 13.

Once you create and declare a function, you can invoke it like a built-in function.

11.1 Built-In Functions

The functions described in this section let you perform sophisticated manipulations of string and numeric data. BASIC also provides algebraic, exponential, trigonometric, and randomizing mathematical functions.

11.1.1 Numeric Functions

Numeric functions generally return a result of the same data type as the function's parameter. For example, if you pass a DOUBLE argument to any of the trigonometric functions, they return a DOUBLE result.

If the format of a BASIC function specifies an argument of a particular data type, BASIC converts the actual argument supplied to the specified data type. For example, if you supply an integer argument to a function that expects a floating-point number, BASIC converts the argument to a floating-point number. Floating-point arguments that are passed to integer functions are truncated, not rounded.

The following sections discuss the BASIC built-in numeric functions.

11.1.1.1 ABS Function

The ABS function returns a floating-point number that equals the absolute value of a specified numeric expression. For example:


READ A,B 
DATA 10,-35.3 
NEW_A = ABS(A) 
PRINT NEW_A; ABS(B) 
END 

Output


 10  35.3 

The ABS function always returns a number of the default floating-point data type.

11.1.1.2 INT and FIX Functions

The INT function returns the floating-point value of the largest integer less than or equal to a specified expression. The INT function always returns a number of the default floating-point type.

The FIX function truncates the value of a floating-point number at the decimal point. FIX always returns a number of the default floating-point type.

The following example shows the differences between the INT and FIX functions. Note that the value returned by FIX(-45.3) differs from the value returned by INT(-45.3).


PRINT INT(23.553); FIX(23.553) 
PRINT INT(3.1); FIX(3.1) 
PRINT INT(-45.3); FIX(-45.3) 
PRINT INT(-11); FIX(-11) 
END 

Output


 23  23 
 3  3 
-46 -45 
-11 -11 

11.1.1.3 SIN, COS, and TAN Functions

The SIN, COS, and TAN functions return the sine, cosine, and tangents of an angle in radians or degrees, depending on which angle clause you choose with the OPTION statement. If you supply a floating-point argument to the SIN, COS, and TAN functions, they return a number of the same floating-point type. If you supply an integer argument, they convert the argument to the default floating-point data type and return a floating-point number of that type.

The following example accepts an angle in degrees, converts the angle to radians, and prints the angle's sine, cosine, and tangent:


!CONVERT ANGLE (X) TO RADIANS, AND 
!FIND SIN, COS AND TAN 
PRINT "DEGREES", "RADIANS", "SINE", "COSINE","TANGENT" 
FOR I% = 0% TO 5% 
    READ X 
    LET Y = X * 2 * PI / 360 
    PRINT 
    PRINT X ,Y ,SIN(Y) ,COS(Y) ,TAN(Y) 
NEXT I% 
 
DATA 0,10,20,30,360,45 
END 

Output


DEGREES       RADIANS       SINE          COSINE        TANGENT 
 
 0             0             0             1             0 
 
 10            .174533       .173648       .984808       .176327 
 
 20            .349066       .34202        .939693       .36397 
 
 30            .523599       .5            .866025       .57735 
 
 360           6.28319       .174846E-06   1             .174846E-06 
 
 45            .785398       .707107       .707107       1 

Note

As an angle approaches 90 degrees (PI/2 radians), 270 degrees (3*PI/2 radians), 450 degrees (5*PI/2 radians), and so on, the tangent of that angle approaches infinity. If your program tries to find the tangent of such an angle, BASIC signals "Division by 0" (ERR=61).

11.1.1.4 SQR Function

The SQR function returns the square root of a number. For example:


PRINT SQR (2) 

Output


1.41421 

11.1.1.5 LOG10 Function

A logarithm is the exponent of some number (called a base). Common logarithms use the base 10. The common logarithm of a number n, for example, is the power to which 10 must be raised to equal n. For example, the common logarithm of 100 is 2, because 10 raised to the power 2 equals 100.

The LOG10 function returns a number's common logarithm. The following example calculates the common logarithms of all multiples of 10 from 10 to 100, inclusively:


FOR I% = 10% TO 100% STEP 10% 
    PRINT LOG10(I%) 
NEXT I% 
END 

Output


 1 
 1.30103 
 1.47712 
 1.60206 
 1.69897 
 1.77815 
 1.8451 
 1.90309 
 1.95424 
 2 

If you supply a floating-point argument to LOG10, the function returns a floating-point number of the same data type. If you supply an integer argument, LOG10 converts it to the default floating-point data type and returns a value of that type.

11.1.1.6 EXP Function

The EXP function returns the value of e raised to a specified power. The following example prints the value of e and e raised to the second power:


READ A,B 
DATA 1,2 
PRINT 'e RAISED TO THE POWER'; A; " EQUALS"; EXP(A) 
PRINT 'e RAISED TO THE POWER'; B; " EQUALS"; EXP(B) 
END 

Output


e RAISED TO THE POWER 1 EQUALS 2.71828 
e RAISED TO THE POWER 2 EQUALS 7.38906 

If you supply a floating-point argument to EXP, the function returns a floating-point number of the same data type. If you supply an integer argument, EXP converts it to the default floating-point data type and returns a value of that type.


Previous Next Contents Index