The purpose of a DataBasic subroutine is to specify a set of instructions that are required in more than one place in a program, or in more than one program. Instead of duplicating the instructions, you can set up a subroutine and call it from within the program as needed. Subroutines are of two types: Internal and External.
Using subroutines improves program source code by allowing you to reuse common code, thus enhancing readability, maintainability and testability. In addition, using an external subroutine avoids duplication of effort by enabling a number of programs to share the same source code. Refer to the topic Efficient Use of Subroutines for guidelines on the use of subroutines to make a program more efficient.
An internal subroutine is a sequence of statements within a DataBasic program which starts with a statement label and ends with a RETURN statement. Internal subroutines are called, from within the same program only, using the GOSUB or ON GOSUB statements.
Note: Within a program module all identifiers are global in scope. You should bear this in mind when choosing variable names for use in internal subroutines. If you inadvertently use the same identifier in both the main program and an internal subroutine, you risk changing a value on which some other part of the program relies.
GOSUB VERIFYINPUT CRT NUMBER STOP ************************************* * Subroutine VERIFYINPUT * * Inputs a number from 1 to 1000. * VERIFYINPUT: LOOP PRINT "Input Number from 1 to 1000": INPUT NUMBER UNTIL NUMBER >= 1 AND NUMBER <= 1000 DO PRINT "Invalid data" REPEAT * RETURN **************************************
The GOSUB statement calls the
subroutine VERIFYINPUT
from within the same program. The statements in the
subroutine are then processed until the RETURN
statement is reached. Control is
then passed back to the program statement following the most recently executed
GOSUB
statement, in this example, CRT NUMBER
.
The VERIFYINPUT
subroutine requests a numeric input and checks that it is in the range 1 to
1000. If it is, it returns control to the calling program which outputs the
number to the screen. If it is not, it displays the message 'Invalid
data'
and requests another number.
An external subroutine is a separate DataBasic program which can be called in various ways:
Note: The ENTER statement must not be used to execute a subroutine.
The subroutine returns to the calling program when a RETURN statement is encountered; if no RETURN statement is encountered, the subroutine does not return.
An external subroutine must be in a separate program module, starting with a SUBROUTINE statement (only comments can precede the SUBROUTINE statement). The name of the subroutine (declared in the SUBROUTINE statement) must match the module’s item-id and obey the rules for identifiers.
Note: The CHAIN statement should never be used in an external subroutine to run another DataBasic program.
External subroutines must be cataloged (see the CATALOG command for details). It is recommended that you also catalog the calling program, because this will make your program more efficient.
There are two methods you can use to pass data between the calling program and the subroutine:
As arguments to the subroutine call. In this case, the subroutine declaration must include any required parameters. For example:
SUBROUTINE DISTANCE(X1, Y1, X2, Y2, D)
This declares parameters called X1, Y1, X2, Y2 and D which must be used to pass data to the DISTANCE subroutine. The subroutine would be called as follows:
CALL DISTANCE(SX, SY, EX, EY, DIST)
where SX, SY, EX and EY contain the data to be passed to the subroutine, and DIST is a variable to which the result will be returned.
An argument passed to a subroutine can be any valid DataBasic expression that returns a value of the required type. Variables used as arguments to an external subroutine are passed by reference; if the subroutine changes the values of these parameters, the changes will be visible to the calling program (in the above example, the D parameter is used to return the result of the subroutine). The results of all other expressions are passed by value.
Using one or more COMMON variables, accessible to both the calling program and the subroutine. In this case, both the calling program and the subroutine must declare the necessary COMMON variables. For example, in the subroutine:
SUBROUTINE DISTANCE COMMON X1, Y1, X2, Y2, D
and in the calling program:
COMMON SX, SY, EX, EY, DIST CALL DISTANCE
Note: Using COMMON variables is more efficient than passing data as arguments in the subroutine call.
Identifiers used within an external subroutine are local in scope and can be the same as identifiers used in the calling program.
************************************** * Subroutine DISTANCE * * Computes the distance between two points. * SUBROUTINE DISTANCE(X1, Y1, X2, Y2, D) DX = X2 – X1 DY = Y2 – Y1 D = SQRT(DX * DX + DY * DY) RETURN **************************************
This example defines an external subroutine called DISTANCE that accepts five arguments. It computes the distance between two points (defined by the X1/Y1 and X2/Y2 parameters) and returns the result in the D parameter.