GO BACK     Copyright (c) Kyla Computing Ltd 2002

REXX: THE LANGUAGE

INTRODUCTION

INSTRUCTIONS

CONDITIONS

LOOPS

OTHERS

ABOUT TUTOR INTRODUCTION SAY COMMENTS LAYOUT RULES LITERAL STRINGS ABUTTAL CONCATENATION

ASSIGNMENT VARIABLES ARITH. OPS EXPRESSION PULL

COMPARISONS
IF THEN ELSE
IF DO-END
STRICT COMPS.
LOGICAL COMP.
NOT OPERATOR
SELECT

DO LOOPS
WHILE
UNTIL
LEAVE
ITERATE
FOREVER

INTERPRET
FUNCTIONS
ARG
RESULT

SECTION INDEX

INTRODUCTION

STRING FUNCTIONS

OTHER FUNCTIONS

PARSE EDITOR

INTRODUCTION
INSTRUCTIONS
CONDITIONS
LOOPS
OTHERS

ALIGNMENT
COMPARISON
COMBINING
EXTRACTION
SEARCH
OTHER

WORD
NUMBER
CONVERSION
BIT
PROGRAM

PARSE


TOP . . NEXT . . SECTION INDEX . . FUNCTION-LIST . .

1.1 Introduction to tutorial and REXX.

Welcome to my REXX tutor! It's here for you to use. Most of the data comes from a training course I perform (and I mean perform) at Computer Associates Training centre in Slough. If you want to attend the course please contact them on (01753) 577733. If you just want to play yourself please go ahead and enjoy it. Most of the examples in this tutorial have been executed on an Amiga, this is for 2 reasons, first it comes free with the machine and second it's the most amazing machine in the history of PCs and I still hate using anything else. I'll take it to my grave if necessary. Anyway enjoy it all, this is yours to keep for free! (That old fashioned word.) By the way if you haven't a clue what to look for because you're here to learn and you don't know what you need to know, then I would start here at the beginning and just grind your way down this whole file! - Good luck. Jim Barry of Kyla Computing ltd.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Comments

Comments always start /* and end */.
Top line Comment
If you thought that comment cards were optional you were wrong. On most platforms you must code a comment as the first line of your code. On some you even need to include the word REXX in this line.
Section Descriptions
Comments are important if you expect to alter your program in the future. There is a popular belief that you will remember your own code. Well just try writing a program without comments and returning to it two weeks later! Even very well written code is much easier to read when sectioned by comment lines describing what each block of code is doing.
Commenting out code.
Another purpose for comments is when you have code, which you do not want to execute. Note that it is alright to have a comment within a comment in most platforms (sometimes a compile option).


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

SAY instruction

 template: SAY expression
 examples:   SAY "print this line"
                     SAY "Contents of A=" A

Why the word SAY and not the word PRINT I just don't know? All its doing is printing! If you don't know what I mean by EXPRESSIONS then look up that definition. Note that SAY on its own will print a blank line.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Layout rules.

There really are very few rules when it comes to coding REXX. However it is important to understand the few that there are.

  • The system presumes that each line is a new instruction unless you state you are continuing on another line by the use of a comma (we will see this in a minute).
  • If you want two instructions on one line you will need to put a semi-colon between them.
  • You can indent your instructions as much as you like; this is very useful when you are coding loops.
  • You can also have as many blank lines as you like. These can be used to section your code and make it far more readable.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Literal Strings.

 /* REXX program. Detailing Literals */
 SAY "A Literal strings is a constant."
 SAY 'Its delimiter can be single or '
 SAY 'double quotes, which is "Useful".'
 SAY "To continue on a second line",
 "just end with a comma."
 SAY 'We''ll see here two quotes together'
  ---------------------------------------------
  A Literal strings is a constant.
  Its delimiter can be single or
  double quotes, which is "Useful".
  To continue on a second line just end with a comma.
  We'll see here two quotes together

