--------------------------
AREXX PROGRAMMING - Part 1
By Scott L. Wilcox
--------------------------

     (EDITOR'S NOTE: This begins a series of tutorials designed as an
introduction to the ARexx programming language. You will need the ARexx
software to make use of this column. It's available retail for about $30.
It's published by William S. Hawes, POB 308, Maynard, MA 01754. Telephone
508-568-8695. There has been rumbling that ARexx will be supported by the
yet-to-be-released Workbench 1.4, but we have no definitive word on this.)

     ARexx is the Amiga version of the Rexx programming language. Programs
are written in plain text (ASCII) on any text editor or word-processor that
saves in ASCII. It is an interpretive language and has many features that
make it very useful as a macro language, but it is also a good, general
purpose programming language.
     Instructions are the basic commands in an ARexx program. They are the
built-in "commands" the interpreter executes. There are presently 32
instructions in ARexx (v.1.10). All other operations are performed by
functions, which we will examine at another time. Consider the following
simple ARexx program:

/*      A simple ARexx program.  */

    say 'Hello, Jumpdisk!  Look, Ma, I'm programming!'
    
     This program is made of one instruction and a string. The SAY
instruction writes to the console the expression that follows. It is
equivalent to the PRINT command in Basic. The string can be enclosed in
single or double quotes.
     The above program begins with a null clause. All ARexx programs must
begin with a null clause or comment line. Anything within the '/* */'
characters are considered null clauses. They are thrown out when read by the
interpreter and do not slow down a program's execution. They may appear
anywhere in a program.

/* This is a comment, or null clause! */

     There are other kinds of clauses (label, assignment, command), but we
will concentrate on instruction clauses in this article. Instruction clauses
are simply clauses that contain instructions, so are aptly named. Let's add
more instructions to the above program.

/*      A simple ARexx program.  */

    say 'Hello, Jumpdisk!  Look, Ma, I'm programming!'
    say
    options prompt 'Type in your name: '
    pull name
    say
    say 'Hi, 'name'.'
 
     We use the SAY instruction without an expression to send a linefeed to
the console. The OPTIONS instruction is used here with the PROMPT keyword to
designate what the prompt string will be while waiting for user input. And
the PULL instruction is the short form of PARSE UPPER PULL, which in this
case reads the string the user types in and stores it in the variable
'name.' If we run the program now, the results would be something like this,
assuming you typed 'Bill' at the prompt:


    Hello, Jumpdisk!  Look, Ma, I'm programming!

    Type in your name: Bill

    Hi, BILL.

     A nice thing about ARexx is that it is an interpretive language, which
makes it easy to check for bugs while you write a program. You can type a
few lines of code, run it, debug it, run again, then type more until you are
satisfied. Since this is such a laborious process with a compiler, ARexx is
well suited as a prototyping language.
     Let's add more lines to this program. We'll add an IF / THEN / ELSE
statement to check user input, and then turn on the TRACE feature so we can
watch program execution. We will also use one of the built-in functions,
DATATYPE().

/*      A simple ARexx program.  */

    trace r
    
    say "Hello, Jumpdisk!  Look, Ma, I'm programming!"
    say
    options prompt 'Type in your name: '
    pull name
    say
    
    if ~datatype(name,'M') then 
        say 'Your name should be spelled with letters from the alphabet.'
        else
        say 'Hi, 'name'.'
     
     The DATATYPE(name) function tells the program what type of data is
stored in the variable 'name'. Without the option parameter, it will return
either NUM or CHAR, which means the variable is either a NUMber or
CHARacter. The option parameter 'M' that is after 'name' tells the function
to see if the data in 'name' is Mixed alphabetics (upper and lower case
letters). The function then returns a boolean value (0 if false, 1 if true).
The ' ~ ' character is the 'not' operator that negates the statement. IF the
result of ~DATATYPE(name,'M') is true, then 'name' does not consist of
alphabetic characters, and the SAY instruction on the next line is
performed. If the result is false, then 'name' consists of alphabetic
characters, and the SAY clause after the ELSE instruction is performed.
     The first instruction is 'TRACE R', which echoes the results of each
