2.4.21 The SIGNAL Instruction
     SIGNAL = { string | symbol } ;
          [ VALUE ] expr ;
          { ON | OFF } condition [ NAME
          { string | symbol } ] ;


The SIGNAL instruction is used for two purposes: (a) to transfer
control to a named label in the program, and (b) to set up a named
condition trap.

The first form in the syntax definition transfers control to the
named label, which must exist somewhere in the program; if it does
not exist, a SYNTAX condition {16} is raised. If the label is
multiple defined, the first definition is used. The parameter can
be either a symbol (which is taken literally) or a string. If it
is a string, then be sure that the case of the string matches the
case of the label where it is defined. In practice, labels are in
upper case, so the string should contain only uppercase letters
too, and no space characters.

The second form of the syntax is used if the second token of the
instruction is VALUE. Then, the rest of the instruction is taken
as a general REXX expression, which result after evaluation is
taken to be the name of the label to transfer control to. This
form is really just a special case of the first form, where the
programmer is allowed to specify the label as an expression. Note
that if the start of expr is such that it can not be
misinterpreted as the first form (i.e. the first token of expr is
neither a string nor a symbol), then the VALUE subkeyword can be
omitted.

Example: Transferring control to inside a loop

When the control of execution is transferred by a SIGNAL
instruction, all active loops at the current procedural level are
terminated, i.e. they can not continued later, although they can
of course be reentered from the normal start. The consequence of
this is that the following code is illegal:

     do forever
          signal there
     there:
     nop
     end

The fact that the jump is altogether within the loop does not
prevent the loop from being terminated. Thus, after the jump to
the loop, the END instruction is attempted executed, which will
result in a SYNTAX condition {10}. However, if control is
transferred out of the loop after the label, but before the END,
then it would be legal, i.e. the following is legal:

     do forever
          signal there
     there:
     nop
     signal after
     end
     
     after:

This is legal, simply because the END instruction is never seen
during this script. Although both TRL1 and TRL2 allow this
construct, it will probably be disallowed in ANSI.

Just as loops are terminated by a SIGNAL instruction, SELECT and
IF instructions are also terminated. Thus, it is illegal to jump
to a location within a block of statements contained in a WHEN,
OTHERWISE, or IF instruction, unless the control is transferred
out of the block before the execution reaches the end of the
block.

Whenever execution is transferred during a SIGNAL instruction, the
special variable SIGL is set to the line number of the line
containing the SIGNAL instruction, before the control is
transferred. If this instruction extends over several lines, it
refers to the first of this. Note that even blanks are part of a
clause, so if the instruction starts with a line continuation, the
real line of the instruction is different from that line where the
instruction keyword is located.

The third form of syntax is used when the second token in the
instruction is either ON or OFF. In both cases must the third
token in the instruction be then name of a condition (as a
constant string or a symbol, which is taken literally), and the
setup of that condition trap is changed. If the second token is
OFF, then the trap of the named condition is disabled.

If the second token is ON, then the trap of the named condition is
enabled. Further, in this situation two more tokens may be allowed
in the instruction: the first must be NAME and the second must be
the name of a label (either as a constant string or a symbol,
which is taken literally). If the five token form is used, then
the label of the condition handler is set to the named label, else
the name of the condition handler is set to the default, which is
identical to the name of the condition itself.

Note that the NAME subclause of the SIGNAL instruction was a new
construct in TRL2, and is not a part of TRL1. Thus, older
interpreters may not support it.

Example: Naming condition traps

Note that the default value for the condition handler (if the NAME
subclause is not specified) is the name of the condition, not the
condition handler from the previous time the condition was
enabled. Thus, after the following code, the name of the condition
handler for the condition SYNTAX is SYNTAX, not FOOBAR:

     signal on syntax name foobar
     signal on syntax

Example: Named condition traps in TRL1

A common problem when trying to port REXX code from a TRL2
interpreter to a TRL1 interpreter, is that explicitly named
condition traps are not supported. There exist ways to circumvent
this, like:

     syntax_name = ‘SYNTAX_HANDLER’
     signal on syntax
     if 1 + 2 then  /* will generate SYNTAX condition */
          nop
     syntax:
     oldsigl = sigl
     signal value translate(syntax_name)
     
     syntax_handler:
     say ‘condition at line’ oldsigl ‘is being handled...’
     exit

Here, a “global” variable is used to store the name of the real
condition handler, in the absence of a field for this in the
interpreter. This works fine, but there are some problems: the
variable SYNTAX_NAME must be exposed to everywhere, in order to be
available at all times. It would be far better if this value could
be stored somewhere from which it could be retrieved from any part
of the script, no matter the current state of the call-stack. This
can be fixed with programs like GLOBALV under VM/CMS and putenv
under Unix.

Another problem is that this destroys the possibility of setting
up the condition handler with the default handler name. However,
to circumvent this, add a new DEFAULT_SYNTAX_HANDLER label which
becomes the new name for the old SYNTAX label.

Further information about conditions and condition traps are given
in chapter Conditions.



PREV NEXT