These will litter your program. These really are important. You use them anywhere you want a CONSTANT. These are numbers or strings of letters, which will not change during the execution of the program.
Delimiters
Being able to use both double and single quotes as the delimiters is extremely clever and powerful. In the example you can see that both double and single quotes have been included in some of the literals. In each case the other type of quote has been use d as the delimiter. The other way you can code double or single quote within the string is by coding two next to each other, these will be printed as just one and it doesn't mean that its the end of the string.
Continuation
As with any command if you wish to continue on the next line a comma is put at the end of the line. Note that there is no SAY instruction on the second line and the comma is outside the delimiters.
Maximum length
The maximum length of a literal is platform specific but it will be at least 100 bytes and normally considerably more.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Concatenation and Abuttal.

 /* REXX program. Concatenation & Abuttal */
 SAY "When two literals are" "put next to each"
 SAY "other they're printed" "with a single"
 SAY "space between then"
  SAY "To print without" || "gaps use these."
  SAY "This is called" || " ABUTTAL"
  ----------------------------------------
  When two literals are put next to each
  other there printed with a single
  space between then
  To print withoutgaps use these.
  This is called ABUTTAL


Concatenation
A very important concept it the automatic concatenation that applies within REXX. This is not only used for printing but in lots of other situations. The basic idea is that if you put two things (TOKENS) next to each other (in this example two literal strings), then they will be connected with a space. Note that they are always joined by one space regardless of how many spaces there are between the literal strings.
Abuttal
If you do not wish to have a space between the two tokens you must code two vertical lines (OR symbol). This system can apply to numbers as well, we haven't looked at these yet but what do you think A would equal here?

         A = 5 || 7


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

1.2 Basic Instructions

Assignment Instructions.

 /* REXX program. ASSIGNMENT Instructions.     */
  SAY "An assignment instruction is where tokens are"
  SAY "are used to change the contents of a variable."
  A = 2 + 3
  SAY A "is the result of '2 + 3'"
  B = A * 2
  SAY B "is" A "times '2'"
  ----------------------------
  An assignment instruction is where tokens are
  are used to change the contents of a variable.
  5 is the result of '2 + 3'
  10 is 5 times '2'

Assignment instructions are used to change the contents of variables. Variables can be thought of as pigeonholes in the system where letters or a number can be held. We will deal with these in more details later. For now look at the example, Here the instruction A = 2 + 3 is adding two CONSTANTS and putting the result in the VARIABLE called A. Assignment instructions always have an equal sign in them and the name of a variable to the left of this. On the right of the equals sign are EXPRESSIONS and OPERATORS. In these examples the expressions are either single variables or constants but they can be far more complex. What do you think the contents of B would in after the following instructions?

 		A = 45
           B = A || 1  +  3


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Simple Variables

 /* REXX program. Introducing SIMPLE VARIABLES. */
  SAY "Simple variable names can contain these chars."
  SAY "A - Z, a - z, 0 - 9, !, ?, #, $, @ & _ "
  SAY "0 - 9 can not be used for the first character."
  SAY "All lowercase chars. are converted to uppercase."
  SAY "Variables are initialized with their name!"
  TOTAL_a = 12 ;  Text    = "Page No." ;  Page#   = 1 + TOTAL_A
  SAY ;    SAY TOTAL_a "  " Text || Page# "  " NEW_var
  ----------------------------
  Simple variable names can contain these chars.
  A - Z, a - z, 0 - 9, !, ?, #, $, @ & _
  0 - 9 can not be used for the first character.
  All lowercase chars. are converted to uppercase.
  Variables are initialized with their name!
  12    Page No.13    NEW_VAR


