Make your own free website on Tripod.com
2.4.3 The CALL Instruction
      CALL = routine [ parameter ]
           [, [ parameter ] ... ] ;
          { ON | OFF } condition [ NAME label ] ;

The CALL instruction invokes a subroutine, named by routine, which
can be internal, built-in, or external; and the three repositories
of functions are searched in that order. are searched for routine
in that order. The token routine must be either a literal string
or a symbol (which is taken literally).  However, if routine is a
literal string, the pool of internal subroutines is not searched.
Note that some interpreters may have additional repositories of
labels to search.

In a CALL instruction, each parameter is evaluated, strictly in
order from left to right, and passed as an argument to the
subroutine.  A parameter might be left out (i.e. an empty
argument), which is not the same as passing the nullstring as
argument.

Users often confuse a parameter which is the nullstring with
leaving out the parameter. However, this is two very different
situations.  Consider the following calls to the built-in function
TRANSLATE():

     say translate(‘abcDEF’   )   /* says ABCDEF */
     
     say translate(‘abcDEF’,””)   /* says abcDEF */
     
     say translate(‘abcDEF’,,””)  /* says ‘      ’ */

The TRANSLATE() function is able to differ between receiving the
nullstring (i.e. a defined string having zero length), from the
situation where a parameter was not specified (i.e. the undefined
string). Since TRANSLATE() is one of the few functions where the
parameters’ default values are very different from the nullstring,
the distinction becomes very visible.

For the CALL instruction, watch out for interference with line
continuation. If there are trailing commas, it might be
interpreted as line continuation. If a CALL instruction use line
continuation between two parameters, two commas are needed: one to
separate the parameters, and one to denote line continuation.

A number of settings are stored across internal subroutine calls.
An internal subroutine will inherit the values in effect when the
call is made, and the settings are restored on exit from the
subroutine.  These settings are:

·    Conditions traps, see chapter Conditions.
·    Current trapped condition, see section CTS.
·    NUMERIC settings, see section Numeric.
·    ADDRESS environments, see section Address.
·    TRACE mode, see section Trace and chapter [not yet written].
·    The elapse time clock, see section Time.

Also, the OPTIONS settings may or may not be restored, depending
on the implementation.  Further, a number of other things may be
saved across internal subroutines. The effect on variables are
controlled by the PROCEDURE instruction in the subroutine itself.
The state of all DO-loops will be preserved during subroutine
calls.

Example: Subroutines and trace settings

Subroutines can not be used to set various settings like trace
settings, NUMERIC settings, etc. Thus, the following code will not
work as intended:

     say digits() /* says 9, maybe */
     call inc_digits
     say digits() /* still says 9 */
     exit
     
     inc_digits:
         numeric digits digits() + 1
         return

The programmer probably wanted to call a routine which incremented
the precision of arithmetic operations. However, since the setting
of NUMERIC DIGITS is saved across subroutine calls, the new value
set in inc_digits is lost at return from that routine. Thus, in
order to work correctly, the NUMERIC instruction must be located
in the main routine itself.

Built-in subroutines will have no effect on the settings, except
for explicitly defined side effects. Nor will external subroutines
change the settings. For all practical purposes, an external
subroutine is conceptually equivalent to reinvoking the
interpreter in a totally separated process.

If the name of the subroutine is specified by a literal string,
then the name will be used as-is; it will not be converted to
upper case.  This is important because a routine which contains
lower case letters can only be invoked by using a literal string
as the routine name in the CALL instruction.

Example: Labels are literals

Labels are literal, which means that they are neither tail-
substituted nor substituted for the value of the variable.
Further, this also means that the setting of NUMERIC DIGITS has no
influence on the section of labels, even when the labels are
numeric symbols. Consider the following code:

     call 654.32
     exit
     
     654.321:
         say here
         return
     
     654.32:
         say there
         return

In this example, the second of the two subroutines are always
chosen, independent of the setting of NUMERIC DIGITS. Assuming
that NUMERIC DIGITS are set to 5, then the number 654.321 is
converted to 654.32, but that does not affect labels. Nor would a
statement CALL 6.5432E2 call the second label, even though the
numeric value of that symbol is equal to that of one of the
labels.

The called subroutines may or may not return data to the caller.
In the calling routine, the special variable RESULT will be set to
the return value or dropped, depending on whether any data was
returned or not. Thus, the CALL instruction is equivalent to
calling the routine as a function, and assigning the return value
to RESULT, except when the routine does not return data.

In REXX, recursive routines are allowed. A minimum number of 100
nested internal and external subroutine invocations, and support
for a minimum of 10 parameters for each call are required by REXX.
See chapter Limits for more information concerning implementation
limits.

When the token following CALL is either ON or OFF, the CALL
instruction is not used for calling a subroutine, but for setting
up condition traps. In this case, the third token of the clause
must be the name of a condition, which setup is to be changed.

If the second token was ON, then there can be either three or five
tokens. If the five token version is used, then the fourth token
must be NAME and the fifth token is taken to be the symbolic name
of a label, which is the condition handler. This name can be
either a constant string, or a symbol, which is taken literally.
When OFF is used, the named condition trap is turned off.

Note that the ON and OFF forms of the CALL instruction were
introduced in TRL2. Thus, they are not likely to be present on
older interpreters. More information about conditions and
condition traps are given in a chapter Conditions.



PREV NEXT