Program Control

Rexx has instructions such as DO, LOOP, IF, and SELECT to control your program. Here is a typical Rexx IF instruction:


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

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 may want to review the appropriate section in the Open Object Rexx: Reference .

Here is a list of some Rexx comparison operators and operations:

= True if the terms are equal (numerically, when padded, and so on)
\\=, <>= True if the terms are not equal (inverse of =)
> Greater than
< Less than
<> Greater than or less than (same as not equal)
>= Greater than or equal to
<= Less than or equal to
== True if terms are strictly equal (identical)
\\==, <>== True if the terms are NOT strictly equal (inverse of ==)
Note

Throughout the language, the NOT character, <>, is synonymous with the backslash (\\). You can use both characters. The backslash can appear in the \\ (prefix not), \\=, and \\== operators.

A character string has the value >false if it is 0, and true if it is 1. (These values are sometimes called logical or boolean values and can be optionally expressed in programs with the ooRexx environment symbols .false which returns 0 and .true which returns 1. Environment symbols in ooRexx start with a dot.)

A logical operator can take at least two values and return 0 or 1 as appropriate:

& AND - returns 1 if both terms are true.
¦ Inclusive OR - returns 1 if either term or both terms are true.
&& Exclusive OR - returns 1 if either term, but not both terms, is true.
Prefix \\,<> Logical NOT - negates; 1 becomes 0, and 0 becomes 1.
Note

On ASCII 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 is shown as a solid vertical bar (¦) or a split vertical bar (¦). The appearance of the character on your screen might not match the character engraved on the key. If you receive error 13, invalid character in program, on an instruction including a vertical bar, 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. 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 and ELSE instructions
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 and ELSE instructions
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:


ELSE IF instruction
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 the SELECT keyword is not followed by an expression. Instead, expressions are placed in WHEN clauses:


SELECT instruction
select
when name="Bob" then
say "It's Bob!"
when name="Mary" then
say "Hello, Mary."
otherwise
end /* select */

WHEN clauses are evaluated sequentially. 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. Notice that statements like the break statement in C are not needed.

The OTHERWISE keyword is used without an instruction following it. Rexx does not require an OTHERWISE clause. However, if none of the WHEN clauses evaluates to true and you omit OTHERWISE, an error occurs. Therefore, always include an OTHERWISE.

As with the IF instruction, you can use DO/END pairs for several clauses within SELECT cases. You do not need a DO/END pair if several clauses follow the OTHERWISE keyword:


SELECT and OTHERWISE instructions
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. Rexx has the DO/END and LOOP/END pair. All of the traditional looping variations are incorporated into the DO and LOOP instructions, which can be used interchangeably for looping:


DO and LOOP instructions
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 ab /* least once. The expression is */
say "Until loop" /* evaluated at the end of the loop. */
end

or, using LOOP

loop i=1 to 10 /* Simple loop */
say i
end
loop i=1 to 10 by 2 /* Increment count by two */
say i
end
b=3; a=0 /* LOOP WHILE - the conditional expression*/
loop 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 /* LOOP UNTIL - like many other languages,*/
b=4 /* a Rexx LOOP 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:


DO FOREVER instruction
/* Program to emulate your five-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 of?"
pull guess
if guess=num then do
say "That's correct"
leave
end
say "No, guess again..."
end

Rexx also includes an ITERATE instruction, which skips the rest of the instructions in that iteration of the loop:


ITERATE instruction
loop 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 instructions:


ITERATE instruction
/* Say hello ten times if I is equal to 1 */
if i=1 then
loop j=1 to 10
say "Hello!"
end

There is an equivalent to the Basic GOTO statement: the Rexx SIGNAL instruction. SIGNAL causes control to branch to a label:


SIGNAL instruction
Signal fred; /* Transfer control to label FRED below */
....
....
Fred: say "Hi!"

As with GOTO, you need to be careful about how you use SIGNAL. In particular, do not use SIGNAL to jump to the middle of a DO/END block or into a SELECT structure.