ADDRESS environment [ command ]
ADDRESS [ VALUE ] expression
address directs commands to the proper external environment(s) for execution.
An address instruction with both environment and command coded specifies to which external environment that command is sent. An address instruction with an environment but no command specifies the default external environment for subsequent commands. An address instruction with neither environment nor command coded toggles the target environment between the last two specified or used.
The value format defines the target environment by way of the resolved expression for subsequent commands. value and command cannot be coded in the same statement. The purpose of the value format is to provide for programmability in determining the target environment for subsequent commands.
The environments that may be specified for command execution are system-dependent. Use the address() function to find out what the current environment is.
say address() /* displays the current command environment */
address system dir /* send the DIR command to the SYSTEM environment */
address command /* send all subsequent commands to the COMMAND environment */
‘dir’ /* as per the prior line of code, ‘dir’ is sent to the COMMAND environment */
The ANSI-1996 standard added a new format for the address instruction. Here is the template for this new format:
ADDRESS [ environment ] [ command ] [ redirection ]
ADDRESS [ [ VALUE ] expression [ redirection ] ]
redirection is: WITH INPUT input_redirection
and/or: WITH OUTPUT output_redirection
and/or: WITH ERROR output_rediection
input_redirection is: [ NORMAL | STREAM | STEM ] symbol
output_redirection is: [ APPEND | REPLACE ]
plus a destination: [ NORMAL | STREAM | STEM ] symbol
Optional extensions for the ANSI standard are fifo and lifo for the with input, with output and with error options.
Any, all or none of the three clauses with input, with output, and with error may be specified. They may be specified in any order. append or replace specify whether an output or error file will be appended to or over-written. replace is the default.
stream or stem specify whether an I/O stream or compound variable stem (an array) will provide the input or be written to as output or error. When using an array, element 0 should state the number of elements for input. Element 0 tells how many lines of output there are for output or error.
/* First, send an operating system SORT command to the SYSTEM environment.
Use file sortin.txt for input with output going to file sortout.txt. */
address SYSTEM sort WITH INPUT STREAM ‘sortin.txt’ , OUTPUT STREAM ‘sortout.txt’
/* Now send the SORT command to the SYSTEM environment, but use arrays for input and output. Specify both arrays as compound variable stems (include the period after the array name). Before issuing the command, you must set Element 0 in the input array to the number of items in the input array. After the command, the number of elements
in the output array will be in Element 0 of that array. */
in_array.0 = 10 /* 10 items are in the input array called in_array. */
/* They are in array positions in_array.1 thru .10. */
address SYSTEM sort WITH INPUT STEM in_array. OUTPUT STEM sortout.
say ‘Number of output elements:’ sortout.0
ARG [ template ]
The arg instruction parses arguments in the template in the same manner as: parse upper arg [ template ]
arg automatically translates all input arguments to uppercase.
/* function invoked by: testsub(‘a’,3,’c’) */
arg string_1, number_1, string_2
/* string_1 contains ‘A’, number_1 contains ‘3’, string_2 contains ‘C’ */
CALL name [ expression ] [, [ expression ] ] ...
CALL ON condition [ NAME trapname ]
CALL OFF condition
call either invokes a routine or enables an error condition. If on is specified, call enables the error condition and optionally specifies the name of the exception routine that will be invoked when it is raised. The condition must be one of error, failure, halt, and notready. Specifying off disables an error condition.
If neither on nor off is specified, call invokes an internal, built-in or external routine. Coding the routine name in quotes prevents searching for an internal routine. Zero, one, or more expression arguments may be passed to the routine.
If the routine returns a result, the special variable result is set to that value. Otherwise result is set to uninitialized.
call on error /* enables ERROR trap with routine of ERROR: */
call on error name error_handler /* enables ERROR to ERROR_HANDLER: */
call off error /* dis-ables ERROR trap */
call my_routine parm_1 , parm_2 /* call routine my_routine with 2 parameters */
/* if a result was returned, display it... */
if result <> ‘RESULT’ then say ‘The returned result was:’ result
DO [ repetitor ] [ conditional ]
[ instruction_list ]
END [ symbol ]
repetitor is: symbol = expression_i [ TO expression_t ]
[ BY expression_b ] [ FOR expression_f ]
condition is: WHILE expression_w
The do-end instruction groups multiple instructions together and executes them 0, 1, or more times. to, by, and for are optional and can be coded in any order. by expression_b is an increment that defaults to 1. for expression_f sets a limit for loop iterations if not terminated by some other constraint. forever defines an endless loop that must be terminated or exited by some internal instruction. while is a top-driven structured loop, and until defines a bottom-driven unstructured loop. Loop control variables can be altered from within the loop and the leave, iterate, signal, return, and exit instructions may also modify loop behavior.
if a = 2 then do /* a simple do-end pair to group multiple */
say ‘a is 2’ /* instructions into one for the IF instruction */
/* we assume all DO’s below have a body and END. We just show the DO here. */
do 40 /* executes a loop 40 times */
do j = 1 to 40 /* executes a loop 40 times (BY 1 is implied) */
do while counter < 30 /* do-while with a condition specified */
do while (counter < 30 & flag = ‘NO’) /* multiple conditions specified */
do forever /* codes an endless loop... better have an
unstructured exit inside the loop ! */
DROP symbol [ symbol ... ]
drop “unassigns” one or more variables or stems by setting them to uninitialized.
a = 55
say a /* writes ‘A’ because this symbol is uninitialized */
EXIT [ expression ]
exit unconditionally terminates a program and optionally returns the single value defined by expression to the caller.
exit 1 /* unconditional termination, sends ‘1’ to environment */
exit /* unconditional termination with no return code */
IF expression [;] THEN [;] instruction [ ELSE [;] instruction ]
if conditionally executes a “branch” of instruction(s). The expression must evaluate to either 0 or 1. The else always matches to the nearest unmatched if. To execute more than one instruction after the then or else, use a do-end pair, such as: then do . . . end or else do . . . end. To code a branch with no instructions, use the nop instruction.
if b = 1 then say ‘B is 1’ /* a simple IF instruction */
else say ‘B is not 1’
if b = 1 then do /* THEN DO and ELSE DO are required */
say ‘B is 1’ /* to execute more than 1 instruction */
say ‘TRUE branch taken’ /* in a branch. */
end /* END terminates a logical branch. */
say ‘B is not 1’
say ‘FALSE branch taken’
interpret executes instructions that may be built dynamically within the expression. The expression is evaluated, then executed. The expression must be syntactically complete; for example, a do must include a matched end. interpret is useful for creating self-modifying scripts. Set trace r or trace i if experiencing problems with interpret.
interpret say ‘Hi there’ /* interprets (executes) the SAY instruction */
ITERATE [ symbol ]
iterate alters the flow of control within a do loop by passing control directly back to the do instruction of that loop. This skips any subsequent instructions encoded south of the iterate instruction within that execution of the do loop.
do j = 1 by 1 to 3 /* This displays 1 and 3, but not 2. */
if j = 2 then iterate /* The ITERATE instruction skips displaying 2. */
LEAVE [ symbol ]
leave alters the flow of control within a do loop by immediately passing control directly to the instruction following the end clause. This causes an unstructured exit from the do loop. Whereas iterate sets the loop to start on a new iteration, leave exits the loop.
do j = 1 by 1 to 3 /* This displays 1, then ‘Hello.’ The LEAVE */
if j = 2 then leave /* instruction exits the loop when j = 2. */
nop means “no operation.” It can be used within an if statement to code a branch with no action taken.
if flag = ‘YES’
then nop /* no action taken when FLAG = ‘YES’ */
else say ‘flag is NO’
NUMERIC DIGITS [ expression ]
FORM [ SCIENTIFIC | ENGINEERING | [ VALUE ] expression ]
FUZZ [ expression ]
The numeric instruction controls various aspects of numeric calculation. digits set the number of significant digits; it defaults to 9. form sets the form in which exponential numbers are written; it defaults to scientific. fuzz controls how many digits will be ignored during comparisons; it defaults to 0.
Use the digits(), form() and fuzz() functions to find out the current values for these numeric settings.
numeric digits 12 /* Set precision to 12 significant digits. */
say digits() /* This will now display: 12. */
numeric form engineering /* Display exponential numbers in engineering format. */
say form() /* This will now display: ENGINEERING. */
numeric fuzz 1 /* 1 digit will be ignored during comparisons. */
say fuzz() /* will now display: 1 */
Note that the example code above is run in sequence:
options passes commands to the interpreter. It can be used to alter the behavior of the Rexx interpreter or its defaults. The options allowable are strictly implementation-dependent. Interpreters ignore any options they do not recognize. This is good because it means implementation-dependent coding on this statement runs under other interpreters. But it also means that you must check to see whether the options you coded were implemented or ignored.
options 4.00 vm_compatible /* The two options ‘4.00’ and ‘vm_compatible’ */
/* may each be set, or ignored, depending */
/* on whether the Rexx interpreter we are */
/* using recognizes them. */
PARSE [ UPPER ] type [ template ]
where type is: [ ARG | LINEIN | PULL | SOURCE | VERSION ]
VALUE [ expression ] WITH
parse assigns values to one or more variables from various data sources according to parsing rules and its template. If upper is specified, all input values are translated to uppercase.
ARG — Parses input values to this routine
LINEIN — Reads a line from the default input stream and parses it into variable(s)
PULL — Reads a line from the stack, or it is empty, from the default input stream and parses this string into variable(s)
SOURCE — Reads three words of system-dependent information:
system how_the_script_was_invoked filename_of_the_script
VERSION — Reads five words of system-dependent information:
language level date month year
VALUE expression WITH — Evaluates the expression and then parses it
VAR symbol — Parses the string in symbol
parse arg a, b /* internal routine reads its parameters */
parse linein /* reads a line from default input stream */
parse pull a /* reads A from the stack or input stream */
/* parse the return from the DATE function */
parse value date() with dd mmm yyyy
say dd mmm yyyy /* displays something like: 15 Jun 2005 */
string = ‘ a b’ /* parses STRING, displays: a b */
parse var string c d
say c d
/* retrieve and display system information */
parse source system how_called filename
say system how_called filename
parse version language level date month year
say language level date month year
PROCEDURE [ EXPOSE variable_list ]
The procedure instruction makes all variables of the caller unavailable to this one. If it is not coded, all the caller’s variables are available to this routine (they are global). If procedure is coded with the expose keyword, only the variables listed after the expose keyword are available to this routine. Exposed variables are accessible for both reading and updating by the routine.
my_sub: procedure /* No caller variables are available to my_sub. */
my_sub: /* ALL caller variables are available to my_sub. */
my_sub: procedure expose a b /* a and b only are available to my_sub. */
PULL [ template ]
pull reads a line from the stack, or if none is available, reads a line from the default input stream. pull parses the input according to the template and always translates all arguments to uppercase. pull is equivalent to:
parse upper pull [ template ]
/* reads one line from the stack, or reads */
/* input from the user if the stack is empty. */
/* waits for input to read if necessary. */
/* always translates to all uppercase letters */
PUSH [ expression ]
Adds a line to the external data queue or stack, in the order last-in, first-out (LIFO). Use the queued() function to determine how many elements are on the stack at any time.
push line /* pushes LINE onto the stack LIFO */
QUEUE [ expression ]
Adds a line to the external data queue or stack, in the order first-in, first-out (FIFO). Use the queued() function to determine how many elements are on the stack at any time.
queue line /* places LINE onto the stack FIFO */
RETURN [ expression ]
Returns control from a program or internal routine to its caller, optionally passing the single result of expression.
return /* return with no result */
return 4 /* return with result of: 4 */
SAY [ expression ]
Writes a line to the default output stream, after evaluating expression. Using say is the same as coding:
call lineout , [expression]
say ‘Hi’ /* displays: Hi */
say ‘Hi’ ‘there’ /* displays: Hi there */
SELECT ; when_part [ when_part ... ] [ OTHERWISE [;] statement ... ] ] END ;
when_part is: WHEN expression [;] THEN [;] statement
select implements the Case construct for determining the flow of control. Only the first when condition that evaluates to true( 1 ) executes. otherwise executes if none of the when conditions are true. If no otherwise is provided and none of the when conditions is true, a syntax error results. We recommend always coding an otherwise clause.
when input = ‘yes’ then do
say ‘branch 1’
when input = ‘no’ then do
say ‘branch 2’
say ‘user is crazy’
end /* select */
SIGNAL [ VALUE ] expression
SIGNAL ON condition [ NAME trapname ]
SIGNAL OFF condition
signal either causes an immediate unstructured transfer of control to the label at label_name, or enables or disables an error condition. If on is specified, signal enables the error condition and optionally specifies the name of the routine invoked when it is raised. The condition must be one of error, failure, halt, novalue, notready, or syntax. The ANSI-1996 standard adds the new condition lostdigits. Specifying off disables an error condition.
If neither on nor off is specified, signal directly transfers control to the label of label_name, rather like the goto of other computer languages. Any active do, if, select, and interpret instructions are terminated. The value keyword allows transfer of control to a label whose name is determined at execution time.
signal on error /* enables ERROR trap with routine of ERROR: */
signal on error name error_handler /* enables ERROR to ERROR_HANDLER: */
signal off error /* disables ERROR trap */
signal goto_place /* immediately goes to the label goto_place: */
TRACE trace_setting | [ VALUE ] expression
trace_setting is any of these flags:
A — All
C — Commands
E — Errors
F — Failure
I — Intermediates
L — Labels
N — Normal
O — Off
R — Results
? — Toggles interactive tracing on or off; can be followed by any letter in this list only.
A positive whole number — If in interactive trace, skips the number of pauses specified
A negative whole number — Inhibits tracing for the number of clauses specified
Sets the trace level for debugging. Multiple trace instructions may be placed within a script, altering the trace level at will. Setting it to a positive or negative whole number during interactive tracing skips or inhibits tracing for that number of pauses or clauses.
Use the trace() function to retrieve the current setting for the trace level.
say trace() /* displays the current trace setting */
trace a /* turn on TRACE ALL */
trace ?I /* turn on interactive trace with setting of I */