Exits from a control structure.
||Number of control structures, n, to exit (if n exceeds the number of control structures of the specified type that are currently active, the exit is to the end of the outer one; while for n negative, the exit is to the end of the –n‘th structure in order of execution); default 1|
||Type of control structure to exit (
||Whether to go to the next set of parameters on exit from a
||Text to be printed if the exit takes place; default
|expression||Logical expression controlling whether or not an exit takes place|
Sometimes you may want simply to abandon part of a program: you may be unable to do any further calculations or analyses. For example, if you are examining several subsets of the units, you would wish to abandon the analysis of any subset that turned out to contain no observations. Another example would be if you wanted to abandon the execution of a procedure whenever an error diagnostic has appeared. The
EXIT directive allows you to exit from any control structure.
In its simplest form
EXIT has no parameter setting, and the exit is unconditional: Genstat will always exit from the control structure or structures concerned. You are most likely to use this as part of an
ELSE block of a block-if or multiple-selection structure. For example
CALCULATE Percent = R * 100 / N
PRINT [IPRINT=*] 'Incorrect value ',N,' for N.'
prints an appropriate warning message for a zero or negative value of
N, and then exits from a procedure.
If the warning message is simply a text or string, the
EXPLANATION option can be used to print it on exit. For example
EXPLANATION='Incorrect value for N.'] N.LE.0
CALCULATE Percent = R * 100 / N
has the same effect except that the actual value of
N is no longer printed.
CONTROLSTRUCTURE option specifies the type of control structure from which to exit. The default setting is
for, causing an exit from a
FOR loop. For the other settings:
if causes an exit from a block-if structure (as introduced by the
case exits from a multiple-selection structure (as introduced by
procedure exits from a procedure (see the
PROCEDURE directive), and
job causes the entire job to be abandoned (see
JOB). Sometimes, to exit from one type of control structure, others must be left too. To exit from the procedure in the above example, requires Genstat to exit also from the block-if structure. Generally, Genstat does these nested exits automatically, as required. However, inside a procedure, you can exit only from
FOR loops and block-if or multiple-selection structures that are within the procedure. You cannot put, for example,
within a part of the procedure where there is no block-if in operation, and then expect Genstat to exit both from the procedure and from a block-if structure in the outer program from which the procedure was called. Genstat regards a procedure as a self-contained piece of program.
NTIMES option indicates how many control structures of the specified type to exit from. If you ask Genstat to exit from more structures than are currently in operation in your program, it will exit from as many as it can and then print a warning. If
NTIMES is set to zero or to missing value no exit takes place. If
NTIMES is set to a negative value, say –n, the exit is to the end of the nth structure of the specified type, counting them in the order in which their execution began. Consider this example:
"contents of the inner loop, including:"
"amongst other statements"
ENDFOR "end of the loop over D"
ENDFOR "end of the loop over C"
ENDFOR "end of the loop over B"
ENDFOR "end of the loop over A"
If the scalar
Nexit has the value 2, the exit is to the end of the loop over C; so the two exits are from the loop over
D and the loop over
C. But if
Nexit has the value -2 the exit is to the end of the loop over
B, as this is the second loop to have been started.
A further possibility when
EXIT is used within a
FOR loop is that you can choose either to go right out of the loop and continue by executing the statement immediately after the
ENDFOR statement, or to go to
ENDFOR and then repeat the loop with the next set of parameter values. To repeat the loop, you need to set option
REPEAT=yes. For example, suppose that variates
Weight contain information about children of various ages, ranging from five to 11. The
RESTRICT statement causes the subsequent
GRAPH statement to plot only those units of
Weight where the variate
EXIT statement ensures that the graph is not plotted if there are no units of a particular age; the program then continues with
Ageval taking the next value in the list.
RESTRICT Height,Weight; CONDITION=Age.EQ.Ageval
EXIT [REPEAT=yes] NVALUES(Height).EQ.0
GRAPH Height; X=Weight
REPEAT option can also be used within a procedures to ask Genstat to call the procedure with the next set of parameter settings.
The example of the heights and weights of children also illustrates the use of the parameter of
EXIT, to make the effect conditional. The parameter is an expression which must evaluate to a single number which Genstat interprets as a logical value. If the value is zero, the condition is false and no exit takes place; for other values the condition is true and the exit takes effect as specified. This is particularly useful for controlling the convergence of iterative processes: for example
CALCULATE Clim = X/10000
CALCULATE Previous = Root
& Root = (X/Previous + Previous)/2
PRINT Root,Previous; DECIMALS=4
EXIT ABS(Previous-Root) < Clim
will calculate the square root of
X to four significant figures.
Commands for: Program control.
" Example PROC-1: Defining a procedure" PROCEDURE 'SQUARERT' " Define the options & parameters of the procedure " OPTION NAME='PRINT','TRACE'; MODE=t; DEFAULT='no' PARAMETER NAME='X','ROOTX'; MODE=p " Check that the option settings are valid and set scalars Sprint and Strace to indicate whether they are set to yes " SCALAR Sprint,Strace FOR Setting=PRINT,TRACE; Sset=Sprint,Strace IF Setting .EQS. 'yes' CALCULATE Sset = 1 ELSIF Setting .EQS. 'no' CALCULATE Sset = 0 ELSE EXIT [CONTROLSTRUCTURE=procedure] ENDIF ENDFOR " Check for invalid setting of parameter X ( i.e. < 0 ) " IF X < 0 PRINT 'X < 0 : square root cannot be calculated' ELSE " Calculate convergence limit & initialize " CALCULATE Clim = X/10000 & ROOTX = X " Loop until convergence " FOR [NTIMES=20] CALCULATE Previous = ROOTX & ROOTX = (X/Previous + Previous)/2 IF Strace PRINT [IPRINT=*] ROOTX ENDIF EXIT ABS(Previous-ROOTX) < Clim ENDFOR IF Sprint PRINT [IPRINT=*] 'square root of ',X,' is ',ROOTX;\ JUSTIFICATION=left ENDIF ENDIF ENDPROCEDURE " Use the procedure" SCALAR Rx SQUARERT X=48; ROOTX=Rx PRINT Rx " Use it and set the option" SQUARERT [PRINT=yes] X=48; ROOTX=Rx SQUARERT [PRINT=yes; TRACE=yes] 81; ROOTX=Rx