line to the console. If we press Return at the prompt, the output to the
console will look like this:

  4 *-* ;
  5 *-* say "Hello, Jumpdisk!  Look, Ma, I'm programming!";
      >>> "Hello, Jumpdisk!  Look, Ma, I'm programming!"
Hello, Jumpdisk!  Look, Ma, I'm programming!
  6 *-* say;

  7 *-* options prompt 'Type in your name: ';
      >>> "Type in your name: "
  8 *-* pull name;
      >>> ""
  9 *-* say;

 10 *-* ;
 11 *-* if ~datatype(name,'M') then
      >>> ""
      >>> "M"
      >>> "1"
   11 *-* ;
   12 *-* say 'Your name should be spelled with letters from the...
        >>> "Your name should be spelled with letters from the alph..."
Your name should be spelled with letters from the alphabet.
   13 *-* else;

     Comments are filtered out and each line is written to the screen and
evaluated, after which the final results are written to the console screen.
Each line is numbered, which makes it easy to find bugs. Now if we turn off
tracing (TRACE OFF, instead of TRACE R), we get these results when a name is
typed:

    Hello, Jumpdisk!  Look, Ma, I'm programming!

    Type in your name: Bill

    Hi, BILL.

     If we type a number or other non-alphabetic character we should get
these results:

    Hello, Jumpdisk!  Look, Ma, I'm programming!

    Type in your name: 234
    
    Your name should be spelled with letters from the alphabet.
    
     With just a few instructions we have written a useful and powerful
program. Well, it's not so useful or powerful, but it does demonstrate the
simplicity of ARexx instructions. In future ARexx tutorials we will look at
more instructions, functions, interfacing with other programs, and using
external libraries.
     The example program is in this drawer as arexx.simple.
     For adventurous types, there are two other ARexx listings in this
drawer for study and use:

ALARM.REXX INSTRUCTIONS
     This is a simple program that demonstrates the use of the speak: device
from within Arexx, and uses the Sourceline(), and Delay() functions. I wrote
it to remind me when it was time to pick up my kindergartener. You know how
time slips away while computing. I originally used a "do - until" loop to
wait for the time, but found it was too CPU-intensive while waiting. The
Delay() function paused the program in the background and didn't grab too
much CPU time. The Sourceline() function is an easy way to embed defaults,
'help' information, or any data you might want to store within the source
code itself. The program listing should be fairly easy to follow. Like 'C',
Arexx programs have their comments like this: 
                    /* This is a comment! */
                    
SPELL.REXX INSTRUCTIONS
     Spell.rexx is an educational program to help drill lists of spelling
words. It uses the built-in speech capabilities of the Amiga. The word lists
are stored in an ASCII file (plain text). You can create lists from within
the program, or use any text editor or word-processor that can save in
ASCII. A 'SPELLFILE' is made of lines of words with spaces between words. Up
to 10 lines of words can be entered. The program will prompt you for any
input it needs. The listing should be fairly easy to follow. All comments
look like this:
            /* This is a comment! */
     You will need the Arexx interpreter to run this program, as well as
version 1.3 of Workbench in order to use the speak: device. The program
could be modified to run under the 1.2 OS. To do so, replace any line that
looks like this:

writeln('temptalk',phrase)

with . . .

address command 'say' phrase

     Then delete this line:

open('temptalk','speak:temp','W')
                
     This modification will use the 'SAY' command on Workbench 1.2 to
synthesize speech. It may even work on 1.1 OS. Does anyone still use 1.1?
     The program will 'read' one line at a time from the SPELLFILE,
pronounce each word, then prompt you for the correct spelling. To hear the
word pronounced again press Return. You can do this any number of times. The
Amiga voice is difficult to understand with some words. You will get two
tries to spell the word right, after which the correct spelling will be
written to the screen. When all the words in the line are finished, you will
be allowed to repeat that line of words, go on to the next line, or quit.
     In this drawer you will find the SPELLFILE needed by this program.

END
