@@
D. Procedures


     Procedures are POPS language subroutines which are normally
written by the user at run time in order to avoid repeated typing of
frequently used sequences of POPS statements.  As was mentioned above,
procedures offer powerful looping and conditional execution capabilities
which are not available in the normal execution mode.  Parameters may
be passed to and from a procedure via a "formal parameter list" and/or
via adverbs.  A procedure declaration must begin a line of input and
follow the format

       PROCEDURE   < name >   (  < formal parameter list >  )

where the word PROC may be used instead of PROCEDURE.  The < formal
parameter list > is optional.  If it is used, the parameters must be
enclosed in parentheses and separated by commas.  The symbols used in
the formal parameter list may be of any type, but they must be 
previously defined global symbols (i.e. adverbs).  Note, a dummy proc
may be used simply to define needed new adverbs.

     The procedure declaration causes POPS to enter the "compile" mode
and to use the prompt symbol ':' .  In this mode, input lines are
compiled in essentially the normal way, but the compiled code is
stored in a core area rather than executed.  While in this mode, the
user can create new global symbols in three ways.  Real scalars may be
declared using

        SCALAR   <name1>  ,  <name2>  ,  ......

Real arrays may be declared using

        ARRAY  <name1> ( <lims1> ) , <name2> ( <lims2> ) ....

and character scalars and arrays may be declared using

        STRING * n  <name1> ( <lims1> ) , <name2> ( <lims2> ) ....

where the <namei> are the new symbol names, the <limsi> are the
desired array limits, and n is the number of characters in the string
scalar or in each element of the string array.  Note that n is taken to
be 1 if the * is omitted.  The <limsi> are required for real and string
arrays, but should be omitted for string scalars.  The <limsi> must be
enclosed in parentheses and commas must separate the limits for each
axis (if there is to be more than one axis).  The limits for each axis
may be written as

             < scalar1 >  TO  < scalar2 >
             < scalar1 >  :   < scalar2 >
             < scalar >

where <scalar2> must be greater than or equal to <scalar1> and where
the third form is equivalent to  1  TO  <scalar>.  Examples:

        ARRAY  ALPHA(N), BETA (-1:1, 9 TO 10), C (3)
        STRING*12 CALPH(LEVEL), CBET(-LEVEL:0,3,6)

which, among others, create a one-dimensional array real array C
having elements C(1), C(2), and C(3) and a two-dimensional array BETA
having elements, in order, BETA(-1,9), BETA(0,9), BETA(1,9),
BETA(-1,10), BETA(0,10), and BETA(1,10).  Any subscripts other than
these will cause an error condition to arise.  (Subscripts are turned
into integers by truncation before evaluation. Thus, C(2.6) is the
same as C(2).)  It is legal to use real scalar variables (but not
single elements of arrays) in these declarations.  The values of the
variables at the time the array is declared determine the (permanent)
dimensions of the array.  In a similar way, variables may alse be
used for the number of characters in strings.  Of course, variables
used in this way must be previously defined in order to have
meaningful values.

     Every procedure must be terminated with a FINISH statement and
must contain a RETURN statement at each point at which control is to
pass back to the calling routine.  The RETURN statement has the format

               RETURN   < exp >

where the < exp > is optional and may be a numeric or character
constant, a logical or arithmetic POPS expression, or an entire real or
character array.  If < exp > is used, then the procedure has the
attributes of a function.  In any case, the RETURN is required to
rebuild the linkage back to the calling function and to place the final
values of the formal parameters back into the calling parameters.  This
is particularly important when a procedure is called by another
procedure.  The FINISH statement causes a clean-up pass through the
procedure (to satisfy forward references) and returns POPS to the
normal mode.  FINISH must be the last statement on a line and, if
the procedure contains IF or WHILE statements, FINISH must appear on
a line by itself.  Example:

     PROC MAX(X,Y);IF X>Y THEN RETURN X ELSE RETURN Y END
     FINISH


     After a procedure has been typed (from PROC through FINISH), it
may be listed and edited.  The LIST statement has the form

             LIST  < proc-name >

and must be the only statement on a line.  A typical output is

        1     PROC PRTMAX ( X , Y )
        2     IF X > Y
        3        THEN TYPE 'X=',X
        4             RETURN X
        5        ELSE TYPE '=Y',Y
        6             RETURN Y
        7        END
        8     FINISH


The edit instruction has the form

              EDIT   < proc-name >   < line-number >

