Program Control

Rexx has instructions such as DO, LOOP, IF, and SELECT to control your program. 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

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

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
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 knows 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 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

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:

                  /* 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:

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:

/* 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 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 the middle of a DO/END block or into a SELECT structure.