Naming Convention
There are rules on the name of your variables. These are detailed in the example. There are several points worth noting. If your name contains lower case characters then these are automatically converted into capitals. See here how the variable TOTAL_a is used in one line and on the next it is referred to a TOTAL_A. Doing this for real would be considered a very sloppy habit but its quite legal (like a lot of sloppy habits).
Initialized Value
This is something worth remembering, in REXX you can use a variable even if you have not given it a value. In the example here we have only used NEW_var on a SAY statement. So what does it print? The answer is its own name (in capitals of course).
Data Type
Another rather weird thing about REXX is that you do not have to tell it whether your variable is going to contain a string of characters or a number - it just doesn't care!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Arthimetic Operartors

 /* REXX program ARITHMETIC operators.   */
  SAY "ADD:     5 +  2 =" 5 +  2 ; SAY "SUBTRACT:2 -  5 =" 2 -  5
  SAY "MULTIPLY:5 * -2 =" 5 * -2 ; SAY "DIVIDE:  5 / +2 =" 5 / +2
  SAY "INT. DIV.5 %  2 =" 5 %  2 ; SAY "REMAINER:5 // 2 =" 5 //  2
  SAY "POWER:   5 ** 2 =" 5 **  2
  SAY "ABUTTAL:5 || 2'00' =" 5 || 2'00'
  SAY "USE BRACKETS FOR PRIORITY:" 7 || ((2 + 5) * 5)/3
  ----------------------------
  ADD:     5 +  2 = 7
  SUBTRACT:2 -  5 = -3
  MULTIPLY:5 * -2 = -10
  DIVIDE:  5 / +2 = 2.5
  INT. DIV.5 %  2 = 2
  REMAINER:5 // 2 = 1
  POWER:   5 ** 2 = 25
  ABUTTAL:5|| 2'00' = 5200
  USE BRACKETS FOR PRIORITY: 711.6666667


Operators
Here you can see the different mathematical operators available. It all looks pretty straight forward until you come down to ABUTTAL - what is this doing here you may say? Well I said you could use concatenations for more than just pretty SAY statements! Two types of abuttal are used here, one using the '||' symbol and the other is achieved by typing the CONSTANT next to the literal string. We haven't seen this method of abuttal before. Note the last number in the example 711.666667, the precision here means we get a total of 9 digits. This is an environmental option which we can change with the NUMERIC keyword we'll see this later.
Operator Priorities & Brackets
These can get silly, I say that because we could spend a lot of time learning them and then writing very fancy code which works and is very clever. Clever but unreadable when two months later when you can't remember which operator has priority over its neighbour. The solution is simple use brackets even when they may not be needed! If you want to be an anorak here are the priorities, when two are the same, the priority is from left to right.

 8] + - (as a prefix) 5] + - (not as a prefix)
  7] **                   4] Abuttal.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Expresssions

What is an expression?
Simply its several bits of code which will be used to work out one thing, that 'thing' may be a literal string or a number. Let's take an assignment instruction for example

 OUTLINE = 'The Total is =' L * 2 + W * 2 + ExtraBit

Everything here except the OUTLINE = is one expression. It contains constants, literal strings, arithmetic operators and variables but all the values will be shrunk down to one literal string that in this case will be put into the variable called OUTLINE. We could however print it by coding SAY at the beginning rather than OUTLINE =. Later we will look at functions and the arguments, which are their inputs. Normally we have just a single variable as an argument but in fact it will take a very large and complex expression. In summary an expression can be:

  • Everytime to the right of a SAY instruction
  • Everything to the right of the equal sign in an assignment
  • Everthing between and open bracket and a comma or a close bracket in function argument
  • Everything between the IF and the '=' in an IF instruction
  • Everything between the '=' and the THEN in an IF instruction
  • Everything after EXIT or RETURN
  • Many more if you think about it.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The PULL instruction

 /* REXX program to show the PULL instruction */
 SAY "Program to multiple 2 numbers"
 SAY "Please enter your first number"
 PULL Num1
 SAY "Thank you, now your second number"
 PULL Num2
 SAY "Well done: Now" Num1 "times" Num2 "=" Num1 * Num2
 ----------------------------
 Program to multiple 2 numbers
 Please enter your first number
 12
 Thank you, now your second number
  14
  Well done: Now 12 times 14 = 168

The PULL Instruction is a funny little baby. What it does will depend on where you are executing your program. When running it online it will pause the execution of the routine and wait for you to type something in. When executing the REXX in JCL this instruction will try and get a line from the input queue - more about that later. For now we will worry about running it online. In the example above I typed in the numbers 12 and 14 in 'answer' to the two PULL statements. Its a pretty obvious thing to say but if you are going to use PULL like this then have a good SAY instruction just before it so you will know what to type in!
There is far more to PULL than meets the eye, you can not only accept input with it but also split it up, convert it to upper case, its very clever. Refer to end of the PARSE section for more details.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

1.3 Conditional Processing

Comparative Operators

 /* REXX showing Comparative Operators */
 SAY 12 = 12
 SAY "fred" = "fred"
 SAY 12 = 13
 SAY "fred" = "freda"
 ----------------------------
  1
  1
  0
  0