and must be the only statement on a line.  This statement places POPS
in the "compile (edit)" mode and switches the prompt character to ';' .
If the <line-number> specified corresponds to one of the line numbers
in the listing, then that line will be replaced with the first line
entered.  If additional lines are entered, they will be inserted after
the replaced line.  If the <line-number> specified lies between two
line numbers in the listing (done by giving it a fractional part),
then only insertion takes place.  Deletion is done by entering an empty
line.  The command ENDEDIT (which must appear by itself on a line) is
used to terminate the editing session.  Note that editing will
probably alter the procedure line numbers.  The user should list the
procedure again before attempting further editing.  Example continued:

         > EDIT PRTMAX 4.5
         ;      ELSE IF X = Y
         ;         THEN TYPE 'EQUAL',Y
         ;ENDEDIT
         >LIST PRTMAX
             1     PROC PRTMAX ( X , Y )
             2     IF X > Y
             3        THEN TYPE 'X=',X
             4             RETURN X
             5        ELSE IF X = Y
             6           THEN TYPE 'EQUAL',Y
             7        ELSE TYPE '=Y',Y
             8             RETURN Y
             9        END
            10     FINISH
         >EDIT PRTMAX 7
         ;      ELSE TYPE 'Y=',Y
         ;      END
         ;ENDEDIT
         >LIST PRTMAX
             1     PROC PRTMAX ( X , Y )
             2     IF X > Y
             3        THEN TYPE 'X=',X
             4             RETURN X
             5        ELSE IF X = Y
             6           THEN TYPE 'EQUAL',Y
             7           ELSE TYPE 'Y=',Y
             8           END
             9             RETURN Y
            10        END
            11     FINISH
         >

Actually, the editor will give an error message following the first of
the two EDIT ... ENDEDIT sequences to remind the user that there is an
IF, FOR, or WHILE loop missing an END statement.

     Procedures may include any executable POPS statement except those
statements which include the pseudoverbs PROCEDURE, PROC, EDIT,
ENDEDIT, STORE, RESTORE, SAVE, GET, LIST, CORE, SCRATCH, COMPRESS, and
RUN.  In particular, procedures may call previously defined
procedures.  However, they may not call themselves or otherwise cause
recursion to occur.  In POPS, all symbols are global symbols.  Thus,
if a procedure containing, for example, FOR I = ... calls another
procedure containing FOR I = ... then the value of I in the first
(calling) procedure will be altered by the call.  This applies even
to the symbols used in formal parameter lists.  Be thou warned!

     A procedure may be caused to execute in normal mode simply by
invoking its name and providing any needed parameters.  Thus, the above
procedure could be invoked by

           A3  =  PRTMAX (A1,A2)

which would print an appropriate message and set A3 to the maximum of
A1 and A2.  The actual arguments provided in a procedure call must
match, in type and length, the formal parameters of the procedure
declaration.  This requirement arises because

           PROC  FUNC ( X1, X2, X3 )
              statements
           FINISH
           FUNC (A1,A2,A3)

is equivalent to

           PROC FUNC
              statements
           FINISH
           X1 = A1; X2 = A2; X3 = A3
           FUNC
           A1 = X1; A2 = X2; A3 = X3

An exception to this rule arises, of course.  If a formal parameter
(e.g. the Xi above) is a scalar, then the actual parameter (Ai) may
be a constant or an expression.  In that case, the last line above is
not performed for the particular variable.  Thus, if

           STRING * 12  STRA
           PROC XYZ (STRA, ...)
then
           XYZ ( 'XYZF', ... )

is ok.  As explained in the discussion on the = verb, the match in
lengths of arrays does not require a match in the details of the
dimensions and array ranges.  Thus, if

           ARRAY  A1 (-1 TO 1, 3, 8:10), X1(27)
           PROC FUNC(X1, ...)
then
           FUNC (A1, ...)

is ok.  If a POPS error condition arises during the execution of a
procedure, then the execution of that procedure (and the rest of the
input line) is terminated.
@@
E. Pseudoverbs


     Pseudoverbs are special verbs which, by their nature, require
special grammar in order to be processed.  The safest rule for pseudo-
verbs is to make the pseudoverb and whatever arguments it may require
the sole contents of the input line.  Of course, this isn't entirely
true.  The actual rules for the pseudoverbs which have already been
discussed are as follows:

    (1) PROCEDURE and PROC must be the first statement on a line, but
        other statements may follow.
    (2) ARRAY, STRING, ELSE, and THEN may occur anywhere in a line
         followed and preceded by other statements.
    (3) FINISH must be the last statement in a line and the only
        statement if an IF or WHILE occur in the procedure.
    (4) IF and WHILE must have a logical expression following them on
        the same line, but other statements may precede and follow.
    (5) EDIT, ENDEDIT, and LIST must occur on lines by themselves.

