CALL, ENTER |
![]() ![]() ![]() |
The CALL statement calls a catalogued subroutine. The ENTER statement is a synonym for CALL unless the PICK.ENTER option of the $MODE directive is used.
Format
CALL name {(arg.list)} CALL @var {(arg.list)}
where
A subroutine with no arguments is equivalent to a program. A whole matrix can be passed as an argument by prefixing it with MAT.
Direct calls
Placing the subroutine name in the CALL statement is referred to as a direct call. QM will search for the subroutine as described below when any CALL statement referencing the subroutine is first executed in the program or subroutine. For CALL statements which occur within catalogued subroutines the search will take place every time the calling subroutine itself is called. QM includes an object code caching mechanism to minimise the performance impact of this repeated search.
Indirect calls
Executing a CALL statement using a variable to hold the subroutine name is referred to as an indirect call. In this case, QM will search for the subroutine as described below when the first CALL statement is executed. Indirect calls allow an application to call a subroutine where the name of the routine was not known at compile time. This might be of use, for example, in menu systems.
When an indirect call is executed, the variable containing the subroutine name is modified to become a subroutine reference. This can still be used as a string in the program but also contains a pointer to the memory resident copy of the subroutine. The subroutine will remain in memory so long as one or more subroutine references point to it. Overwriting the variable will destroy the subroutine link and may make the subroutine a candidate for removal from the object code cache.
One advantage of indirect calls is that, by placing the variable in a common block where it is accessible by all modules of the application and will not be discarded, the catalogue search need only be performed once even when the CALL is in a subroutine which itself may be called many times. A direct call works in a similar way but the variable in which the subroutine reference is placed is local to the program containing the CALL and is thus lost when the program terminates.
Searching for the subroutine
Subroutines to be executed using CALL must be placed in the catalogue using the CATALOGUE command or the equivalent automated cataloguing from within the QMBasic compiler.
Subroutine names must conform to the QMBasic name formats except that two special prefix characters are allow. An exclamation mark prefix character is used on all standard globally catalogued subroutines provided as part of QM that are intended for user use. An asterisk prefix may be used on user written globally catalogued subroutines for compatibility with other products.
Unless the subroutine name commences with one of the global catalogue prefix characters, QM goes through a series of steps when a CALL statement searches for a subroutine:
Field 1 V Field 2 CS Field 3 Runfile pathname
Note that subsequent calls to the same subroutine where the subroutine reference has not been reset will continue to use the original catalogued routine even if it has been deleted from the catalogue or replaced.
The argument list may contain up to 255 items. If a subroutine has no arguments, the brackets may be omitted.
Each argument is
Where the argument is a reference to a variable, a matrix element or a whole matrix, the subroutine may update the values in these variables. Except when passing a whole matrix, the calling program can effectively prevent this by forcing the argument to be passed by value rather than by reference by enclosing it in brackets, thus making the argument into an expression.
Pick Style ENTER
By default, the ENTER statement is a synonym for CALL. Use of the PICK.ENTER option of the $MODE compiler directive causes ENTER to behave in the same way as its equivalent in Pick style multivalue database products.
In this mode, use of ENTER terminates the current program and replaces it with the named program. This new program may not take arguments. If the ENTER statement is performed in a program that was started using the EXECUTE statement, or a subroutine called from such a program, the ENTER does not discard the program containing the EXECUTE.
Examples
COMMON /COM1/ INITIALISED, SUB1 IF NOT(INITIALISED) THEN SUB1 = "SUBR1" INITIALISED = @TRUE END
This program fragment declares a common block to hold subroutine call references. When the program is first executed, the conditional statements will be performed as common block variables are initially zero. This path sets the name of the subroutine SUBR1 into common variable SUB1.
Later in the program, perhaps in a different subroutine from that in which the common was initialised, a statement of the form
CALL @SUB1(ARG1, ARG2)
will call the SUBR1, changing the common variable to be a subroutine reference for fast access on subsequent calls.
A statement of the form
CALL SUBR1(ARG1, ARG2)
would call the same subroutine but does not use the common block variable. If this call was in a subroutine, the catalogue search would be performed for the first call each time the calling subroutine is entered. |