Normal Comparative operators.
In the example above you can see how REXX compares two expressions. If we code 'variable-name = expression' it knows we are doing an ASSIGNMENT, but an '=' almost everywhere else means we are COMPARING two expressions. Note I say EXPRESSIONS and not TOKENS. These always return a '1' if the answer is TRUE and a '0' if the answer is FALSE. In the example above we are checking to see if two expressions are equal, here are all the comparative operators.

 = means equals   <> or  >< or \=, means not equals
  < means less than       >= or  \<    means not less than
  > means greater than    <= or  \>    means not greater than

Note sometimes other platforms have other NOT symbols. Sometimes they use a rotated L sometimes a / (not a \).


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

IF THEN & ELSE Instructions

 /* REXX IF program */
 A = 10 ; B = 12
 IF A = B THEN SAY A    "IS EQUAL TO" B
  ELSE SAY A "IS NOT EQUAL TO" B
  ----------------------------
  10 IS NOT EQUAL TO 12

We can use the result of a comparative operator with an IF instruction to ensure that some instructions are only executed under certain conditions. When the comparison result is 1 (TRUE) then the statment after the THEN instruction is executed. If we want we can add an ELSE on the next line and this statement will be executed if the result is 0 (FALSE), this is optional. Note that the word ELSE has been indented. This makes the code more readable and as you will see in a minute will help you find syntax errors.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Using DO & END with the IF Instructions

 /* REXX program showing DO-END blocks */
 A = 76 ; B = 76
 IF A = B THEN DO
    SAY "A=" A "B=" B
    SAY "AND THEY ARE THE SAME" ; END
  ELSE DO
    SAY "A=" A "B=" B
    SAY "AND THEY ARE DIFFERENT"; END
  ----------------------------
  A= 76 B= 76
  AND THEY ARE THE SAME

In the last example we could only execute one single instruction conditionally. There are lots of situations where we will want to execute lots and lots of instructions. Here we have added the keywords DO and END. As it says in the text for every DO you must have an END statements.
Indenting Code
How do we ensure we always remember to code the END keywords ? The answer is all to do with indenting the code. I always line up the END statement with the other statements in the block. I've seen other peoples code where they have lined it up with the IF instruction. It doesn't really matter which you do, get into your own habit and stick with it. Now when your program failed with the error MISSING or UNEXPECTED END you can just glance through your code and see where you have missed out the END keyword.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

More Complex Comparisons

 /* REXX program. Comparative Operators.      */
  SAY "Some more complex Comparisons."
  SAY "Compare ' 010  '  and  '+10.00' ";SAY "  010  " = "+10.00"
  SAY "Compare ' strip ' and  'strip'  ";SAY " strip " = "strip"
  SAY "Compare 'FRED'   'fred'"       ;SAY "FRED" = "fred"
  SAY "Is 'APPLE' less than 'BANANA'?";SAY "APPLE" < "BANANA"
  SAY "Is 'a' greater than 'A'?"      ;SAY "a" > "A"
  SAY 12 < "Apple"                    ;SAY 12 < "Apple"
  ----------------------------
  Some more complex Comparisons.
  Compare ' 010  '  and  '+10.00'
  1
  Compare ' strip ' and  'strip'
  1
  Compare 'FRED'   'fred'
  0
  Is 'APPLE' less than 'BANANA'?
  1
  Is 'a' greater than 'A'?
  1
  1
  0