Most of the pseudoverbs to be introduced in this section follow the
simple rule: they must occur by themselves on a line and must not
be used in procedures.  HELP, INPUTS, INP, and GO may occur anywhere
in a line, including within procedures.

     The compiled code for procedures is stored in a linked list in core
along with the rest of the symbol table.  This allows procedures to be
executed rapidly and efficiently.  When a whole procedure or a line
from a procedure is replaced or deleted, only the linking list is
changed.  The deleted code remains in core.  Since core space is finite,
it is clear that difficulties can arise.  Procedures which are typed
compactly using the minimum number of blanks and the full input line
occupy less core.  This is the main reason for the emphasis on typing
rules in this chapter.  There are eight pseudoverbs designed to assist
the user to manage his core space.  They are

   (1)   CORE
      which reports the amount of core used and available in the area
      used for the symbol table plus compiled procedures, the area used
      for adverb values, and the area used for procedure source text.

   (2)   SCRATCH   < procedure-name >
      which deletes the specified procedure, but does not recover any
      core space.

   (3)   COMPRESS                              **** NOT AVAILABLE YET
      which recovers any unused space.  Note - this remains to be
      coded unfortunately.

   (4)   STORE   < n >
      which stores the current POPS environment (symbol table, adverb
      values, procedure code and text) in the specified storage area.
      There are five such storage areas: < n > = 1 through 5.  STORE
      does not alter any of the current POPS environment.  STORE,
      together with RESTORE, allows the user to build several environ-
      ments appropriate to the various areas of his data reduction
      problem and, then, to apply these environments conveniently in
      any appropriate order.  The user must remember, however, that
      these areas are "public".  He cannot assume that an environment
      STOREd today will still be there tomorrow.

   (5)   RESTORE   < n >
      which replaces the current POPS environment with the contents of
      the specified storage area.  There are five user storage areas:
      < n > = 1 through 5.  In addition, there is a storage area < n >
      = 0 which contains the initial POPS environment provided by the
      programming staff.  In effect, RESTORE 0 initializes all the
      standard adverbs, destroys all the procedures and adverbs created
      by the user, and recovers all the space occupied by those adverbs
      and procedures.

   (6)   SAVE    < save-name >
      which stores the current POPS environment in the specified
      "user-owned" file.  Each user may have up to 99 such storage
      files.  If the specified file already exists, it will be
      overwritten.  These files are for longer term storage and for
      communicating the user's POPS environment to the user's batch 
      jobs.  The < save-name > is any user-chosen name of no more than
      16 characters beginning with an alphabetic character.  It may
      contain imbedded blanks, but if it does, the name must be typed
      with surrounding quotes (').

   (7)   GET     < save-name >
      replaces the current POPS environment with the contents of the
      specified, user-owned storage area.  The < save-name > must match
      (via the usual minimum matching) the name of a storage area 
      created previously via a SAVE operation.  The verb SGINDEX will
      list the user's current storage areas by name and date.

   (8)   SGDESTR   < save-name >
      destroys the user-owned storage area specified by the <save-name>
      Note, the name must match exactly the name of the storage area
      given when it was created via a SAVE operation.


     An important pseudoverb is RUN.  Its format is

            RUN    < name >

where < name > is the name of a text file in a special RUN area on
disk.  RUN causes POPS to take its input from this text file.  When the
file has been exhausted, POPS resumes reading from the user's terminal.
The text file may contain any valid POPS statement except another RUN
statement.  The program will compile and execute the statements just as
if they had come from the user's terminal.  As was mentioned above, the
STORE-RESTORE storage areas are public and, hence, unsafe for long-term
storage.  Thus, a user who wishes to have a particular environment (e.g.
special procedures, preferred adverb values, etc.) each time he uses
the POPS-based program should prepare the commands necessary to create
this environment in a RUN text file.  Then, each time he uses the
program, he simply issues the command RUN <name> and the environment he
desires will be established.  Of course, RUN files may also be used to
execute verbs, tasks, and, even, batch processes.  The text files are
prepared using the local computer's text editor.  Instructions for
doing this are given later in this manual.


     There are four pseudoverbs which are very important and, hence,
have been specially coded to act almost like normal verbs.  They are
HELP, INPUTS, INP, and GO.  They may be entered anywhere on a line
and may be used in procedures.  Their grammar is described below:

     The HELP pseudoverb is used to provide detailed information about
POPS and about the available application routines.  The format is

                   HELP   < name >

where <name> is the name of any programmer-provided verb, pseudoverb,
task, procedure, or adverb or is one of a number of other special
symbols.  In most cases, HELP lists the specified text file on the
user's terminal.  The text file contains a description of the function
of <name> and brief descriptions of any associated symbols.  For
example, HELP GO will describe what the pseudoverb GO does and how it
uses the values stored in the adverbs DOWAIT and TASK.  Chapter IV of
this manual is basically a suitably ordered dump of all of the available
HELP text files.  There are a few special values of <name> which do not
access text files.  Instead, they cause HELP to read the current symbol
table and to list on the terminal the names of all symbols of the
specified type.  These special values of <name> are

    VERBS          ( verbs then pseudoverbs)
    PSEUDO         ( pseudoverbs )
    ADVERBS        ( real scalars then real arrays then strings)
    REALS          ( real scalars)
    ARRAYS         ( real arrays )
    STRINGS        ( character scalars and arrays)
    PROCS          ( procedures )
    PROCEDURES     ( procedures )

These lists will, of course, include any symbols defined by the user at
run time.  If no <name> is given, then HELP HELP is performed.

     A second powerful method of run-time documentation is provided by
the pseudoverbs INP and INPUTS.  Their format is

            INP      < name >
            INPUTS   < name >

where <name> is the name of a verb or task.  If <name> is omitted, the
value stored in the adverb TASK is used.  Inputs produces a listing on
the terminal of all the adverbs used by the specified verb or task.  A
brief description and the current value(s) of each of the adverbs are
also listed.  In addition, error messages are produced whenever a
numeric adverb has a value outside the allowed range.  INPUTS causes
the displayed messages to be stored in the message log file.  INP
simply displays them on the screen, which is faster, but less
permanent.

     The GO pseudoverb is used to activate tasks.  Its basic format is

            GO     < name >

where < name > is the name of the task.  If < name > is omitted, the
value stored in the adverb TASK is used.  On GO, the POPS-based program
puts the needed adverb values on a disk (checking that they are in
range) and signals the operating system to start the task.  The POPS-
based program then waits for a signal from the task before continuing.
If the adverb  DOWAIT  was false ( < 0 ) and the POPS program is an
interactive one, then the signal will normally come as soon as the task
has read its adverb values from disk.  Otherwise, the signal will come
only after the task has finished.  Since a single POPS-based program
can only run one version of a given task at a time, the adverb DOWAIT
can be quite useful.  For example,
      FOR I = 16:24; GETNAME(I); GO FITTP; END
will write maps 16 through 24 on a FITS tape, but only if DOWAIT was
set to TRUE.  Otherwise, the POPS-based program would try to start a
second FITTP while the first was still running.  The resulting error
would cancel the remainder of the line and only map 16 would end up on
tape.

     The TGET pseudoverb is closely related to GO and is used to
recover the adverb values last used for a task.  Its format is

            TGET     < name >

where < name > is the name of the task.  If < name > is omitted, the
name stored in the adverb TASK is used.  On GO, the adverbs sent to the
task are also stored automatically in a directoried file available from
any interactive AIPS, but only to the logon user.  (Batch AIPS have
separate files of the same sort.)  This file may hold a large number of
tasks, but holds only the adverb values from the most recent execution
of any given task.  The verb TGINDEX lists the tasks available for TGET
and the times they were last executed.  To reduce repetitive typing
of the task name, TGET fills in the TASK adverb with the name of the
task just gotten.  This allows the user to use the "defaults" with
INP, INPUTS, and GO (so long as he wishes to refer to the same task).

     The pseudoverbs GET, HELP, INPUTS, INP, GO, and TGET all depend on
members in system disk files.  Their argument < name > (or its default)
need not be in the symbol table, but must be in the directory of the
system text file areas.  Thus, we have implemented "minimum match" on
the argument < name > as well.  The user need type only as many
characters of < name > as are required to obtain a unique match to the
name of the desired text file.  If a unique match is not found, then
suitable error messages are produced.  NOTES: (1) This minimum matching
does not apply to the special HELP symbols listed above.  They must be
typed correctly and in full.   (2) If < name > is omitted, GO and TGET
use the contents of the adverb TASK to determine the desired task name
and then alter the contents of TASK to the full name determined via the
minimum matching.  It does this in order to provide the correct task
name to those verbs which require it (i.e. WAITTASK, ABORTASK).  The
adverb TASK is altered by TGET even when < name > is specified.  (3) For
GO and TGET, the minimum matching is done against a list of all verbs
and tasks which have INPUTS files, not just some list of tasks or 
entries in the task-adverb save area.
