REXX has instructions such as DO, IF, and SELECT for program control. Here is a typical REXX IF instruction:
if a>1 & b<0 then do say "Whoops, A is greater than 1 while B is less than 0!" say "I'm ending with a return code of 99." exit 99 end
C programmers will notice that the REXX relational operator for a logical AND is different from the operator in C (which is &&). Other relational operators differ as well, so you'll want to review the appropriate section in the Object REXX Reference. For now, here's a list of some common comparison operators and operations:
Note: Throughout the language, the NOT character, ¬, is synonymous with the backslash (\). You can use the two characters interchangeably, according to availability and personal preference. The backslash can appear in the \ (prefix not), \=, and \== operators.
A character string is taken to have the value false if it is 0, and true if it is 1. The logical operators take one or two such values (values other than 0 or 1 are not allowed) and return 0 or 1 as appropriate:
&
Note: On ASCII systems (for example, IBM PS/2 systems), REXX recognizes the ASCII character encoding 124 as the logical OR character. Depending on the code page or keyboard you are using for your particular country, the logical OR character may be shown as a solid vertical bar (|) or a split vertical bar (▌). The appearance of the character on your screen may not match the character engraved on the key. If you are receiving error 13, invalid character in program, on an instruction including a vertical bar character, make sure this character is ASCII character encoding 124.
Using the wrong relational or comparison operator is a common mistake when switching between C and REXX. You'll also notice that the familiar C language braces { } are not used in REXX for blocks of instructions. Instead, REXX uses DO/END pairs. The THEN keyword is always required.
Here is an IF instruction with an ELSE:
if a>1 & b<0 then do say "Whoops, A is greater than 1 while B is less than 0!" say "I'm ending with a return code of 99." exit 99 end else do say "A and B are okay." say "On with the rest of the program." end /* if */
You can omit the DO/END pairs if only one clause follows the THEN or ELSE keyword:
if words(myvar) > 5 then say "Variable MYVAR has more than five words." else say "Variable MYVAR has fewer than six words."
REXX also supports an ELSE IF construction:
count=words(myvar) if count > 5 then say "Variable MYVAR has more than five words." else if count >3 then say "Variable MYVAR has more than three, but fewer than six words." else say "Variable MYVAR has fewer than four words."
The SELECT instruction in REXX is similar to the SELECT CASE statement in Basic and the switch statement in C. SELECT executes a block of statements based on the value of an expression. REXX's SELECT differs from the equivalent statements in Basic and C in that there isn't an expression following the SELECT keyword itself. Instead, expressions are placed on WHEN clauses:
select when name='Bob' then say "It's Bob!" when name='Mary' then say "Hello, Mary." otherwise end /* select */
The WHEN clauses are evaluated in order. When one of the expressions is true, the statement (or block of statements) is executed. All the other blocks are skipped, even if their WHEN clauses would have evaluated to true. (C programmers take note: statements like C's break statement are not needed.)
Notice that an OTHERWISE keyword is used even though no instructions follow it. REXX doesn't require an OTHERWISE clause. However, if none of the WHEN clauses evaluates to true and you omit OTHERWISE, an error occurs. You can reduce the risk of errors by making a habit of including an OTHERWISE.
As with the IF instruction, you can use DO/END pairs for multiple clauses within SELECT cases. You don't need a DO/END pair if multiple clauses follow the OTHERWISE keyword:
select when name='Bob' then say "It's Bob" when name='Mary' then do say "Hello Mary" marycount=marycount+1 end otherwise say "I'm sorry. I don't know you." anonymous=anonymous+1 end /* select */
Many Basic implementations have several different instructions for loops. In REXX, there is only the DO/END pair. All of the traditional looping variations are incorporated into the DO instruction:
do i=1 to 10 /* Simple loop */ say i end do i=1 to 10 by 2 /* Increment count by two */ say i end b=3; a=0 /* DO WHILE -- the conditional expression */ do while a<b /* is evaluated before the instructions */ say a /* in the loop are executed. If the */ a=a+1 /* expression isn't true at the outset, */ end /* instructions are not executed at all. */ a=5 /* DO UNTIL -- like many other languages, */ b=4 /* a REXX DO UNTIL block is executed at */ do until a>b /* least once. The expression is */ say "Until loop" /* evaluated at the end of the loop. */ end
REXX also has a FOREVER keyword. Use the LEAVE, RETURN, or EXIT instructions to break out of the loop:
/* Program to emulate your 5 year old child */ num=random(1,10) /* To emulate a three year old, move this inside the loop! */ do forever say "What number from 1 to 10 am I thinking?" pull guess if guess=num then do say "That's correct" leave end say "No, guess again..." end
REXX also includes an ITERATE instruction that's quite handy. It skips the rest of the instructions in that iteration of the loop:
do i=1 to 100 /* Iterate when the 'special case' value is reached */ if i=5 then iterate /* Instructions used for all other cases would be here */ end
You can use loops in IF or SELECT statements:
/* Say hello ten times if I is equal to 1 */ if i=1 then do j=1 to 10 say "Hello!" end
Basic programmers may be wondering if there is an equivalent to the GOTO statement. There is. You can use a REXX SIGNAL instruction. SIGNAL causes control to branch to a label:
Signal fred; /* Transfer control to label FRED below */ .... .... Fred: say 'Hi!'
As with GOTO, you need to be careful about how you're using SIGNAL. In particular, you should not try to signal into the middle of a DO/END block or into a SELECT structure.