Numerical Comparisons Now you have seen how IF instructions work we (I mean you of course) are going back to look at some more complex comparisons, if you want to do some clever IF instructions you will need to go through this next bit even if its a bit heavy.
When I say complex comparisons I don't really mean complex just could-be-true could-be-false. In the first test here you can see that the result is TRUE if the numerical value of the two expressions are the same. Leading and trailing spaces are removed as well as unnecessary zeros and signs. This only occurs when both expressions are considered to be numerical and not literal strings.
Literal Comparisons
The two literal comparisons shown here also tell us a few things. First leading and trailing spaces have no effect. The comparisons are case sensitive, here "FRED" is not equal to "fred". The last two examples show us that we can see if one literal string is alphabetically greater or less than another, this is also case sensitive. It is legal to do something like "A" <12 but we are unlikely to use this in practice.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Strict Comparisons

 /* REXX program. Strict Comparative Operators. */
 SAY "Now we will look at STRICT comparisons."
 SAY "Strickly compare ' strip ' & 'strip' "
 SAY " strip " == "strip"
  SAY "Check 'FRED' & 'fred' are strictly not equal"
  SAY "FRED" \== "fred"
  SAY "Strictly compare '  010 '  &  '+10.00' "
  SAY "  010  " == "+10.00"
  SAY "Strictly compare 12 * 3 & 72 / 2"
  SAY 12 * 3 == 72 / 2
  ----------------------------
  Now we will look at STRICT comparisons.
  Strickly compare ' strip ' &  'strip'
  0
  Check 'FRED' & 'fred' are strictly not equal
  1
  Strictly compare '  010 '  &  '+10.00'
  0
  Strictly compare 12 * 3  &  72 / 2
  1

Another feature of REXX is the 'strict comparisons' . Here the expressions must be exactly the same to get a 1 as the result. Leading and trailing spaces are not removed as you can see in the examples above. It is of course case sensitive as you would expect.
Numeric Strict Comparisons
This time the numbers are treated more like literal strings, it's not only their numerical value that must be the same, but also there must not be any extra characters getting in the way.
Comparison Priority
Comparisons have a priority of 3, which is very low. This means that most other operations are performed first (including concatenation / abuttal). In the last example here we can see that the multiplication and division is carried out before the comparison.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Logical Comparisons

 /* REXX program. Logical (Boolean) Operators. */
1 SAY "Logical operators compare two results."
2 SAY "Print 1 if: 1 = 1 AND 2 = 2" ;SAY 1 = 1 &  2 = 2
3  SAY "Print 1 if: 1 = 3 AND  2 = 2" ;SAY 1 = 3 &  2 = 2
4  SAY "Print 1 if: 1 = 1 OR   1 = 2" ;SAY 1 = 1 |  1 = 2
5  SAY "Print 1 if: 1 = 2 OR   2 = 1" ;SAY 1 = 2 |  2 = 1
6  SAY "Print 1 if: 1 = 1 XOR  1 = 2" ;SAY 1 = 1 && 1 = 2
7  SAY "Print 1 if: 1 = 1 XOR  2 = 2" ;SAY 1 = 1 && 2 = 2
8  SAY 1 | 0
9  SAY 2 & 1
10 SAY 1 && 1
  ----------------------------
  Logical operators compare two results.
  Print 1 if: 1 = 1 AND  2 = 2
  1
  Print 1 if: 1 = 3 AND  2 = 2
  0
  Print 1 if: 1 = 1 OR   1 = 2
  1
  Print 1 if: 1 = 2 OR   2 = 1
  0
  Print 1 if: 1 = 1 XOR  1 = 2
  1
  Print 1 if: 1 = 1 XOR  2 = 2
  0
  1
  +++ Error 46 in line 9: Boolean value not 0 or 1
  Command returned 10/46: Boolean value not 0 or 1


Combining two results with Logical Operators
Now we really are getting clever. We are combining the results of two (can be more) results to produce a final result. The examples show the AND, OR and exclusive-OR logical operators. These can be used to combine numerals (as long as they are 0 or 1s) not just the results from other comparisons. For example the instruction SAY A & B would be legal as long as A and B have values of either 1 or 0. You can see what happens if the input is not a 1 or zero; we get an error. Note that the sign for exclusive-OR is two AND signs, not two OR signs - that means abuttal of course.
Comparison (Boolean) errors.
The line 9 of the example, it shows a very common error. We are trying to AND two values , but one of these is not a 0 or a 1. It looks pretty silly here but it's a very common error when variables are used. For example if you coded SAY 1 | A it would fail if A had not been initialized with a 0 or 1. Remember this, it may be one of dozens of things you are trying to absorb right now but its one which will come back to haunt you (and several times if its in a loop).
Logical Operators Prioritiy
The priority of the AND (&) is 2 and the priority of OR (|) and exclusive OR (&&) are both 1. This means they are done after all other operations within the expression. But as I have said before when in doubt about priority use brackets.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The 'NOT' Operator

 /* REXX. The NOT operator and comparison errors. */
 SAY "The NOT operator can be used to reverse a result."
 SAY " 1 not= 1 will give a:" ; SAY 1 \= 1
 SAY "     not 1 = 1 will give a:" ; SAY  \ 1 = 1
  SAY "not 1 = 1 XOR 2 \= 1 gives:" ; SAY  \ 1 = 1 &&  2 \= 1
  SAY "        1 = 1 AND 1  gives:" ; SAY 1 = 1 & 1
  ----------------------------
  The NOT operator can be used to reverse a result.
  1 not= 1 will give a:
  0
  not 1 = 1 will give a:
  0
  not 1 = 1 XOR 2 \= 1 gives:
  1
  1 = 1 AND 1  gives:
  1

