home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxtut2.zip / rexx.txt < prev    next >
Text File  |  1993-11-20  |  45KB  |  1,151 lines

  1.   The REXX Tutorial for Complete Beginners
  2.  
  3. This document is being ported from a UNIX version for IMC Unix.  It was
  4. written by Ian Collier.  If you find any mistakes or unixisms in it, please
  5. contact Paul Prescod: papresco@undergrad.math.uwaterloo.ca.
  6.  
  7. Please also contact me if you have suggestions for improvement, or 
  8. text you would like to see added, or files you would like to see in 
  9. the zip file.  Also, if you could write a REXX script that turns
  10. a readable text file into a .inf file, I would love to ship both text
  11. and .inf versions.
  12.   
  13.  
  14.  
  15. 1. Creating a Rexx program
  16.   
  17. Many programmers start by writing a program which displays the message
  18. "Hello world!".  Here is how to do that in Rexx...
  19.   
  20. Write a file called "hello.cmd" containing the following text.  Use any
  21. text editor, e, edit,  or epm will do.  To do this in the WorkPlace shell,
  22. just go to the templates folder and drag a data file object out of it.  
  23. Bring up its settings and rename it to "hello.cmd."  The text, as with all
  24. example text in this guide, starts at the first indented line and ends at
  25. the last.  The four spaces at the start of each line of text should not be
  26. entered (this is very important!):
  27.   
  28.       /* This program says "Hello world!" */
  29.       say "Hello world!"
  30.   
  31. This program consists of a comment saying what the program does, and an
  32. instruction which does it.  "say" is the Rexx instruction which displays
  33. data on the terminal.
  34.   
  35. The method of executing a Rexx program varies greatly between
  36. implementations.  On OS/2, you would just type "hello.cmd" in that 
  37. file's directory, or double click on its icon in the WorkPlace Shell.
  38.  
  39. When you execute your first Rexx program using the method detailed above,
  40. you should see the message "Hello world!" appear on the screen.
  41.  
  42.   2. Doing arithmetic
  43.  
  44. Rexx has a wide range of arithmetic operators, which can deal with very
  45. high precision numbers.  Here is an example of a program which does
  46. arithmetic.  Make a file called "arith.cmd" containing the following:
  47.  
  48.       /* This program inputs a number and does some calculations on it */
  49.       pull a
  50.       b=a*a
  51.       c=1/a
  52.       d=3+a
  53.       e=2**(a-1)
  54.       say 'Results are:' a b c d e
  55.  
  56. in a positive integer.  Here is a sample run:
  57.  
  58. input:  5
  59. output: Results are: 5 25 0.2 8 16
  60.  
  61.   The results you see are the original number (5), its square (25), its
  62.   reciprocal (0.2), the number plus three (8) and two to the power of one
  63.   less than the number (16).
  64.  
  65.   This example illustrates several things:
  66.  
  67.   * variables: in this example a, b, c, d and e are variables. You can
  68.     assign a value to a variable by typing its name, "=", and a value, and
  69.     you can use its value in an expression simply by typing its name.
  70.   * input: by typing "pull a" you tell the interpreter to ask the user for
  71.     input and to store it in the variable a.
  72.   * arithmetic: the usual symbols (+ - * /) as well as ** (to-power) were
  73.     used to perform calculations.  Parentheses (or "brackets") were used to
  74.     group together an expression, as they are in mathematics.
  75.   * string expressions: the last line of the program displays the results by
  76.     saying the string expression
  77.     
  78.         'Results are:' a b c d e
  79.  
  80.     This has six components: the string constant 'Results are:' and the five
  81.     variables. These components are attached together with spaces into one
  82.     string expression, which the "say" command then displays on the
  83.     terminal.  A string constant is any sequence of characters which starts
  84.     and ends with a quotation mark - that is, either " or ' (it makes no
  85.     difference which you use, as long as they are both the same).
  86.  
  87. If you supply the number 6 as input to the program, you should notice that
  88. the number 1/6 is given to nine significant figures.  You can easily
  89. change this.  Edit the program and insert before the second line:
  90.  
  91.       numeric digits 25
  92.  
  93. If you run this new program you should see that 25 significant figures are
  94. produced.  In this way you can calculate numbers to whatever accuracy you
  95. require, within the limits of the machine.
  96.  
  97. At this point it seems worth a mention that you can put more than one
  98. instruction on a line in a Rexx program. You simply place a semicolon
  99. between the instructions, like this:
  100.  
  101.       /* This program inputs a number and does some calculations on it */
  102.       pull a; b=a*a; c=1/a; d=3+a; e=2**(a-1); say 'Results are:' a b c d e
  103.  
  104. Needless to say, that example went a bit over the top...
  105.       
  106.   3. Errors
  107.  
  108. Suppose you ignored the instructions of the previous section and typed a
  109. non-integer such as 3.4 as input to the program.  Then you would get an
  110. error, because the ** (to-power) operator is only designed to work when
  111. the second parameter (that is, the power number) is an integer. You might
  112. see this, for example:
  113.  
  114.       3.4
  115.           6 +++ e=2**(a-1)
  116.      Error 26 running arith.cmd, line 6: Invalid whole number
  117.  
  118. Or if you typed zero, you might see the following (because you cannot
  119. divide by zero):
  120.  
  121.     rexx arith
  122.     0
  123.         4 +++ c=1/a
  124.     Error 42 running arith.cmd, line 4: Arithmetic overflow or underflow
  125.  
  126. Perhaps most interestingly, if you type a sequence of characters which is
  127. not a number, you might see this.  It does not complain about the
  128. characters you entered, but at the fact that the program tries to use it
  129. as a number.
  130.  
  131.       rexx arith
  132.       hello
  133.           3 +++ b=a*a
  134.     Error 41 running arith.cmd, line 3: Bad arithmetic conversion
  135.  
  136. In each case, you have generated a "syntax error" (it is classified as a
  137. syntax error, even though the problem was not directly related to the
  138. program's syntax).  What you see is a "traceback" starting with the line
  139. which caused the error (no other lines are listed in this traceback,
  140. because we have not yet considered any Rexx control structures), and a
  141. description of the error.  This information should help you to determine
  142. where the error occurred and what caused it.  More difficult errors can be
  143. traced with the "trace" instruction (see later).
  144.  
  145.   4. Untyped data
  146.  
  147. In the previous section, you found that you could input either a number or
  148. a sequence of letters and store it in the variable a, although arithmetic
  149. can only be performed on numbers.  That is because data in Rexx are
  150. untyped.  In other words, the contents of a variable or the result of an
  151. expression can be any sequence of characters.  What those characters are
  152. used for matters only to you, the programmer.  However, if you try to
  153. perform arithmetic on a random sequence of characters you will generate a
  154. syntax error, as shown in the previous section.
  155.  
  156. You have seen that you can add strings together by placing a space in
  157. between them.  There are two other ways: the abuttal and the concatenation
  158. operator.  An abuttal is simply typing the two pieces of data next to each
  159. other without a space.  This is not always appropriate: for example you
  160. cannot type an "a" next to a "b", because that would give "ab", which is
  161. the name of another unrelated variable.  Instead, it is safer to use the
  162. concatenation operator, ||.  Both these operations concatenate the strings
  163. without a space in between. For example:
  164.  
  165.       /* demonstrates concatenation and the use of untyped data */
  166.       a='A string'
  167.       b='123'
  168.       c='456'
  169.       d=a":" (b||c)*3
  170.       say d
  171.  
  172. The above program says "A string: 370368".  This is because (b||c) is the
  173. concatenation of strings b and c, which is "123456".  That sequence of
  174. characters happens to represent a number, and so it can be multiplied by 3
  175. to give 370368.  Finally, that is added with a space to the concatenation
  176. of a with ":" and stored in d.
  177.  
  178.   5. More on variables
  179.  
  180. The previous examples only used single-letter variable names.  In fact it
  181. is more useful to have whole words as variable names, and Rexx allows this
  182. up to an implementation maximum (which should be suitably large, e.g. 250
  183. characters).  Moreover, not only letters but numbers and the six characters
  184. "@#$!?_" are allowed in variable names - or "symbols", as they are called
  185. in the liturature.  These are valid symbols:
  186.  
  187.       fred
  188.       Dan_Yr_0gof
  189.       HI!
  190.  
  191. The case of letters is unimportant, so that for example "Hello", "HELLO"
  192. and "hellO" all mean the same.
  193.  
  194. If you use a symbol in an expression when it has not been previously given
  195. a value, that does not cause an error (unless "signal on novalue" is set -
  196. see later).  Instead, it just results in its own name translated into
  197. upper case.
  198.  
  199.       /* A demonstration of simple symbols */
  200.       foo=3
  201.       bar="Characters"
  202.       say foo bar':' hi!
  203.  
  204. This program says "3 Characters: HI!".
  205.  
  206. As well as "simple symbols", which are variables like the above, there are
  207. arrays.  Any ordinary variable name can also be used as the name of an
  208. array:
  209.  
  210.       /* This program uses an array. */
  211.       pull a
  212.       array.1=a
  213.       array.2=a*a
  214.       array.3=a**3
  215.       say array.1 array.2 array.3 array.1+array.2+array.3
  216.  
  217. An element of an array is accessed by typing the array name, a dot, and
  218. the element number.  The array name and the dot are together known as the
  219. "stem" of the array.  The name of the element is called a "compound
  220. symbol".  Note that an array does not have to be declared before it is
  221. used.
  222.  
  223. In fact not only numbers, but strings and variable names may be used as
  224. element names.  Also, an element name can consist of two or more parts
  225. separated by dots, so giving two or more dimensional arrays.
  226.  
  227.       /* This program uses an array with various elements */
  228.       book.1.author="M. F. Cowlishaw"
  229.       book.1.title="The REXX Language, a practical approach to programming"
  230.       book.1.pub="Englewood Cliffs 1985"
  231.       book.2.author="A. S. Rudd"
  232.       book.2.title="Practical Usage of REXX"
  233.       book.2.pub="Ellis Horwood 1990"
  234.       /* insert lots more */
  235.       say "Input a book number"
  236.       pull i
  237.       say "Author:   " book.i.author
  238.       say "Title:    " book.i.title
  239.       say "Publisher:" book.i.pub
  240.  
  241. In the above program, an array called "book" is created, containing a
  242. number of records each with elements AUTHOR, TITLE and PUB.  Notice that
  243. these three uppercase names are produced by symbols "author", "title" and
  244. "pub", because those symbols have not been given values.  When a book
  245. number i has been input, the elements of the ith record are printed out.
  246. It is not an error to reference an undefined element of an array.  If you
  247. type "3" into the above program, you will see this:
  248.  
  249.       Input a book number
  250.       3
  251.       Author:    BOOK.3.AUTHOR
  252.       Title:     BOOK.3.TITLE
  253.       Publisher: BOOK.3.PUB
  254.  
  255. As before, if a compound symbol has not been given a value, then its name
  256. is used instead.
  257.  
  258. There is a way to initialise every element of an array: by assigning a
  259. value to the stem itself.  Edit the above program and insert after the
  260. comment line:
  261.  
  262.       book.="Undefined"
  263.  
  264. This gives every possible element of the array the value "Undefined", so
  265. that if you again type "3" you will see the following:
  266.  
  267.       Input a book number
  268.       3
  269.       Author:    Undefined
  270.       Title:     Undefined
  271.       Publisher: Undefined
  272.       
  273.   6. Functions
  274.  
  275. The Online Rexx Summary contains a list of the functions which are available 
  276. in Rexx.  Each of these functions performs a specific operation upon the
  277. parameters. For example,
  278.  
  279.       /* Invoke the date function with various parameters */
  280.       say date("W")',' date()
  281.  
  282.   This might say, for example, "Friday, 22 May 1992".
  283.  
  284.   A function is called by typing its name immediately followed by "(". After
  285.   that come the parameters, if any, and finally a closing ")".  In the above
  286.   example, the "date" function is called twice.  The value of date("W") is
  287.   the name of the weekday, and the value of date() is the date in "default"
  288.   format.
  289.  
  290.   7. Conditionals
  291.  
  292.   It is time to use some Rexx control structures.  The first of these will
  293.   be the conditional.  Here is an example:
  294.  
  295.       /* Use a conditional to tell whether a number is less than 50 */
  296.       pull a
  297.       if a<50 then say a "is less than 50"
  298.       else say a "is not less than 50"
  299.  
  300.   The program is executed in the manner in which it reads - so, if a is less
  301.   than 50 then the first instruction is executed, else the second
  302.   instruction is executed.
  303.  
  304.   The "a<50" is a conditional expression.  It is like an ordinary
  305.   expression (in fact conditional expressions and ordinary numeric
  306.   expressions are interchangeable), but it contains a comparison operator.
  307.  
  308.   There are many comparison operators, as follows:
  309.  
  310.   = (equal to)  < (less than)  > (greater than)  <= (less or equal)
  311.   >= (greater or equal)  <> (greater or less)  \= (not equal)
  312.   \> (not greater)  \< (not less)
  313.  
  314.   All the above operators can compare numbers, deciding whether one is equal
  315.   to, less than, or greater than the other.  They can also compare
  316.   non-numeric strings, first stripping off leading and trailing blanks.
  317.  
  318.   There are analogous comparison operators to these for comparing strings
  319.   strictly.  The main difference between them is that 0 is equal to 0.0,
  320.   numerically speaking, but the two are different if compared as strings.
  321.   The other difference is that the strict operators do not strip blanks
  322.   before comparing.  The strict operators are
  323.  
  324.   == (equal to)  << (less than)  >> (greater than)  <<= (less or equal)
  325.   >>= (greater or equal)  \== (not equal)  \>> (not greater)  \<< (not less)
  326.  
  327.   Conditional expressions may be combined with the boolean operators:
  328.   & (and), | (or) and && (xor).  They may also be reversed with the \ (not)
  329.   operator.
  330.  
  331.       /* Decide what range a number is in */
  332.       pull a
  333.       if a>0 & a<10 then say "1-9"
  334.       if a\<10 & a<20 then say "10-19"
  335.       if \ (a<20 | a>=30) then say "20-29"
  336.       if a<=0 | a>=30 then say "Out of range"
  337.  
  338.   As well as demonstrating the boolean and comparison operators, this
  339.   program shows that the "else" clause is not required to be present.
  340.  
  341.   The above program may also be written using Rexx's other conditional
  342.   instruction, "select":
  343.  
  344.       /* Decide what range a number is in */
  345.       pull a
  346.       select
  347.          when a>0 & a<10 then say "1-9"
  348.      when a\<10 & a<20 then say "10-19"
  349.      when \ (a<20 | a>=30) then say "20-29"
  350.      otherwise say "Out of range"
  351.       end
  352.  
  353.   The "select" instruction provides a means of selecting precisely one from
  354.   a list of conditional instructions, with the option of providing a list of
  355.   instructions to do when none of the above were true.  The difference is
  356.   that if no part of a "select" instruction can be executed then a syntax
  357.   error results, whereas it is OK to miss out the "else" part of an "if"
  358.   instruction.
  359.  
  360.   Only one instruction may be placed after "then", "else" and "when", but
  361.   Rexx provides a way of bracketing instructions together so that they can
  362.   be treated as a single instruction.  To do this, place the instruction
  363.   "do" before the list of instructions and "end" after it.
  364.  
  365.       /* execute some instructions conditionally */
  366.       pull a
  367.       if a=50 then
  368.          do
  369.             say "Congratulations!"
  370.         say "You have typed the correct number."
  371.      end
  372.       else say "Wrong!"
  373.  
  374.   If you wish for one of the conditional instructions to do "nothing", then
  375.   you must use the instruction "nop" (for "no operation").  Simply placing
  376.   no instructions after the "then", "else" or "when" will not work.
  377.  
  378.   8. Loops
  379.  
  380.   Rexx has a comprehensive set of instructions for making loops, using the
  381.   words "do" and "end" which you met briefly in the previous section.
  382.  
  383.     a. Counted loops
  384.  
  385.     The instructions within a counted loop are executed the specified number
  386.     of times:
  387.  
  388.         /* Say "Hello" ten times */
  389.     do 10
  390.        say "Hello"
  391.         end
  392.  
  393.     A variation of the counted loop is one which executes forever:
  394.  
  395.         /* This program goes on forever until the user halts it */
  396.     do forever
  397.        nop
  398.     end
  399.  
  400.     b. Control loops
  401.  
  402.     Control loops are like counted loops, but they use a variable (called
  403.     the control variable) as a counter.  The control variable may count
  404.     simply in steps of 1:
  405.  
  406.         /* Count to 20 */
  407.     do c=1 to 20
  408.        say c
  409.     end
  410.  
  411.     or in steps of some other value:
  412.  
  413.         /* Print all multiples of 2.3 not more than 20 */
  414.     do m=0 to 20 by 2.3
  415.        say m
  416.     end
  417.  
  418.     It may take a specific number of steps:
  419.  
  420.         /* Print the first six multiples of 5.7 */
  421.     do m=0 for 6 by 5.7
  422.        say m
  423.     end
  424.  
  425.     or it may go on forever:
  426.  
  427.         /* Print all the natural numbers */
  428.     do n=0
  429.        say n
  430.     end n
  431.  
  432.     The "n" at the end of this last example is optional.  At the end of any
  433.     controlled loop, the name of the control variable may be placed after
  434.     the "end", where it will be checked to see if it matches the control
  435.     variable.
  436.  
  437.     c. Conditional loops
  438.  
  439.     A set of instructions may be executed repeatedly until some condition is
  440.     true. For example,
  441.  
  442.         /* I won't take no for an answer */
  443.     do until answer \= "NO"
  444.        pull answer
  445.         end
  446.  
  447.     Alternatively, they may be executed as long as some condition is true:
  448.  
  449.         /* It's OK to repeat this as long as there is no error */
  450.     do while error=0
  451.        pull a
  452.        if a="ERROR" then error=1
  453.        else say a
  454.     end
  455.  
  456.     Note that in this example, if there is already an error to start with
  457.     then the set of instructions will not be executed at all.  However in
  458.     the previous example the instructions will always be executed at least
  459.     once.
  460.  
  461.     d. Controlled conditional loops
  462.  
  463.     It is possible to combine forms a or b with form c mentioned above, like
  464.     this:
  465.  
  466.         /* I won't take no for an answer unless it is typed three times */
  467.     do 3 until answer \= "NO"
  468.        pull answer
  469.     end
  470.  
  471.     or this:
  472.  
  473.         /* input ten answers, but stop when empty string is entered */
  474.     do n=1 to 10 until ans==""
  475.        pull ans
  476.        a.n=ans
  477.     end
  478.  
  479.   The "iterate" and "leave" instructions allow you to continue with, or to
  480.   leave, a loop respectively.  For example:
  481.  
  482.       /* input ten answers, but stop when empty string is entered */
  483.       do n=1 to 10
  484.          pull a.n
  485.      if a.n=="" then leave
  486.       end
  487.  
  488.       /* print all integers from 1-10 except 3 */
  489.       do n=1 to 10
  490.          if n=3 then iterate
  491.      say n
  492.       end
  493.  
  494.   If a symbol is placed after the instructions "iterate" or "leave", then
  495.   you can iterate or leave the loop whose control variable is that symbol.
  496.  
  497.       /* Print pairs (i,j) where 1 <= i,j <= 5, except (2,j) if j>=3 */
  498.       do i=1 to 5
  499.          do j=1 to 5
  500.         if i=2 & j=3 then iterate i /* or "leave j" would work,
  501.                                        or just "leave"           */
  502.             say "("i","j")"
  503.      end
  504.       end
  505.  
  506.   9. Parsing
  507.  
  508.   The following program examines its arguments:
  509.  
  510.       /* Parse the arguments */
  511.       parse arg a.1 a.2 a.3 a.4 .
  512.       do i=1 to 4
  513.          say "Argument" i "was:" a.i
  514.       end
  515.  
  516.   Execute it as usual, except this time type "alpha beta gamma delta" after
  517.   the program name on the command line, for example:
  518.  
  519.     arguments alpha beta gamma delta
  520.  
  521.   The program should print out:
  522.  
  523.       Argument 1 was: alpha
  524.       Argument 2 was: beta
  525.       Argument 3 was: gamma
  526.       Argument 4 was: delta
  527.  
  528.   The argument "alpha beta gamma delta" has been parsed into four
  529.   components.  The components were split up at the spaces in the input.  If
  530.   you experiment with the program you should see that if you do not type
  531.   four words as arguments then the last components printed out are empty, and
  532.   that if you type more than four words then the last component contains all
  533.   the extra data.  Also, even if multiple spaces appear between the words,
  534.   only the last component contains spaces.  This is known as "tokenisation".
  535.  
  536.   It is not only possible to parse the arguments, but also the input.  In
  537.   the above program, replace "arg" by "pull".  When you run this new program
  538.   you will have to type in some input to be tokenised.
  539.  
  540.   Replace "parse" with "parse upper" in the program.  Now, when you supply
  541.   input to be tokenised it will be uppercased.
  542.  
  543.   "arg" and "pull" are, respectively, abbreviations for the instructions
  544.   "parse upper arg" and "parse upper pull".  That explains why the "pull"
  545.   instruction appeared in previous examples, and why it was that input was
  546.   always uppercased if you typed letters in response to it.
  547.  
  548.   Other pieces of data may be parsed as well.  "parse source" parses
  549.   information about how the program was invoked, and what it is called.
  550.   "parse version" parses information about the interpreter itself.  However,
  551.   the two most useful uses of the parse instruction are
  552.   "parse var [variable]" and "parse value [expression] with".  These allow
  553.   you to parse arbitrary data supplied by the program.
  554.  
  555.   For example,
  556.  
  557.       /* Get information about the date and time */
  558.       d=date()
  559.       parse var d  day month year
  560.  
  561.       parse value time() with hour ':' min ':' sec
  562.  
  563.   The last line above illustrates a different way to parse data.  Instead of
  564.   tokenising the result of evaluating time(), we split it up at the
  565.   character ':'.  Thus, for example, "17:44:11" is split into 17, 44 and 11.
  566.  
  567.   Any search string may be specified in the "template" of a "parse"
  568.   command.  The search string is simply placed in quotation marks, for
  569.   example:
  570.  
  571.       parse arg first "beta" second "delta"
  572.  
  573.   This line assigns to variable first anything which appears before
  574.   "beta", and to second anything which appears between "beta" and "delta".
  575.   If "beta" does not appear in the argument string, then the entire string
  576.   is assigned to first, and the empty string is assigned to "second".  If
  577.   "beta" does appear, but "delta" does not, then everything after "beta"
  578.   will be assigned to second.
  579.  
  580.   It is possible to tokenise the pieces of input appearing between search
  581.   strings. For example,
  582.  
  583.       parse arg "alpha" first second "delta"
  584.  
  585.   This tokenises everything between "alpha" and "delta" and places the
  586.   tokens in first and second.
  587.  
  588.   Placing a dot instead of a variable name during tokenising causes that
  589.   token to be thrown away:
  590.  
  591.       parse pull a . c . e
  592.  
  593.   This keeps the first, third and last tokens, but throws away the second
  594.   and fourth.  It is often a good idea to place a dot after the last
  595.   variable name, thus:
  596.  
  597.       parse pull first second third .
  598.  
  599.   Not only does this throw away the unused tokens, but it also ensures that
  600.   none of the tokens contain spaces (remember, only the last token may
  601.   contain spaces; this is the one we are throwing away).
  602.  
  603.   Finally, it is possible to parse by numeric position instead of by
  604.   searching for a string.  Numeric positions start at 1, for the first
  605.   character, and range upwards for further characters.
  606.  
  607.       parse var a 6 piece1 +3 piece2 +5 piece3
  608.  
  609.   The value of piece1 will be the three characters of a starting at
  610.   character 6; piece2 will be the next 5 characters, and piece3 will be the
  611.   rest of a.
  612.  
  613.   
  614.   10. Interpret
  615.  
  616.   Suppose you have a variable "inst" which contains the string "a=a+1".  You
  617.   can execute that string as an instruction, by typing:
  618.  
  619.       interpret inst
  620.  
  621.   The interpret instruction may be used to accept Rexx instructions from the
  622.   user, or to assign values to variables whose names are not known in
  623.   advance.
  624.  
  625.       /* Input the name of a variable, and set that variable to 42 */
  626.       parse pull var
  627.       interpret var "=" 42
  628.  
  629.   11. The stack
  630.  
  631.   Rexx has a data stack, which is accessed via the "push", "queue" and
  632.   "pull" instructions.  The "pull" instruction (or in full, "parse pull")
  633.   inputs data from the user as we have seen before.  However, if there is
  634.   some data on the stack then it will pull that instead.
  635.  
  636.       /* Access the Rexx stack */
  637.       queue "Hello!"
  638.       parse pull a      /* a contains "Hello!" */
  639.       parse pull b      /* b is input from the user */
  640.       push "67890"
  641.       push "12345"
  642.       parse pull c      /* c contains "12345" */
  643.       /* there is one item left on the stack */
  644.  
  645.   The difference between "push" and "queue" is that when the items are
  646.   pulled off the stack, the items which were queued appear in the same order
  647.   that they were queued (FIFO, or first in, first out), and the items which
  648.   were pushed appear in reverse order (LIFO, or last in, first out).
  649.  
  650.   12. Subroutines and functions
  651.  
  652.   The following program defines an internal function, and calls it with
  653.   some data:
  654.  
  655.       /* Define a function */
  656.       say "The results are:" square(3) square(5) square(9)
  657.       exit
  658.  
  659.       square: /* function to square its argument */
  660.       parse arg in
  661.       return in*in
  662.  
  663.   The output from this program should be: "The results are: 9 25 81"
  664.  
  665.   When Rexx finds the function call "square(3)", it searches the program for
  666.   a label called "square".  It finds the label on line 5 - the name followed
  667.   by a colon.  The interpreter executes the code which starts at that line,
  668.   until it finds the instruction "return".  While that code is being
  669.   executed, the arguments to the function can be determined with "parse arg"
  670.   in the same way as the arguments to a program.  When the "return"
  671.   instruction is reached, the value specified is evaluated and used as the
  672.   value of "square(3)".
  673.  
  674.   The "exit" instruction in this program causes it to finish executing
  675.   instead of running into the function.
  676.  
  677.   A function which takes multiple arguments may be defined, simply by
  678.   separating the arguments with a comma. That is, like this:
  679.  
  680.       /* Define a function with three arguments */
  681.       say "The results are:" condition(5,"Yes","No") condition(10,"X","Y")
  682.       exit
  683.  
  684.       condition: /* if the first argument is less than 10, return the second,
  685.                     else return the third. */
  686.       parse arg c,x,y
  687.       if c<10 then return x
  688.       else return y
  689.  
  690.   A subroutine is similar to a function, except that it need not give a
  691.   value after the "return" instruction.  It is called with the "call"
  692.   instruction.
  693.  
  694.       /* Define a subroutine to print a string in a box, then call it */
  695.       call box "This is a sentence in a box"
  696.       call box "Is this a question in a box?"
  697.       exit
  698.   
  699.       box: /* Print the argument in a box */
  700.       parse arg text
  701.       say "+--------------------------------+"
  702.       say "|"centre(text,32)"|"             /* centre the text in the box */
  703.       say "+--------------------------------+"
  704.       return
  705.  
  706.   It is possible to call a function, even a built-in function, as if it were
  707.   a subroutine.  The result returned by the function is placed into the
  708.   variable called "result".
  709.  
  710.       /* print the date, using the "call" instruction */
  711.       call date "N"
  712.       say result
  713.  
  714.   If a function or subroutine does not need to use the variables which the
  715.   caller is using, or if it uses variables which the caller does not need,
  716.   then you can start the function with the "procedure" instruction.  This
  717.   clears all the existing variables away out of sight, and prepares for a
  718.   new set of variables.  This new set will be destroyed when the function
  719.   finishes executing.  The following program calculates the factorial of a
  720.   number recursively:
  721.  
  722.       /* Calculate factorial x, that is, 1*2*3* ... *x  */
  723.       parse pull x .
  724.       say x"!="factorial(x)
  725.       exit
  726.  
  727.       factorial: /* calculate the factorial of the argument */
  728.       procedure
  729.       parse arg p
  730.       if p<3 then return p
  731.       else return factorial(p-1) * p
  732.  
  733.   The variable p which holds the argument to funtion factorial is unaffected
  734.   during the calculation of factorial(p-1), because it is hidden by the
  735.   "procedure" instruction.
  736.  
  737.   If the subroutine or function needs access to just a few variables, then
  738.   you can use "procedure expose" followed by the list of variable names to
  739.   hide away all except those few variables.
  740.  
  741.   You can write functions and subroutines which are not contained in the
  742.   same Rexx program.  In order to do this, write the function and save it
  743.   into a file whose name will be recognised by the interpreter.  This type
  744.   of function is called an "external" function, as opposed to an "internal"
  745.   function which can be found inside the currently running program.
  746.  
  747.   If you want to call your function or subroutine using "call foobar" or
  748.   "foobar()", then you should save it in a file named "foobar.cmd" which
  749.   can be found in the current directory or in your path.
  750.  
  751.   The "procedure" instruction is automatically executed before running your
  752.   external function, and so it should not be placed at the start of the
  753.   function.  It is not possible for an external function to access any of
  754.   its caller's variables, except by the passing of parameters.
  755.  
  756.   For returning from external functions, as well as the "return" instruction
  757.   there is "exit".  The "exit" instruction may be used to return any data to
  758.   the caller of the function in the same way as "return", but "exit" can be
  759.   used return to the caller of the external function even when it is used
  760.   inside an internal function (which is in turn in the external function).
  761.   "exit" may be used to return from an ordinary Rexx program, as we have
  762.   seen.  In this case, a number may be supplied after "exit", which will be
  763.   used as the exit code of the interpreter.
  764.  
  765.   13. Executing commands
  766.  
  767.   Rexx can be used as a control language for a variety of command-based
  768.   systems.  The way that Rexx executes commands in these systems is as
  769.   follows.  When Rexx encounters a program line which is nether an
  770.   instruction nor an assignment, it treats that line as a string expression
  771.   which is to be evaluated and passed to the environment.  For example:
  772.  
  773.       /* Execute a given command upon a set of files */
  774.       parse arg command
  775.       command "file1"
  776.       command "file2"
  777.       command "file3"
  778.       exit
  779.  
  780.   Each of the three similar lines in this program is a string expression
  781.   which adds the name of a file (contained in the string constants) to the
  782.   name of a command (given as a parameter).  The resulting string is passed
  783.   to the environment to be executed as a command.  When the command has
  784.   finished, the variable "rc" is set to the exit code of the command.
  785.  
  786.   The environment to which a command is given varies widely between systems,
  787.   but in most systems you can select from a set of possible environments by
  788.   using the "address" instruction.
  789.   
  790.   14. Signal
  791.  
  792.   Where other programming languages have the "goto" command, Rexx has
  793.   "signal".  The instruction "signal label" makes the program jump to the
  794.   specified label.  However, once this has been done, it is not possible to
  795.   resume any "select" or "do" control structures that have recently been
  796.   entered.  Thus the main use of "signal" is to jump to an error handling
  797.   routine when something goes wrong, so that the program can clean up and
  798.   exit.
  799.  
  800.   There is a much more useful way of using "signal", however.  That is to
  801.   trap certain kinds of error condition.  The conditions which may be
  802.   trapped include: "syntax" (that is, any syntax error), "error" (any
  803.   environment command that results in a non-zero exit code), "halt" (when
  804.   the user interrrupts execution) and "novalue" (which is when a symbol is
  805.   used without having been given a value).
  806.  
  807.   Error trapping for one of these conditions is turned on by
  808.  
  809.       signal on <condition>
  810.  
  811.   and is turned off by
  812.  
  813.       signal off <condition>
  814.  
  815.   When one of these conditions occurs, the program immediately signals to a
  816.   label whose name is the same as that of the condition.  Trapping is turned
  817.   off, so another "signal on" will be required if you want to continue to
  818.   trap that condition.
  819.  
  820.   Whenever a "signal" occurs, the variable "sigl" is set to the line number
  821.   of the instruction which caused the jump.  If the signal was due to an
  822.   error trap, then the variable "rc" will be set to an error code.
  823.  
  824.       /* This program goes on forever until someone stops it. */
  825.       say "Press Control-C to halt"
  826.       signal on halt
  827.       do i=1
  828.          say i
  829.      do 10000
  830.      end
  831.       end
  832.  
  833.       halt:
  834.       say "Ouch!"
  835.       say "Died at line" sigl
  836.  
  837.  
  838.   15. Tracing
  839.  
  840.   Full details of how to use Rexx's tracing facility are contained in
  841.   the online rexx reference.
  842.  
  843.   If a program goes wrong and you need more information in order to work out
  844.   why, then Rexx provides you with the ability to trace all or part of your
  845.   program to see what is happening.
  846.  
  847.   The most common form of tracing is turned on by
  848.  
  849.       trace r
  850.  
  851.   This causes each instruction to be listed before it is executed. Also, it
  852.   displays the results of each calculation after it has been found.
  853.  
  854.   Another useful trace command is:
  855.  
  856.       trace ?a
  857.  
  858.   This makes the interpreter list each instruction and stop before it is
  859.   executed.  You can execute the instruction by pressing return, or you can
  860.   type in some Rexx to be interpreted, after which the interpreter will
  861.   pause again.  You can use this to examine the program's variables and so
  862.   forth.
  863.  
  864.   If you want the interpreter to stop only when passing a label, use:
  865.  
  866.      trace ?l
  867.  
  868.   This is useful for setting breakpoints in the program, or for making the
  869.   program stop at a function call.
  870.  
  871.  
  872.  
  873.  
  874. The REXX Summary
  875.  
  876. Summary of the summary
  877.  
  878.  * Section 1: Removed
  879.  * Section 2: Summary of expression syntax
  880.  * Section 3: Summary of instructions
  881.  * Section 4: Summary of builtin functions
  882.  
  883. [1] The Rexx Language, a practical approach to programming
  884.     M. F. Cowlishaw
  885.     Englewood Cliffs 1985
  886.  
  887. 2 Summary of expression syntax
  888.  
  889. Strings:          "String constants" 'enclosed in quotes'
  890. Hex strings:      '616263 64'x
  891. Numbers:          123.4e-56
  892. Constant symbols: .abc 1d4 7!
  893. Simple symbols:   foo bar xyz3
  894. Stems:            array.
  895. Compound symbols: c.3 element.bar.45
  896. Operators:        arithmetic: + - * / ** (to-power) % (div) // (mod)
  897.                   string:     [abuttal] [space] || (concatenation)
  898.                   logical:    \ (not) & (and) | (or) && (xor)
  899.                   comparison: = > < <> <= >= \> \< \=
  900.                               == >> << <<= >>= \>> \<< \== (strong comparison)
  901. Function calls:   fn(1,2,3)    bar(,5)  'DATE'()
  902.  
  903. 3 Summary of instructions
  904.  
  905. /* this is a comment */
  906.  
  907. expression                     - execute a host command
  908.  
  909. symbol=value                   - assignment
  910.  
  911. ADDRESS [VALUE] [environment]  - change the current environment
  912. ADDRESS environment command    - execute a command in an environment
  913.  
  914. CALL name [arg][,[arg],...]]   - call a function or subroutine
  915. CALL ON condition [NAME symbol]- turn on condition handling
  916. CALL OFF condition             - turn off condition handling
  917.  
  918.     condition = ERROR | FAILURE | NOTREADY | HALT
  919.  
  920. DO [ symbol=start   [TO  finish]  ]     [WHILE expression_w]
  921.    [                [BY  step  ]  ]
  922.    [                [FOR count ]  ]     [UNTIL expression_u]
  923.  
  924.    [ expression_c                 ]     [FOREVER           ]
  925.  
  926.                                - block or repetitive block instruction
  927.  
  928. DROP symbol [symbol...]        - de-assignment
  929.  
  930. END [symbol]                   - end block or repetitive block instruction
  931.  
  932. EXIT [expression]              - exit program or external function
  933.  
  934. IF expression [;] THEN [;] statement [ ; ELSE [;] statement]
  935.                                - conditional instruction
  936.  
  937. INTERPRET expression           - dynamically execute a string
  938.  
  939. ITERATE [symbol]               - continue repetitive block
  940.  
  941. LEAVE [symbol]                 - leave repetitive block
  942.  
  943. NOP                            - do nothing
  944.  
  945. NUMERIC DIGITS n               - set parameters for numeric formatting
  946. NUMERIC FUZZ n
  947. NUMERIC FORM   SCIENTIFIC
  948.              | ENGINEERING
  949.              | "string constant"
  950.              | [VALUE] expression
  951.  
  952. OPTIONS expression             - Control system-dependent things
  953.  
  954. [PARSE [UPPER]] ARG template   
  955. [PARSE [UPPER]] PULL [template]
  956. PARSE [UPPER] LINEIN [template]
  957. PARSE [UPPER] SOURCE template
  958. PARSE [UPPER] VERSION template
  959. PARSE [UPPER] NUMERIC template
  960. PARSE [UPPER] VAR symbol template
  961. PARSE [UPPER] VALUE expression WITH template
  962.  
  963.     template        -> [firstPosition] assignments [assignments]
  964.     assignments     -> [nextPosition] varlist [stopPosition]
  965.     varlist         -> varname ' ' [varlist]
  966.     varname         ->   "non-constant symbol"
  967.                        | '.'
  968.     firstPosition   -> position
  969.     nextPosition    -> position [nextPosition]
  970.     stopPosition    -> position
  971.     position        ->   searchPosition
  972.                        | absPosition
  973.                        | relPosition
  974.                        | '(' "expression" ')'
  975.     searchPosition  -> "string constant"
  976.     absPosition     ->   "integer"
  977.                        | '=' numexpr
  978.     relPosition     ->   '+' numexpr
  979.                        | '-' numexpr
  980.     numexpr         ->   "integer"
  981.                        | '(' "integer expression" ')'
  982.  
  983. PROCEDURE                      - hide the caller's symbols
  984. PROCEDURE EXPOSE var1 [var2...]
  985. PROCEDURE HIDE var1 [var2...]
  986.  
  987. PUSH  expression               - stack a value in LIFO order
  988. QUEUE expression               - stack a value in FIFO order
  989.  
  990. RETURN [value]                 - return from a function or subroutine
  991.  
  992. SAY [expression]               - echo data
  993. SAYN expression                - echo data without newline
  994.  
  995. SELECT [expression]
  996.    WHEN expression THEN statements
  997.    WHEN expression THEN statements
  998.    ...
  999.    [OTHERWISE statements]
  1000. END [SELECT]                   - switch on a list of conditions
  1001.  
  1002. SIGNAL [VALUE] name            - jump to a label
  1003. SIGNAL ON condition [NAME symbol] - turn on condition handling
  1004. SIGNAL OFF condition              - turn off condition handling
  1005.  
  1006.     condition = ERROR | FAILURE | NOTREADY | HALT | SYNTAX | NOVALUE
  1007.  
  1008. TRACE [symbol]                 - control program tracing. Values are:
  1009. TRACE "string"                   A (all clauses) C (commands) E (error)
  1010. TRACE VALUE expression           F (failure) I (intermediate values)
  1011.                                  L (labels) N (normal, =F) O (off) 
  1012.                                  R (results)
  1013.  
  1014.  
  1015. 4 Summary of builtin functions
  1016.  
  1017. Standard functions
  1018.  
  1019. ABBREV(information,info[,length])  - check for valid abbreviations
  1020. ABS(number)                        - return the absolute value
  1021. ADDRESS()                          - return the current environment
  1022. ARG([n][,opt])                     - return or test an argument
  1023. BITAND(string1,string2[,pad])
  1024. BITOR (string1,string2[,pad])      - combine two strings with bit operations
  1025. BITXOR(string1,string2[,pad])
  1026. B2D(binary)
  1027. B2X(binary)
  1028. D2B(decimal)
  1029. C2X(string)
  1030. C2D(string[,n])
  1031. D2C(decimal[,n])                   - convert between data formats
  1032. D2X(decimal[,n])
  1033. X2B(hex)
  1034. X2C(hex)
  1035. X2D(hex)
  1036. CENTER(s,n[,pad])                  - centre a string in a field
  1037. CENTRE(s,n[,pad])
  1038. COMPARE(s1,s2[,pad])               - compare two strings
  1039. CONDITION([option])                - return information about trapped condition
  1040.                                      Option can be (default I):
  1041.                                    C (condition name) D (description)
  1042.                                    I (instruction)    S (status)
  1043.                                    
  1044. COPIES(s,n)                        - replicate a string
  1045. DATATYPE(string[,type])            - test datatype. Type can be:
  1046.                                    A (alphanumeric) B (bits) L (lowercase)
  1047.                                    M (mixed case) N (number) S (symbol chars)
  1048.                                    U (upper case) W (whole number) X (hex)
  1049.  
  1050. DATE([format])                     - get date. Format can be:
  1051.                                    B (base date - days since 1/1/1 AD)
  1052.                                    C (days in century) D (days in year)
  1053.                                    E (European) J (Julian) M (month name)
  1054.                                    N (normal: dd Mon yyyy) O (ordered)
  1055.                                    S (sorted) U (USA) W (day of week)
  1056.                                    
  1057. DELSTR(string,n[,length])          - delete substring
  1058. DELWORD(string,n[,length])         - delete words
  1059. DIGITS()                           - NUMERIC DIGITS setting
  1060. ERRORTEXT(i)                       - Rexx error message
  1061. FORM()                             - NUMERIC FORM setting
  1062.  
  1063. FORMAT(number [,[before] [,[after] [,[expp] [,expt]]]] )
  1064.                                    - format a number as specified
  1065. FUZZ()                             - NUMERIC FUZZ setting
  1066. INSERT(new,target[,[n][,[length][,pad]]])  - insert new string into target
  1067. JUSTIFY(s,n[,pad])                 - justify text to given width
  1068. LASTPOS(needle,haystack[,start])   - find last occurrence of a string
  1069. LEFT(string,num[,pad])             - return an initial substring
  1070. LENGTH(string)                     - find the length of a string
  1071. LINESIZE()                         - find the terminal width
  1072. MAX(number[,number...])            - find the maximum of a set
  1073. MIN(number[,number...])            - find the minimum of a set
  1074. OVERLAY(new,target[,[n][,[length][,pad]]])  - overlay new string on to target
  1075. POS(needle,haystack[,start])       - find the first occurance of a string
  1076. QUEUED()                           - return the number of items on the stack
  1077. RANDOM([min][,[max][,seed]])       - return a random number
  1078. REVERSE(string)                    - find the reverse of a string
  1079. RIGHT(string,num[,pad])            - return a final substring
  1080. SOURCELINE([i])                    - return a line of the source program
  1081. SPACE(s[,[n][,pad]])               - evenly space words in a sentence
  1082. STRIP(string[,[opt][,char]])       - remove leading/trailing spaces
  1083. SUBSTR(string,n[,length[,pad]])    - return a substring
  1084. SUBWORD(string,n[,k])              - return a substring of words
  1085. SYMBOL(name)                       - test to see if a symbol is defined
  1086. TIME([format])                     - get the time. Format can be:
  1087.                                    C (civil time) N (normal) L (long)
  1088.                                    H (hours since midnight)
  1089.                                    M (minutes since midnight)
  1090.                                    S (seconds since midnight) E (elapsed time)
  1091.                                    R (elapsed time then reset)
  1092.                                    
  1093. TRACE([setting])                   - get and/or set trace mode (see trace
  1094.                                      instruction)
  1095.                                      
  1096. TRANSLATE(string[,[tableo][,[tablei][,pad]]])
  1097.                                    - translate characters using given tables
  1098. TRUNC(number[,n])                  - truncate floating point number
  1099. VALUE(s[,[newvalue][,selector]])   - get or set value of a symbol
  1100.  
  1101. VERIFY(string,reference[,[option][,start]])
  1102.                                    - verify string for valid characters
  1103. WORD(string,n)                     - return a word from a string
  1104. WORDINDEX(string,n)                - return the position of a word in a string
  1105. WORDLENGTH(string,n)               - return the length of a word in a string
  1106. WORDPOS(phrase,string[,start])     - find a phrase in a string 
  1107. WORDS(string)                      - return the number of words in a string
  1108. XRANGE([a[,b]])                    - return a range of characters
  1109.  
  1110. I/O functions (some of which are UNIX-specific)
  1111.  
  1112. CHARIN([stream] [,[position] [,count]])  - read characters
  1113. CHAROUT([stream] [,[string] [,position] ]- write characters
  1114. CHARS([stream])                          - number of characters available
  1115. CLOSE(stream)                            - close a stream
  1116. FDOPEN(fd [,[mode] [,stream]])           - open an fd number
  1117. FILENO(stream)                           - find an fd number
  1118. FTELL(stream)                            - return the current file pointer
  1119. LINEIN([stream] [,[line] [,count]])      - read a line
  1120. LINEOUT([stream] [,[string] [,line]])    - write a line
  1121. LINES([stream])                          - determine whether lines may be read
  1122. OPEN(file [,[mode] [,stream]])           - open a file
  1123. PCLOSE(stream)                           - close a pipe
  1124. POPEN(command [,[mode] [,stream]])       - open a pipe to a shell command
  1125. STREAM(stream [,[option] [,command]])    - miscellaneous stream operations
  1126.  
  1127. UNIX-specific functions
  1128.  
  1129. CHDIR(directory)                   - change to new directory
  1130. GETCWD()                           - return current working directory
  1131. GETENV(name)                       - get an environment variable
  1132. PUTENV(string)                     - set an environment variable
  1133. SYSTEM(s)                          - return the output of a shell command
  1134. USERID()                           - return the process owner's login name
  1135.  
  1136. Mathematical functions (implemented as separate package)
  1137.  
  1138. ACOS(x)      the arc-cosine of x in radians (0<=acs(x)<=pi)
  1139. ASIN(x)      the arc-sine of x in radians (-pi/2<=asn(x)<=pi/2)
  1140. ATAN(x)      the arc-tangent of x in radians (-pi/2<=atn(x)<=pi/2)
  1141. COS(x)       the cosine of x radians
  1142. EXP(x)       the exponential of x (2.718281... to the power x)
  1143. LN(x)        the natural logarithm of x (x>0)
  1144. SIN(x)       the sine of x radians
  1145. SQRT(x)      the square root of x (x>=0) [arbitrary precision possible]
  1146. TAN(x)       the tangent of x radians (x <> pi/2)
  1147. TOPOWER(x,y) x to the power y
  1148.  
  1149.  
  1150.  
  1151.