SD - The Open Source, Multivalue, String, Database
The CALL statement calls a catalogued subroutine.
Format:
CALL name {(arg.list)}
CALL @var {(arg.list)}
Parameters:
name is the name of the subroutine to be called.
@var is the name of a variable holding the name of the subroutine to be called.
arg.list is the list of arguments to the subroutine.
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. SE 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. SD 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, SD 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 CATALOG command or the equivalent automated cataloguing from within the SD Basic compiler.
Subroutine names must conform to the SD Basic 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 SD 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, SD goes through a series of steps when a CALL statement searches for a subroutine:
1) The local catalogue is checked. This consists of a VOC record of the form
Field 1 V
Field 2 CS
Field 3 Runfile pathname
2) The private catalogue file is checked.
3) The global catalogue is checked.
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
A constant CALL SUB("MY.FILE")
An expression CALL SUB(X + 7)
A variable name CALL SUB(X)
An indexed matrix element name CALL SUB(A(5,2))
A matrix name prefixed by MAT CALL SUB(MAT A)
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.
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.
SD Basic Statements - CALL
OpenQM 2.6.6 documentation for this command is available here. The OpenQM documentation may provide additional context for this command. However, some features in SD have been modified so the OpenQM information may not be 100% applicable to SD.