It is possible to reverse the result of a comparison by the use of the NOT operator. The symbol used for this can vary with different platforms. On TSO it is possible to use an inverted and rotated L (which I haven't got in my character set or I would show you) or a / (slash). In the examples above you can see that the NOT symbol can be part of a comparison operator or at the beginning of the expression on its own. When it is used on its own it has a priority of 8, which is very high.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The SELECT, WHEN, OTHERWISE and NOP instructions

 /* REXX The SELECT, WHEN, OTHERWISE and NOP instructions */
 A = "120"
 SELECT
    WHEN A = "100" THEN NOP /* DO NOTHING */
    WHEN A = "200" THEN SAY "A IS 200"
    WHEN A = "300" THEN DO
       SAY "DO A BLOCK OF CODE IF ITS 300
       END
    OTHERWISE SAY "NONE ABOVE ARE TRUE"
    END
If you are a matching socks and tie man (person) then this stuff is for you. This can tidy up the crappist code. This is wonderful take a look. If you have several IF instructions all asking the same basic question then here we can handle the situation with wonderful easy, simplicity itself and all sort of other very long words. The idea is that if the first WHEN condition is TRUE it will execute the code after the THEN statement and then go straight to the END statement without doing any of the other tests. If the condition if FALSE it will try the next WHEN condition etc. If all of these conditions are FALSE the you the instructions next to OTHERWISE. Note then you don't code a THEN next to OTHERWISE. If we want to execute a block of statements we just code a DO after the THEN and an END before the next WHEN (what a month full). It's the same as the IF instruction. When there is a condition where you don't want to execute any instructions and you want to go straight to the END you can code NOP (no - operations).

TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

1.4 Instruction Loops

DO Loops (with FOR, BY and TO)

 /* REXX. Introducing DO loops */
 DO A = 1 TO 7 BY 2
 SAY "A=" A ; END
 DO B = 1 FOR 4
 SAY " B=" B ; END
 ----------------------------
 A= 1
 A= 3
 A= 5
  A= 7
       B= 1
       B= 2
       B= 3
       B= 4

DO loops come is several shapes and sizes, but it's all about being able to execute a block of code more than once. It's the only way to do it in REXX so they are rather important. In these examples we are controlling the number of times we go round the loop by two different ways but on each we are incrementing a variable (which is very important). In the first example we are incrementing the variable called A. We'll keep going round the loop until A is equal to 7. The BY parameter means that each time we go round the loop A is incremented BY 2 . If BY was not coded A would default to an increment of 1. In the second example the FOR parameter has been used to ensure we go round the loop 4 times. Here B is incremented but its not B's value that will terminate the loop. To be honest you won't see this facility used a lot and I am never quite such why! What you will find is this simulated with less efficient code, where an incremented counter is added with extra statements. Very under-rated / under-used are the FOR and BY parameters.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

DO WHILE and UNTIL loops

 /* REXX showing UNTIL/WHILE loops*/
 A = 6; B = 1; C = 1
 DO WHILE A \= B
   SAY "B=" B
    B = B + 1 ; END
  DO UNTIL A = C
    SAY "     C=" C
    C = C + 1 ; END
  ----------------------------
  B= 1
  B= 2
  B= 3
  B= 4
  B= 5
       C= 1
       C= 2
       C= 3
       C= 4
       C= 5

It is very rare to find a REXX program without one of these two. Here we have a comparison operator and we keep going round the loop WHILE it is TRUE or UNTIL it is TRUE. There is no automatic increment so people will sometimes code there own. While the WHILE and UNTIL parameters look like exact opposites, there is one very important difference between them. The WHILE test is executed at the beginning of the loop and the UNTIL test is executed at the end - look at the red lines. See the following section for the next exciting episode where you can see the effect this can have!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The LEAVE instruction

 /* REXX program to show the LEAVE instruction */
 MaxNum = 10000; MaxLoop = 10 ; A = 2
 DO Loop = 1 TO MaxLoop
 B = A * A
 SAY "Loop1=" Loop  "B =" B
     A = B
     If A > MaxNum THEN LEAVE
    END
  A = 2
    DO Loop = 1 TO MaxLoop WHILE A < MaxNum
    B = A * A
    SAY "Loop2=" Loop  "B =" B
    A = B
    END
  ----------------------------
  Loop1= 1 B = 4
  Loop1= 2 B = 16
  Loop1= 3 B = 256
  Loop1= 4 B = 65536
  Loop2= 1 B = 4
  Loop2= 2 B = 16
  Loop2= 3 B = 256
  Loop2= 4 B = 65536

Two examples again, both produce the same output with differing code. The first introduces the LEAVE instruction. Very simple and very useful. You leave the loop immediately you hit this instruction. In this example we go straight the SAY instruction Here it is not really necessary to use LEAVE, this is because it is the last instruction within the loop. It is cleaner to code the test on the DO instruction, which is what we have done in the second example. Note I've been a good boy and not coded the constants within the body of the program, they are defined at the top. Strictly speaking there is a mistake here, the it should be WHILE A <= MaxNum.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The ITERATE & FOREVER instructions

 /* REXX program to show ITERATE & FOREVER */
 A = 0; Incr = 1; Divis = 4; MaxNum = 10
 DO FOREVER
   A = A + Incr
    IF A = MaxNum THEN DO
        SAY "HIT LOOP END CONDITION"
        LEAVE
        SAY "NEVER EXECUTED" ; END
    IF (A // Divis) = 0 THEN DO
        SAY "HERE" A "IS DIVISIBLE BY" Divis
        ITERATE
        SAY "NEVER EXECUTED" ; END
    SAY "A=" A
    END
  SAY "REACHED END"
  ----------------------------
  A= 1
  A= 2
  A= 3
  HERE 4 IS DIVISIBLE BY 4
  A= 5
  A= 6
  A= 7
  HERE 8 IS DIVISIBLE BY 4
  A= 9
  HIT LOOP END CONDITION
  REACHED END


The ITERATE instruction
Another new keyword to remember: ITERATE. Very straightforward. If you hit this you go straight back to the beginning of the loop. Note that here the LEAVE instruction is within a IF DO - END block, the LEAVE doesn't mean leave this block, it means leave the ,DO loop!
The FOREVER instruction
Here is another way we can do a DO! Coding DO FOREVER means we will just keep going round and round. The only escape will be via a LEAVE instruction (or an EXIT or a RETURN.)


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

More DO loops

 /* REXX program to show other types of DO */
 LineSpace = 3; Max = 10
  DO LineSpace; SAY "***"; END
  B = ""; A = 0; KeepGoing = 1
  DO WHILE KeepGoing
     A = A + 1
     IF A = Max THEN KeepGoing = 0
     B = B A ; END
  SAY B
  DO LineSpace; SAY "***"; END
  ----------------------------
  ***
  ***
  ***
  1 2 3 4 5 6 7 8 9 10
  ***
  ***
  ***

Some more examples of DO loops. The first and third loops are printing the *** lines. Coding DO n is legal when n is a number (or a variable contains a number), it's very simple the loop is performed that number of times. I've broken the normal convention over having one instruction per line because it seemed sensible to do so!
The second loop is just showing you that the expression after the word UNTIL must have a value or 1 or 0. On most of the other examples we have used a comparison - the result of would be a 1 or 0. It's all another way of achieving the same thing. While it looks like this involves more code and therefore is probably less efficient, you will see a lot of code like this and therefore its important for you to be able to understand it.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

1.5 Other bits: INTERPRET and Functions

The INTERPRET instruction

 /* REXX program to show the power of INTERPRET */
 A = "SAY 'Input REXX instructions or END'"
 INTERPRET A
 DO FOREVER
   PULL Input
    IF Input = "END" THEN EXIT 0
    INTERPRET Input ; END
  ----------------------------
  Input REXX instructions or END
  A = 15
  B = 20
  SAY A * B
  300
  END

The first instruction here is an assignment. It's putting a complete REXX instruction into a variable, you may think this is a strange thing to do but the INTERPRET instruction can execute this! If the second part of this program doesn't knock your socks off - nothing will. It's providing you with the facility to type in any REXX command online and show you its result! Look at the entries I give the program, its executing each line at a time, in effect it is executing the program as I type it in! Type up the second part of this program and always have it at your fingertips for use as a calculator or trying REXX instructions!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Functions (Sub-routines)

 /* REXX : Internal functions. */
 SAY "First Line"
 CALL MyFunction
 SAY "Last Line"
 EXIT 0
  MyFunction:
  SAY "Welcome to my own function!"
  RETURN 0
  ----------------------------
  First Line
  Welcome to my own function!
  Last Line

We are now going to talk about sub-routines, these are used very extensively used in large programs. It is said that the main routine of a program should only really contain CALL statements which invokes blocks of code where the real work is done. It helps you keep sight of what is going on without getting snarled up in the detail. The other time they are very useful is when the same piece of code is required in several places. When the code is in a function you just code it once and then have different CALL instructions. In the example above we have one homemade functions. These are always coded after the EXIT instruction. Their first line is called a LABEL instruction, it always ends with a colon. The function starts here and ends with a RETURN instruction.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

The ARG instruction & RESULT variable

 /* REXX program to show function communication. */
 CALL Funct1 2
 SAY "Give the funct1 a" 2 "and you get back a" Result
 SAY "Give the funct1 a" 4 "and you get back a" Funct1(4)
 EXIT 0
  Funct1:
  ARG Input
  Code = Input * 3
  RETURN Code
  ----------------------------
  Give the funct1 a 2 and you get back a 6
  Give the funct1 a 4 and you get back a 12

Look at the CALL instruction, here you can see two way communication between the calling routine and the function. The argument is put next to the function name and this is picked up by the ARG instruction in the function. The ARG instruction gets very heavy and we will deal with this in detail later in the PARSE section. Look at the line RETURN code, this returns the value of to a variable called RESULT.
The next time the Funct1 function is 'called' we are using a different syntax. Instead of using the instruction CALL we place some brackets next to the function name. Note that there must not be a gap between the function name and the opening bracket! The argument is put inside the brackets. The way the return code is handled is also different. The function becomes the result. You can then put the value into a variable or print it straight out! All clever stuff, as a general rule if you are executing a function and you want the result people tend to code FUNCTION( arguments ) but if they don't need the result they code CALL FUNCTION arguments.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . .

Built in Functions

 /* REXX : DATATYPE & LENGTH functions */
 A = "string" ; B = 12.0000; C = "+12.0456"
 SAY "The data type of '" || A || "' is " DATATYPE(A)
 SAY "The data type of '" || B || "' is "  DATATYPE(B)
  SAY "The data type of '" || C || "' is "  DATATYPE(C)
  SAY "'" || A || "' is" LENGTH(A) "characters in length."
  SAY "'" || B || "' is" LENGTH(B) "characters in length."
  SAY "'" || C || "' is" LENGTH(C) "characters in length."
  EXIT 0
  ----------------------------
  The data type of 'string' is  CHAR
  The data type of '12.0000' is  NUM
  The data type of '+12.0456' is  NUM
  'string' is 6 characters in length.
  '12.0000' is 7 characters in length.
  '+12.0456' is 8 characters in length.

Here we are calling two different functions, one called DATATYPE and the other called LENGTH, but where are they? They are not listed below the EXIT 0 are they? "No" I hear you cry! That's because there is a library of built in functions that you can access which increases the power of this language immeasurably. You will see what I mean in a minute. These two aren't bad for starters. The first one DATATYPE can tell us whether the contents of a variable is a number or a string of characters. Very very useful for checking data before its going to crash your program by trying to multiple something which is not a number!

Section 2 will now going to go through the more common functions that are built in.

GO TO FUNCTIONS