| REXX Workshop - Part 2 |
The following sections introduce the most commonly used REXX instructions. Please refer to other documentation for more details about those instructions which are covered as well as those which are not covered.
The following REXX instructions can be used to alter the sequence in which program statements are executed.
/* Example of using the CALL Instruction */
.
.
.
Call TOTALUP /* "TOTALUP is a subroutine. */
next instruction
.
.
.
Exit
TOTALUP: /* Subroutines start with labels. */
.
.
.
Return /* Return control to the main line. */
/* The main line "falls into" the subroutine.*/
.
.
.
Call TOTALUP
.
.
last statement of main line
TOTALUP: /* TOTALUP starts here. */
.
.
.
Return /* End of TOTALUP subroutine. */
To prevent TOTALUP from being executed incorrectly, place an EXIT instruction at the end of the main line, as in the following example.
/* Example of using the EXIT Instruction */
.
.
.
Call TOTALUP
next instruction
.
.
.
Exit /* Exit terminates the program. */
TOTALUP: /* The subroutine is protected. */
.
.
.
Return
/* Example of using the SIGNAL instruction */
.
.
.
Signal SUMS /* Transfer control to SUMS. */
statement not executed
.
.
.
SUMS: /* This statement receives control. */
statement executed
.
.
.
If expression
Then statement1
Else statement2
/* Example of a simple IF instruction */
x = 2
If x = 1 /* Since x=2 */
Then y = 1 /* statement is bypassed; */
Else y = 2 /* statement is executed. */
/* Example of a simple IF without ELSE */
x = 2
y = 2
If x = 1 /* Since x=2 */
Then y = 1 /* statement is bypassed; */
/* Example of a IF and THEN on same line */
x = 2
y = 2
If x = 1 Then y = 1
/* Example of nested IF instructions */
x = 2
If x = 1
Then y = 1
Else If x = 2
Then y = 2
Else y = 3
Complex decision trees created with nested IF instructions is possible,
but difficult to interpret. Instead, try using the SELECT statement.
Select;
When expression1
Then statement1
When expression2
Then statement2
When expression3
Then statement3
Otherwise statement4
End
The following exec uses the SELECT instruction to translate a number into a color.
/* Example using the SELECT instruction */
Pull n
Select;
When n = 1
Then color = 'RED'
When n = 2
Then color = 'WHITE'
When n = 3
Then color = 'BLUE'
Otherwise color = 'UNKNOWN'
End
Say "The color you specified is" color"."
Exit
/* Example using the NOP insruction */
color = 'UNKNOWN'
Pull n
Select;
When n = 1
Then color = 'RED'
When n = 2
Then color = 'WHITE'
When n = 3
Then color = 'BLUE'
Otherwise NOP
End
Say "The color you specified is" color"."
Exit
Do
statement1
statement2
statement3
End
To execute a DO group several times, add a repetitor clause to the DO instruction to indicate how many times the loop should execute. In the simplest case, the repetitor clause is a simple number, variable with a numeric value, or an expression that evaluates to a number.
Do 5
statement1
statement2
statement3
End
or
Do n - 1
statement1
statement2
statement3
End
Do i = 1 To 6 /* Loops 6 times */
statement1
statement2
statement3
End
or
Do i = 9 To 1 By -1 /* Loops 9 times */
statement1
statement2
statement3
End
Do While (n < 6) /* Loops if n less than 6 */
statement1
statement2
statement3
End
Do While (n < 6) /* Loops if n less than 6 */
statement1
statement2
statement3
n = n + 1
End
n = 10
Do Until (n > 6) /* Loops until n greater than 6 */
statement1
statement2
statement3
End
Do While (n < 6)
x = y + 3
Do i = x To 5
statement
statement
Do Until (x > 7)
statement
statement
End
End
statement
End
Do i = 1 To 10
statement1
statement2
statement3
End i
/* Loops */
Say 'Enter a number:'
Pull n
Do n
Say 'Hello number' n
End
Exit
Do n = 1 To 10
If n = 5 Then Iterate /* Skips when n = 5 */
Say n
End
NEXTSTATEMENT:
Do n = 1 To 10
If n = 5 Then Leave /* Ends looping when n = 5 */
Say n
End
NEXTSTATEMENT:
TOTALUP:
statement1
statement2
statement3
.
.
.
Return(0)
Procedures
can share variables with the main line or can use completely separate
copies of variables. Arguments can be passed to procedures when
those procedures are invoked; single value "results" can be returned
to the main line.
Procedures come in two flavors, subroutines and functions.
Subroutines are invoked by name with the CALL statement:
Call name list-of-arguments
for example:
Call TOTALUP nmen,nwomen,nchildren
Functions are also invoked by name, but use a different syntax:
x = name(list-of-arguments)
for example:
x = TOTALUP(nmen,nwomen,nchildren)
i = 100 /* variable i in main line */
x = TOTALUP(nmen,nwomen,nchildren)
.
.
.
Exit
TOTALUP:
i = 1 /* changes variable i in main line */
sum = 0
.
.
.
Return(sum)
i = 100 /* variable i in main line */
x = TOTALUP(nmen,nwomen,nchildren)
.
.
.
Exit
TOTALUP:
Procedure
i = 1 /* variable i known only to procedure */
sum = 0
.
.
.
Return(sum)
i = 100 /* variable i in main line */
x = TOTALUP(nmen,nwomen,nchildren)
.
.
.
Exit
TOTALUP:
Procedure Expose nmen nwomen nchildren
i = 1 /* variable i known only to procedure */
sum = 0
.
.
.
Return(sum)
TOTALUP:
Procedure Expose nmen nwomen nchildren
i = 1
sum = 0
.
.
.
Return(sum)
Supply a result or return value on the RETURN
instruction.
TOTALUP:
Procedure Expose nmen nwomen nchildren
i = 1
sum = 0
.
.
.
Return(sum)
When a procedure is invoked using the CALL instruction, then the returned value is stored in a special variable named RESULT.
i = 100
Call TOTALUP nmen,nwomen,nchildren
Say RESULT /* Returned value "sum" is stored in "RESULT" */
.
.
Exit
TOTALUP:
Procedure Expose nmen nwomen nchildren
i = 1
sum = 0
.
.
.
Return(sum)
When a procedure is invoked as a function, then the function call is replaced by the returned value before the invoking statement is fully evaluated.
i = 100
x = TOTALUP(nmen,nwomen,nchildren)
Say x
.
.
Exit
TOTALUP:
Procedure Expose nmen nwomen nchildren
i = 1
sum = 0
.
.
.
Return(sum)
i = 100
x = TOTALUP(nmen,nwomen,nchildren)
Say x
.
.
Exit
TOTALUP:
Arg men women children
i = 1
sum = 0
.
.
.
Return(sum)
Push -->. .---> Pull
| |
--------
| data |
--------
| data |
--------
| data |
--------
| data |
--------
|
|
Queue -->'
The examples below deal with only
the simplest case, the one in which a single piece of data is
stored into and retrieved from the program stack.
.
.
.
Push 'Save the whales!'
.
.
.
.
.
.
Pull message /* "message" contains the string */
.
.
.
Note: Used in this way, PULL translates the stacked data to uppercase
before returning it to the variable.
.
.
.
Push 'Save the whales!'
Push 'Save the day!'
.
.
.
To place several strings onto the program stack so that they can be
retrieved in order (first-in-first out), use the QUEUE instruction.
.
.
.
Queue 'Save the whales!'
Queue 'Save the day!'
.
.
.
.
.
.
Queue 'Save the whales!'
Queue 'Save the day!'
x = Queued() /* How many strings are queued? */
.
.
Do While (n < 6)
x = y + 3
Do i = x To 5
Say i
statement
statement
Do Until (x > 7)
Say 'x='x
statement
statement
End
End
statement
End
The following basic format has proved quite useful.
Trace air
Do While (n < 6)
x = y + 3
Do i = x To 5
statement
statement
End
statement
End
Trace off
The CMS Help file on TRACE (HELP REXX TRACE) provides details about
a number of options.