 
    A SIMPLE MACRO PROCESSOR - USER'S GUIDE
    - ------ ----- ---------   ---- - -----
 
 
       JOHN R. RICE, CALVIN RIBBENS AND WILLIAM A. WARD
 
 
 
        ABSTRACT
        --------
 
 
      THIS IS THE USER'S GUIDE FOR A SIMPLE MACRO  PROCESSOR.
 THIS TOOL IS DESIGNED TO MANIPULATE FORTRAN PROGRAM TEXT FOR
 APPLICATIONS SUCH AS: 1. THE  IMPLEMENTATION  OF  VERY  HIGH
 LEVEL  LANGUAGES,  2.  MODIFYING  CODE FOR PARTICULAR TARGET
 ENVIRONMENTS, 3. GENERATING CODE FOR  PARTICULAR  PRECISIONS
 OR VARIABLE TYPES.  IT HAS THE BASIC FACILITIES REQUIRED FOR
 A GENERAL PURPOSE MACRO PROCESSOR AND CAN BE  USED  IN  MOST
 MACRO PROCESSOR APPLICATIONS.
 
      THIS PROGRAM WAS DEVELOPED AT PURDUE UNIVERSITY AS PART
 OF  THE  TOOLPACK  PROJECT.   THIS WORK WAS SUPPORTED BY THE
 NATIONAL SCIENCE  FOUNDATION  UNDER  GRANT  MCS  -  7926310.
 PLEASE  REPORT ANY BUGS OR SUGGESTIONS TO THE AUTHORS AT THE
 ADDRESS: COMPUTER  SCIENCE  DEPARTMENT,  PURDUE  UNIVERSITY,
 WEST LAFAYETTE, IN 47907.
 
 
        CONTENTS
        --------
 
 I.   GENERAL DESCRIPTION
 
 II.  A SIMPLE EXAMPLE
 
 III. SUBSTITUTION FACILITIES
 
 IV.  MACRO PROCESSING DIRECTIVES
 
 V.   FURTHER EXAMPLES
 
 VI.  PREPARATION OF A TUNED VERSION OF THE MACRO PROCESSOR
 
 VII. ERROR MESSAGES
 
 VIII.REFERENCES
 
 
 
 
 I.  GENERAL DESCRIPTION
 
      THIS PROCESSOR ACCEPTS AS INPUT TEMPLATES  OR  PATTERNS
 FOR  PRODUCING TEXT IN SOME USER SPECIFIED FORMAT.  ALTHOUGH
 IT HAS CERTAIN FEATURES WHICH ARE PARTICULARLY HELPFUL  WHEN
 THE  TEXT HAPPENS TO BE LINES OF FORTRAN, THESE FEATURES ARE
 NOT CRUCIAL TO ITS OPERATION.  THIS PROCESSOR IS PART  BATCH
 EDITOR, PART MACRO PROCESSOR, AND PART INTERPRETER.  IT IS A
 BATCH EDITOR IN THE SENSE THAT IT  CAPABLE  OF  MANIPULATING
 TEXT.   IT IS A MACRO PROCESSOR IN THAT IT IS ABLE TO DEFINE
 AND REDEFINE MACROS AND SUBSTITUTE THEIR VALUES WHEN  REFER-
 ENCES  TO  THEM  OCCUR IN THE INPUT TEXT.  FINALLY, IT IS AN
 INTERPRETER BECAUSE ITS COMMANDS ARE DECODED AND EXECUTED AS
 THEY ARE ENCOUNTERED.
 
      SPECIFICALLY, THE INPUT CONSISTS OF  COMMANDS  EMBEDDED
 IN  LINES  OF  TEXT.   THESE  COMMANDS  MAY TAKE THE FORM OF
 EITHER SUBSTITUTIONS OR DIRECTIVES.  TWO SPECIAL  CHARACTERS
 ARE  USED  TO  DISTINGUISH  COMMANDS FROM ORDINARY TEXT: THE
 SUBSTITUTION PREFIX CHARACTER (CSUB) AND THE DIRECTIVE  PRE-
 FIX  CHARACTER (CDIR).  FOR THE REMAINDER OF THIS REPORT THE
 CSUB IS ASSUMED TO BE $ AND THE CDIR IS  ASSUMED  TO  BE  *.
 THE PROCESSOR OPERATES AS FOLLOWS.  EACH INPUT LINE IS FIRST
 SCANNED FOR OCCURRENCES OF THE CSUB AND IF SUBSTITUTIONS ARE
 REQUIRED,  THEN  THEY ARE PERFORMED.  THEN THE LINE IS EXAM-
 INED TO DETERMINE IF IT IS A DIRECTIVE LINE OR A TEXT  LINE.
 IF  THE  FIRST  NONBLANK  CHARACTER IN THE LINE IS THE CDIR,
 THEN THE DIRECTIVE IS DECODED AND EXECUTED.  OTHERWISE,  THE
 LINE  IS ASSUMED TO BE A TEXT LINE AND IS COPIED TO THE OUT-
 PUT FILE.  NOTE THAT SUBSTITUTIONS MAY TAKE  PLACE  IN  BOTH
 DIRECTIVE AND TEXT LINES.
 
      ONE SHOULD VIEW THE USE OF THIS PROCESSOR AS CONSISTING
 OF  TWO PHASES.  IN THE FIRST, MACRO NAMES AND THEIR ASSOCI-
 ATED VALUES ARE ENTERED  INTO  THE  SYMBOL  TABLE.   IN  THE
 SECOND,  TEXT CONTAINING DIRECTIVES AND REFERENCES TO MACROS
 DEFINED IN THE FIRST PHASE IS PROCESSED.   IN  THE  SIMPLEST
 CASE,  THE  SYMBOL TABLE MIGHT CONSIST OF THE MACROS STUDENT
 AND ID ALONG WITH THEIR RESPECTIVE VALUES  'JOHN  JONES' AND
 22215.   THE  TEXT INPUT MIGHT BE $STUDENT, ID = $ID AND THE
 OUTPUT WOULD BE JOHN JONES, ID = 22215.  THE  PROCESSOR  HAS
 THREE LEVELS OF COMMANDS:
 
 
 1.  DIRECTIVES WHICH BUILD OR MANIPULATE THE SYMBOL TABLE:
 
 *APPEND                   APPEND A VALUE TO A VARIABLE.
 *APPEND, *ENDAPP          APPEND LINES OF TEXT TO A VARIABLE.
 *DELETE                   DELETE A VARIABLE FROM THE TABLE.
 *RESET                    RESET A LIST POINTER.
 *SET                      ASSIGN A VALUE TO A VARIABLE.
 *SET, *ENDSET             ASSIGN LINES OF TEXT TO A  VARIABLE
                           OR PERFORM MULTIPLE ASSIGNMENTS.
 
 
 2.  MACRO INVOCATIONS:
 
 $(NAME) OR $NAME          SUBSTITUTE THE VALUE OF NAME.
 $DEF(NAME)                SUBSTITUTE  '.TRUE.'  IF  NAME   IS
                           DEFINED AND '.FALSE.' OTHERWISE.
 *INCLUDE(NAME)            INCLUDE LINES OF TEXT.
 $LABEL OR $(LABEL)        SUBSTITUTE A NEW LABEL.
 $LIST(ITEMS)              SUBSTITUTE THE NEXT ITEM  FROM  THE
                           LIST ITEMS.
 $$                        REPLACE '$$'  BY  '$'.   (EMBEDS  A
                           SINGLE CSUB IN THE TEXT.)
 
 
 3.  CONTROL DIRECTIVES
 
 *COMMENT, *ENDCOM         IGNORE THE ENCLOSED COMMENT LINES.
 *DO, *ENDDO               SPECIFY LOOPS.
 *END                      END OF INPUT.
 *IF, *ELSE, *ENDIF        CONDITIONAL PROCESSING OF LINES.
 
 
      THE FEATURES  WHICH  DISTINGUISH  THIS  PROCESSOR  FROM
 OTHER,  PERHAPS  MORE  SOPHISTICATED,  MACRO PROCESSORS ARE:
 FIRST, IT HAS A SMALL AND SYNTACTICALLY  CONSISTENT  SET  OF
 COMMANDS WHICH ARE EASILY LEARNED.  SECOND, IT IS CAPABLE OF
 RECURSIVE MACRO SUBSTITUTION.  FINALLY,  IT  IS  WRITTEN  IN
 PFORT-PORTABLE  FORTRAN.   THOUGH THIS LAST FEATURE SOMEWHAT
 REDUCES THE PROCESSOR'S  PERFORMANCE,  IT  IS  AN  IMPORTANT
 ADVANTAGE BECAUSE IT REDUCES THE HUMAN TIME REQUIRED TO MAKE
 THE PROCESSOR OPERATIONAL ON A GIVEN SYSTEM.
 
 
 
 II.  A SIMPLE EXAMPLE
 
      THE MACRO PROCESSOR IS INVOKED BY A SUBROUTINE CALL  OF
 THE FORM
 
          CALL  TPDRV (EUNIT, IUNIT, LUNIT, OUNIT),
 
 WHERE EUNIT IS THE UNIT NUMBER OF THE ERROR FILE,  IUNIT  IS
 THE  UNIT NUMBER OF THE INPUT FILE, LUNIT IS THE UNIT NUMBER
 OF THE LISTING FILE, AND OUNIT IS THE  UNIT  NUMBER  OF  THE
 OUTPUT FILE.  IN THE FOLLOWING EXAMPLE, FOUR FILES ARE USED:
 THE FIRST INPUT FILE, ASSIGNED TO UNIT 4,  CONTAINS  DEFINI-
 TIONS  OF  MACROS  REFERENCED  IN  THE  SECOND  INPUT  FILE,
 ASSIGNED TO  UNIT  5.   THE  ERROR  AND  LISTING  FILES  ARE
 ASSIGNED  TO  UNIT 6 AND THE OUTPUT FILE IS ASSIGNED TO UNIT
 7.
 
 
 MAIN PROGRAM:
 
       CALL  TPDRV  (6, 4, 6, 7)
       CALL  TPDRV  (6, 5, 6, 7)
       STOP
       END
 
 FIRST INPUT FILE (ON UNIT 4).
 
 *SET
        LASTNAME = 'DOE'
        FIRSTNAME = 'JOHN'
        MONTH = 08
        DAY = 24
        YEAR = 81
        SEMESTER = 'FALL'
 *ENDSET
 *SET ( NCOURSES = 3 )
 *SET ( COURSES = 'BIO 255$$/' )
 *APPEND ( COURSES, 'GEO 110$$/' )
 *APPEND ( COURSES, 'PSY 201' )
 *END
 
 TPDRV APPLIED TO THE FIRST INPUT FILE MERELY CREATES A  SYM-
 BOL TABLE FOR LATER USE.
 
 
 SECOND INPUT FILE (ON UNIT 5).
 
 *SET ( NAME = '$$LASTNAME, $$FIRSTNAME' )
 *SET ( DATE = '$$MONTH/$$DAY/$$YEAR' )
 NAME:         $NAME
 DATE:         $DATE
 SEMESTER:     $SEMESTER
 LIST OF COURSES:
 *DO ( I = 1, NCOURSES )
          $I.   $LIST(COURSES)
 *ENDDO
 *END
 
 THE PROCESSOR OUTPUT ON UNIT 7 IS:
 
 NAME:         DOE, JOHN
 DATE:         08/24/81
 SEMESTER:     FALL
 LIST OF COURSES:
          1.   BIO 255
          2.   GEO 110
          3.   PSY 201
 
 TPDRV ALSO PRODUCES A LISTING OF THESE TWO FILES ON UNIT 6.
 
 
      NOTE THAT AN ITEM SEPARATOR($/) IS EMBEDDED IN THE TEXT
 BY  SPECIFYING  $$/; OTHERWISE, THE PROCESSOR WOULD EXPECT A
 MACRO NAME TO FOLLOW THE CSUB.  ALSO NOTE THAT THE SAME OUT-
 PUT RESULTS IF THE TWO INPUT FILES ARE CONCATENATED AND READ
 IN AS ONE.
 
 
 
 III.  SUBSTITUTION PROCESSING FACILITIES
 
 
 
 III.A.  SIMPLE SUBSTITUTIONS
 
      A REFERENCE TO THE MACRO NAME MAY BE SPECIFIED BY $NAME
 OR  BY $(NAME).  THE LATTER FORM OF SUBSTITUTION IS REQUIRED
 WHEN THE SUBSTITUTION TAKES PLACE WITHIN A BLOCK OF TEXT AND
 IT  IS  NECESSARY  TO  SEPARATE  THE CHARACTERS OF NAME FROM
 THOSE IN THE SURROUNDING TEXT.  NAME MAY BE AN  ALPHANUMERIC
 STRING  OF ANY LENGTH BUT ITS FIRST CHARACTER MUST BE ALPHA-
 BETIC.  A MACRO IS ALSO CALLED A TEMPLATE VARIABLE  AND  ITS
 VALUE  IS  AN  ARBITRARY CHARACTER STRING.  THE SUBSTITUTION
 OPERATOR $ APPLIED TO A MACRO RESULTS IN THE STRING ELEMENTS
 BEING  EVALUATED ACCORDING TO THE RULES OF THE MACRO PROCES-
 SOR.
 
      SUBSTITUTIONS MAY BE RECURSIVE.   FOR  EXAMPLE,  IF  WE
 HAVE
 
          NAME               VALUE
           A                A$(B)$(E)
           B                BC$(D)
           D                D
           E                E
 
 THEN $A RESULTS IN SUBSTITUTING ABCDE.  THE DEPTH  TO  WHICH
 SUBSTITUTIONS  MAY  BE  NESTED DEPENDS ONLY ON THE AMOUNT OF
 AVAILABLE WORKSPACE.   RECURSIVE  SUBSTITUTION,  ALONG  WITH
 MEMORY  MANAGEMENT  FOR THE PROCESSOR AND THE IMPLEMENTATION
 OF DO LOOPS AND LISTS, ALL MAKE USE  OF  THE  SAME  POOL  OF
 POINTERS.  THEREFORE, A DEPTH OF RECURSION WHICH IS IMPOSSI-
 BLE WHEN THE SYMBOL TABLE IS RELATIVELY FULL MIGHT EASILY BE
 ACHIEVED WHEN SOME SPACE IS RETURNED (SEE *DELETE).
 
      IF A SINGLE OCCURRENCE OF $ (THE CSUB) IS NEEDED  IN  A
 STRING, THEN $$ SHOULD BE SPECIFIED.  THIS IS SIMILAR TO THE
 TECHNIQUE USED BY SOME FORTRAN COMPILERS TO EMBED QUOTES  IN
 QUOTED STRINGS.
 
 
 
 III.B.  THE $DEF FUNCTION
 
      THE $DEF FUNCTION IS USED TO DETERMINE  IF  A  NAME  IS
 DEFINED  IN  THE PROCESSOR SYMBOL TABLE.  $DEF(NAME) RETURNS
 THE STRING .TRUE. IF NAME IS  DEFINED  AND  RETURNS  .FALSE.
 OTHERWISE.   THIS  FUNCTION  IS  USED WITH THE *IF DIRECTIVE
 DISCUSSED BELOW.
 
 
 
 III.C.  THE $LABEL FUNCTION
 
      THE SPECIAL VARIABLE LABEL IS USED TO GENERATE  FORTRAN
 LABELS OR OTHER SEQUENCES OF INCREASING INTEGERS.  EACH TIME
 LABEL IS REFERENCED, ITS VALUE IS INCREMENTED BY  1.   THUS,
 WHEN  $LABEL  OR  $(LABEL)  IS  ENCOUNTERED IN THE TEXT, THE
 CURRENT VALUE OF LABEL IS SUBSTITUTED, AND LABEL  IS  INCRE-
 MENTED.   LABEL  MUST  BE INITIALIZED USING A *SET STATEMENT
 AND MAY BE ASSIGNED A NEW VALUE AT ANY TIME.   LEGAL  VALUES
 FOR LABEL ARE INTEGERS BETWEEN 1 AND 99999 INCLUSIVE.  IF IT
 IS SET TO ANY OTHER STRING, AN ERROR  MESSAGE  IS  GENERATED
 THE NEXT TIME LABEL IS REFERENCED.
 
 
 
 III.D.  THE $LIST FUNCTION
 
      LISTS OF ITEMS MAY BE  CREATED  AND  SUBSTITUTED.   THE
 LIST SEPARATOR IS $/ AND THUS
 
 *SET(XYZ = ' A $$/ B+C $$/ D*E $$/ ')
 *SET(THREELINES)
      THIS IS LINE 1
    $$/THIS IS LINE 2
    $$/THIS IS LINE 3
    $$/
 *ENDSET
 
 CREATES TWO LISTS: XYZ = (A, B+C, D*E) AND THREELINES =
      THIS IS LINE 1
      THIS IS LINE 2
      THIS IS LINE 3
 
 THE STATEMENT
              *APPEND (XYZ, ' F-G $$/ HIJ $$/ ')
 LENGTHENS THE LIST XYZ BY ADDING THE TWO ITEMS F-G AND HIJ.
 
      THE $LIST FUNCTION IS USED TO SUBSTITUTE ITEMS  FROM  A
 LIST ONE AT A TIME.  THUS THE INPUT TEXT
 
      X = $LIST(XYZ)
      Y = $LIST(XYZ)
      Z = $LIST(XYZ) - ($LIST(XYZ))
 
 RESULTS IN THE OUTPUT TEXT
 
      X = A
      Y = B+C
      Z = D*E - (F-G)
 
 THE NEXT REFERENCE TO $LIST(XYZ), WHEREVER IT MIGHT BE, PRO-
 DUCES  HIJ.   THIS  FUNCTION  TREATS A VARIABLE AS A LIST OF
 ITEMS SEPARATED BY THE MARKER $/.  EACH LIST HAS  A  POINTER
 WHICH  IS INCREMENTED EACH TIME THE LIST IS REFERENCED.  THE
 POINTER MAY BE RESET TO THE START OF  THE  LIST.   THUS  THE
 INPUT
 
      *RESET(XYZ)
      K = $LIST(XYZ)
 
 RESULTS IN
 
      K=A
 
 IF THE RESET  WERE  NOT  PRESENT,  ONE  WOULD  OBTAIN  K=HIJ
 INSTEAD.   IF  THE POINTER REACHES THE END OF THE LIST, THEN
 THE NEXT REFERENCE TO THE LIST RESULTS IN AN  ERROR  MESSAGE
 AND NO SUBSTITUTION IS MADE.
 
 
 
 III.E.  SPECIAL ESCAPE CHARACTERS
 
      THE USE OF SPECIAL ESCAPE CHARACTERS HAS  ALREADY  BEEN
 ILLUSTRATED; THE COMPLETE LIST OF THESE CHARACTERS FOLLOWS:
 
 $    SUBSTITUTION PREFIX CHARACTER (CSUB).  IT SIGNALS  THAT
      THE  NEXT  NAME IS A VARIABLE WHOSE VALUE IS TO BE SUB-
      STITUTED.  THE CHARACTER IS DOUBLED TO $$ TO OBTAIN A $
      INSIDE A QUOTED STRING.
 
 *    DIRECTIVE PREFIX CHARACTER (CDIR) IT SIGNALS THE BEGIN-
      NING  OF A PROCESSOR DIRECTIVE PROVIDED IT IS THE FIRST
      NON-BLANK CHARACTER ON A LINE.  OTHERWISE * IS AN ORDI-
      NARY CHARACTER.
 
 $-   END-OF-LINE MARKER (CEOL).  THIS SPECIAL  CHARACTER  IS
      PLACED  AT THE END OF EVERY INPUT LINE.  ITS EFFECT CAN
      BR OVERRIDDEN BY THE CONTINUATION MARKER.
 
 $+   CONTINUATION MARKER (CONC).  THIS SPECIAL CHARACTER  AT
      THE  END  OF  A LINE OF INPUT OVERRIDES THE END-OF-LINE
      MARKER AND CONTINUES THE LINE WITH THE  TEXT  FROM  THE
      NEXT LINE.
 
 $/   LIST ITEM SEPARATOR (CEOR).  IT SEPARATES  ITEMS  IN  A
      LIST.
 
 
 THE INPUT TEXT
 
 *SET ( AVERYLONGNAME = 'A VERY$+
  LONG STRING' )
 
 ASSIGNS THE SAME VALUE TO AVERYLONGNAME AS THE LINE
 
 *SET ( AVERYLONGNAME = 'A VERY LONG STRING' )
 
 
      VARIABLES MAY CONTAIN END-OF-LINE MARKERS, IF LINES HAS
 THE VALUE
 
       '      T = A $-      A = B $-      B = T $-'
 
 THEN *INCLUDE(LINES) RESULTS IN
 
       T = A
       A = B
       B = T
 
 
      IT HAS ALREADY BEEN NOTED THAT  $$ IS USED TO EMBED  AN
 OCCURRENCE OF THE CHARACTER $ IN A STRING FOR LATER PROCESS-
 ING.  NOTE THAT
 
      *SET(LINES = ' T=A $$- A=B $$- B=T $$-')
 OR
      *SET(LINES)
           T=A
           A=B
           B=T
      *ENDSET
 
 CAN BE USED TO ASSIGN LINES THE VALUE USED  ABOVE.   IF  THE
 DOUBLE  $$ IS NOT USED IN THE FIRST CASE, THEN THE PROCESSOR
 ATTEMPTS TO MAKE AN IMMEDIATE SUBSTITUTION FOR $-; THIS,  OF
 COURSE, FAILS AS THERE IS NO VARIABLE WITH - AS A NAME.
 
      FINALLY NOTE THAT LISTS MAY CONTAIN LINES AND LINES MAY
 CONTAIN  LISTS  BUT THE END-OF-LINE MARKER $- DOES NOT INDI-
 CATE AN END-OF-ITEM MARKER $/ OR VICE-VERSA.
 
 
 
 IV.  MACRO PROCESSING DIRECTIVES
 
      THIS SECTION LISTS (IN ALPHABETICAL ORDER)  THE  DIREC-
 TIVES OF THE MACRO PROCESSOR WHICH PROVIDE THE FACILITIES TO
 CREATE THE SYMBOL TABLE  AND  TO  CONTROL  THE  SUBSTITUTION
 PHASE.
 
 
 
 *APPEND AND *ENDAPP
 
      THE FIRST FORM OF THIS CONSTRUCT IS
 
 *APPEND ( NAME1 , NAME2 OR LITERAL ).
 
 WHERE LITERAL IS A QUOTED CHARACTER STRING, AN INTEGER  CON-
 STANT OR ONE OF THE LOGICAL CONSTANTS .TRUE. OR .FALSE.  THE
 SECOND FORM OF THIS STATEMENT IS
 
 *APPEND ( NAME1 )
       LINES OF TEXT
 *ENDAPP
 
 THIS STATEMENT IS SIMILAR IN SYNTAX AND FUNCTION TO THE  SET
 COMMAND  EXCEPT  THAT  INSTEAD  OF  ASSIGNING A VALUE TO THE
 NAME, IT APPENDS (OR, IF YOU PREFER, CONCATENATES) THE INDI-
 CATED VALUE TO THE STRING ALREADY ASSOCIATED WITH NAME1.  TO
 EMPHASIZE THIS DIFFERENCE A COMMA (,) INSTEAD  OF  AN  EQUAL
 (=)  IS USED TO SEPARATE THE NAME FROM THE RIGHT SIDE.  NOTE
 THAT IT IS MUCH MORE EFFICIENT TO  APPEND  ONE  VARIABLE  TO
 ANOTHER    BY    USING    *APPEND (A, B)   THAN   BY   USING
 *SET (A = '$A$B' ).
 
 
 
 *COMMENT AND *ENDCOM
 
      INPUT FILES MAY BE  DOCUMENTED  BY  BRACKETING  COMMENT
 LINES  WITH  THE DIRECTIVES *COMMENT AND *ENDCOM.  ALL LINES
 BETWEEN THESE TWO DIRECTIVES ARE IGNORED.
 
 
 
 *DELETE
 
      THE STATEMENT
 
 *DELETE ( NAME )
 
 DELETES THE VARIABLE 'NAME' FROM THE SYMBOL TABLE.
 
 
 
 *DO AND *ENDDO
 
      THIS CONTROL STATEMENT HAS A FORM SIMILAR TO  THE  FOR-
 TRAN DO-LOOP:
 
 *DO (INAME = I1, I2, I3)
 
 THE VARIABLE INAME IS THE LOOP INDEX AND I1, I2 AND  I3  ARE
 THE  INITIAL,  FINAL  AND  INCREMENTAL VALUES, RESPECTIVELY.
 THE BEHAVIOR OF THIS CONSTRUCT IS VERY SIMILAR TO  ITS  FOR-
 TRAN 66 COUNTERPART, THAT IS
 A)   THE INDEX MAY NOT BE MODIFIED WITHIN THE RANGE  OF  THE
      DO LOOP.
 
 B)   THE LOOP IS ALWAYS PERFORMED AT LEAST ONCE .
 
 C)   I1 IS THE STARTING VALUE FOR INAME, I2 IS THE  TERMINA-
      TION VALUE, AND I3, WHICH IS OPTIONAL, IS THE STEP SIZE
      FOR INDEX.  I1, I2, AND I3 MUST BE INTEGERS OR NAMES OF
      TEMPLATE VARIABLES CONTAINING INTEGER VALUES.
 
 D)   THE DO RANGE IS CLOSED BY THE STATEMENT *ENDDO.
 
 E)   THE DEPTH TO WHICH DO LOOPS MAY BE NESTED IS RESTRICTED
      ONLY BE THE AMOUNT OF AVAILABLE WORKSPACE.
 
      TO ILLUSTRATE ITS USE SUPPOSE ONE HAS A LIST COEFS WITH
 VALUES  -12.3,  16.2, -4.9, 8.2,... .  THEN THE THREE STATE-
 MENTS
 
 *DO (I = 1, 5, 2)
       A($I,1) = B($I) + ($LIST(COEFS))
 *ENDDO
 
 RESULT IN
 
       A(1,1) = B(1) + (-12.3)
       A(3,1) = B(3) + ( 16.2)
       A(5,1) = B(5) + ( -4.9)
 
 
 
 
 *END
 
      THIS STATEMENT TERMINATES THE EXECUTION  OF  THE  MACRO
 PROCESSOR.
 
 
 
 *IF, *ELSE, AND *ENDIF
 
      THIS CONTROL STATEMENT HAS THE FORM
 
 *IF ( EXPRESSION ) DIRECTIVE OR TEXT LINE
     OR
 *IF ( EXPRESSION )
       LINES IN THE TRUE RANGE
 *ELSE
       LINES IN THE FALSE RANGE
 *ENDIF
 
 THE EXPRESSION INSIDE THE PARENTHESES FOLLOWING THE IF  MUST
 BE ONE OF THE FOLLOWING:
      NAME (WITH A LOGICAL VALUE)
      LOGICAL CONSTANT (.TRUE., .FALSE.)
      NAME1 = NAME2
      NAME = LITERAL
      NAME = INTEGER CONSTANT
 FOR THE ONE-LINE FORM, IF THE VALUE IS TRUE, THEN  THE  LINE
 FOLLOWING THE CLOSING PARENTHESIS IS PROCESSED, OTHERWISE IT
 IS IGNORED.  FOR THE MULTI-LINE FORM, IF THE VALUE IS  TRUE,
 THEN  THE  LINES IN THE TRUE RANGE ARE PROCESSED, OTHERWISE,
 THOSE  IN  THE  FALSE  RANGE  ARE  PROCESSED.   *ELSE'S  ARE
 OPTIONAL AND *IF'S MAY BE NESTED TO ANY DEPTH AS ILLUSTRATED
 BY THE FOLLOWING EXAMPLE.
 
 *SET ( TYPEV = 'VALU' )
 *SET ( L1 = 'VALU' )
 *SET ( L2 = 6 )
 *SET ( L3 = .FALSE. )
 *IF  ( L1 = TYPEV )
        A = B
        *IF ( L2 = 6 )
                    B = C
                    *ELSE
                    B = D
        *ENDIF
        *IF ( L3 )       C = D
        *IF ( $DEF(L3))       D = E
 *ENDIF
 
 RESULTS IN
 
        A = B
                    B = C
        D = E
 
 NOTE THAT EVEN THOUGH L3  IS  .FALSE.,  $DEF(L3)  IS  .TRUE.
 BECAUSE L3 HAS BEEN ASSIGNED A VALUE.
 
 
 
 *INCLUDE
 
      *INCLUDE(NAME) IS AN ALTERNATE FORM OF SUBSTITUTION; IT
 MUST  APPEAR  ON  A LINE BY ITSELF.  ITS PURPOSE IS TO ALLOW
 ONE TO SUBSTITUTE LINES OF TEXT WITHOUT PERFORMING THE  SUB-
 STITUTIONS  WITHIN  THESE  LINES.   THERE  IS  A SWITCH (SEE
 *OPTION BELOW) TO TURN SUBSTITUTION OFF  AND  ON.   IF  THIS
 SWITCH IS ON, THEN *INCLUDE(NAME) AND $(NAME) ARE IDENTICAL.
 THE USE OF THIS FACILITY IS ILLUSTRATED BY THE TEXT
 
 *SET(LINSYSCALL)
    *IF(TIMER)
       *INCLUDE(TIME1)
    *ENDIF
    CALL $NAME($MATRIX,$SOLUTION,$RHS,$NUMBEQNS,WORK,IER)
    *IF(TIMER)
       *INCLUDE(TIME2)
    *ENDIF
 *ENDSET
 
 WHEN THIS TEXT IS PROCESSED WITH THE SUBSTITUTION SWITCH OFF
 AND  TIMER  =  .TRUE.,  THE VALUE OF LINSYSCALL HAS LINES OF
 CODE BEFORE AND AFTER THE SUBROUTINE  CALL  WHICH  TIME  THE
 EXECUTION OF THE SUBROUTINE.  FOR EXAMPLE, WE MIGHT HAVE
 
 *SET(TIME2)
    CALL SECOND(TIME2)
    TIME(KTIME) = TIME2-TIME1
    PRINT $TIMELABEL, TIME(KTIME), $NAME
    KTIME = KTIME+1
 *ENDSET
 
 LATER IN THE  PROCESSING  THERE  WILL  PROBABLY  BE  A  LINE
 *INCLUDE(LINSYSCALL) WITH THE SUBSTITUTION SWITCH TURNED ON.
 AT THAT POINT THE VALUES FOR $NAME AND $TIMELABEL  ARE  SUB-
 STITUTED IN THE CODE TO PRINT OUT THE TIMING INFORMATION AND
 THE NAME OF THE SUBROUTINE BEING TIMED.
 
 
 
 *OPTION
 
      THIS COMMAND HAS THE FORM
 
 *OPTION ( OPTION NAME = NAME OR LITERAL )
 
 AND IS USED TO SET INTERNAL FLAGS AND  VALUES  WHICH  AFFECT
 THE  OPERATION  OF THE MACRO PROCESSOR.  THE FOLLOWING TABLE
 LISTS THE OPTIONS WITH THEIR DEFAULTS.
 
  NAME    DEFAULT   MEANING
 
 CDIR     *         THE DIRECTIVE PREFIX CHARACTER *.
 CEOL     -         THE SECOND CHARACTER OF THE END-OF-LINE MARKER.
 CEOR     /         THE SECOND CHARACTER OF THE END-OF-ITEM MARKER.
 CONC     +         THE SECOND CHARACTER OF THE CONTINUATION MARKER.
 CSUB     $         THE SUBSTITUTION PREFIX CHARACTER.
 ICPLI    72        THE NUMBER OF CHARACTERS PER LINE OF INPUT.
 ICPLO    72        THE NUMBER OF CHARACTERS PER LINE OF OUTPUT.
 IUNITI   5         THE INPUT UNIT NUMBER.
 IUNITL   6         THE LISTING UNIT NUMBER.
 IUNITO   7         THE OUTPUT UNIT NUMBER.
 LBREAK   .TRUE.    TRY TO BREAK LNES LONGER THAN ICPLO AT A
                    CONVENIENT BREAK CHARACTER.
 LCOL1    .TRUE.    CHECK ONLY COLUMN 1 IN THE INPUT FILE FOR
                    OCCURRENCES OF THE CDIR.
 LFORT    .TRUE.    WRITE OUT LONG LINES  BY PROVIDING FORTRAN
                    CONTINUATION CARDS.
 LISTI    .TRUE.    LIST INPUT LINES AS THEY ARE READ IN.
 LISTO    .TRUE.    LIST OUTPUT LINES AS THEY ARE WRITTEN OUT.
 LSUB     .TRUE.    START PROCESSING SUBSTITUTIONS.
 L1TRIP   .TRUE.    USE 1-TRIP DO-LOOPS.
 
 
 NOTE THAT OPTION NAMES WHICH BEGIN WITH C, I, AND L EXPECT A
 VALUE  WHICH CONSISTS OF A CHARACTER, AN INTEGER, OR A LOGI-
 CAL VALUE, RESPECTIVELY.
 
 
 
 *RESET
 
      *RESET( NAME ) RESETS THE LIST POINTER OF NAME  TO  THE
 BEGINNING OF THE LIST.
 
 
 
 *SET AND *ENDSET
 
      THE FIRST FORM OF THIS STATEMENT IS
 
 *SET ( NAME1 = NAME2 OR LITERAL ).
 
 THE VALUE TO BE ASSIGNED ON THE RIGHT OF THE = MAY BE EITHER
 A  VARIABLE  NAME,  IN  WHICH  CASE  THE  VALUE  OF NAME2 IS
 ASSIGNED TO NAME1, OR A LITERAL, IN WHICH CASE  THE  LITERAL
 ITSELF IS ASSIGNED TO NAME1.
 
      THE SECOND FORM OF THIS STATEMENT IS
 
 *SET ( NAME1 )
       LINES OF TEXT
 *ENDSET
 
 THIS CAUSES THE VARIABLE NAME1 TO TAKE ON AS ITS  VALUE  THE
 LINES  OF TEXT UP TO THE NEXT MATCHING *ENDSET.  END-OF-LINE
 MARKERS ARE AUTOMATICALLY SUPPLIED.  THESE LINES OF TEXT ARE
 PROCESSED ONLY FOR SUBSTITUTION  (IF THE SUBSTITUTION SWITCH
 IS ON) AND ARE NOT EXAMINED FOR DIRECTIVES.  IN  PARTICULAR,
 IF  THESE  LINES  CONTAIN  ANOTHER  *SET - *ENDSET PAIR, THE
 INNER *SET WILL NOT BE PROCESSED.  FOR EXAMPLE,
 
 *SET( A )
     *SET( B )
         X = Y + Z
     *ENDSET
 *ENDSET
 
 CAUSES A TO TAKE ON THE VALUE
 
       '*SET ( B )$-        X = Y + Z$-    *ENDSET$-'
 
 THE VARIABLE B, HOWEVER, WILL NOT BE GIVEN A VALUE UNTIL  $A
 IS ENCOUNTERED LATER.
 
      THE THIRD  FORM  OF  THIS  STATEMENT  IS  THE  MULTIPLE
 ASSIGNMENT AND IS ILLUSTRATED BY
 
 *SET
     NAME1 = VALUE1
     NAME2 = VALUE2
     NAME3 =
             LINE A
             LINE B
 *
     NAME4 = VALUE4
 *ENDSET
 
 THE DISTINGUISHING FEATURE OF THIS FORM IS THAT THERE IS  NO
 NAME FOLLOWING *SET.  THE RESULT OF THIS STATEMENT IS IDENT-
 ICAL TO
 
 *SET ( NAME1 = VALUE1 )
 *SET ( NAME2 = VALUE2 )
 *SET ( NAME3 )
             LINE A
             LINE B
 *ENDSET
 *SET ( NAME4 = VALUE4 )
 
 NOTE THAT THE * ON A LINE BY ITSELF ENDS  A  GROUP  OF  TEXT
 LINES IN A MULTIPLE ASSIGNMENT *SET.
 
 
 
 V.  FURTHER EXAMPLES
 
 
 
 V.A.  AN EXAMPLE WHICH MODIFIES A LINPACK PROGRAM
 
      THE FOLLOWING EXAMPLE ILLUSTRATES HOW THE MACRO PROCES-
 SOR  MAY  BE USED TO GENERATE A PROGRAM SEGMENT.  SOME BACK-
 GROUND INFORMATION IS NEEDED  TO  UNDERSTAND  THIS  EXAMPLE.
 FIRST,   THE   RESULTING   PROGRAM  CALLS  LINPACK  ROUTINES
 [DONGARRA, ET AL, 1979] TO FACTOR AND POSSIBLY SOLVE A  SYS-
 TEM  OF  LINEAR  EQUATIONS.  RECALL THAT THE LINPACK ROUTINE
 SGECO FACTORS A MATRIX AND PRODUCES AN ESTIMATE OF ITS  CON-
 DITION  NUMBER,  SGEFA  ONLY  FACTORS  THE MATRIX, AND SGESL
 TAKES THE FACTORED MATRIX AND SOLVES A LINEAR SYSTEM GIVEN A
 RIGHT SIDE.  THE DOUBLE PRECISION VERSIONS OF THESE ROUTINES
 ARE DGECO, DGEFA, AND DGESL,  RESPECTIVELY.   FINALLY,  THIS
 EXAMPLE  ASSUMES THAT THE TEMPLATE VARIABLES CONDNO, N, SIN-
 GLE, AND SOLVE HAVE ALREADY BEEN SET ELSEWHERE TO  APPROPRI-
 ATE VALUES.
 
 INPUT TEXT:
 
 
 *IF (SINGLE)
       *SET ( DECL = 'REAL' )
       *SET ( PREFIX = 'S' )
 *ELSE
       *SET ( DECL = 'DOUBLE PRECISION' )
       *SET ( PREFIX = 'D' )
 *ENDIF
       $DECL  A($N,$N)
 *IF (CONDNO)
       $DECL  RCOND, WORK($N)
 *ENDIF
 *IF (SOLVE)
       $DECL  B($N)
 *ENDIF
       INTEGER IPVT($N)
       READ(5,*) A
 *IF (CONDNO)
       CALL  $(PREFIX)GECO (A, $N, $N, IPVT, RCOND, WORK)
       WRITE(6,*) RCOND
 *ELSE
       CALL  $(PREFIX)GEFA (A, $N, $N, IPVT, INFO)
 *ENDIF
 *IF (SOLVE)
       READ(5,*) B
       CALL  $(PREFIX)GESL (A, $N, $N, IPVT, B, 0)
       WRITE(6,*) B
 *ENDIF
       STOP
       END
 *END
 
 
 OUTPUT TEXT ASSUMING SINGLE  =  .TRUE.,  CONDNO  =  .FALSE.,
 SOLVE = .TRUE., AND N = 10,
 
 
       REAL  A(10,10)
       REAL  B(10)
       INTEGER  IPVT(10)
       READ(5,*) A
       CALL  SGEFA (A, 10, 10, IPVT, INFO)
       READ(5,*) B
       CALL  SGESL (A, 10, 10, IPVT, B, 0)
       WRITE(6,*) B
       STOP
       END
 
 
 OUTPUT TEXT ASSUMING SINGLE  =  .FALSE.,  CONDNO  =  .TRUE.,
 SOLVE = .FALSE., AND N = 5,
 
 
       DOUBLE PRECISION  A(5,5)
       DOUBLE PRECISION  RCOND, WORK(5)
       INTEGER  IPVT(5)
       READ(5,*) A
       CALL  DGECO (A, 5, 5, IPVT, RCOND, WORK)
       WRITE(6,*) RCOND
       STOP
       END
 
 
 
 
 V.B.  OTHER EXAMPLES WITH THE ALGORITHM DISTRIBUTION.
 
      THE MACRO PROCESSOR ALGORITHM IS DISTRIBUTED WITH  FIVE
 FILES OF TEST CASES.  THE FIRST AND MOST IMPORTANT IS A CASE
 THAT EXHAUSTIVELY TESTS ALL THE FACILITIES OF THE MACRO PRO-
 CESSOR.   THE  OUTPUT  FROM  PROCESSING  THIS  TEXT AS INPUT
 SHOULD BE AS SHOWN IN THE COMMENTS AT THE BEGINNING  OF  THE
 FILE.   INPUT  IS  GIVEN WHICH TESTS THE SIMPLER FEATURES OF
 THE MACOR PROCESSOR.  IF THE OUTPUT FROM THIS DOES NOT MATCH
 THE  OUPUT GIVEN IN THE COMMENT SECTION, THEN THERE IS SOME-
 THING WRONG WITH THE MACRO  PROCESSOR.   IF  THE  OUTPUT  IS
 IDENTICAL,  THEN ONE HAS HIGH CONFIDENCE THAT THE MACRO PRO-
 CESSOR IS WORKING CORRECTLY.  THIS TEST FILE  ALSO  CONTAINS
 INPUT  WHICH  TESTS  THE  MORE COMPLEX FEATURES OF THE MACRO
 PROCESSOR.  THESE TESTS ARE DONE SILENTLY,  AND  ERROR  MES-
 SAGES  ARE PRINTED ONLY IF A TEST FAILS.  ALAS, THIS EXHAUS-
 TIVE TEST IS NOT INFALLIBLE; WE HAVE FOUND ONE BUG (SO  FAR)
 THAT WAS NOT REVEALED BY THIS TEST.
 
      THE SECOND TEST CASE IS A SIMPLE  FORM  LETTER  TO  THE
 AUTHORS  THAT  MAY  BE  USED TO REPORT ANY PROBLEMS WITH THE
 ALGORITHM.  THE THIRD TEST  IS  THE  LINPACK  EXAMPLE  GIVEN
 ABOVE  AND  THE  FOURTH  TEST  IS  THE SET OF ALL THE SIMPLE
 ILLUSTRATIONS GIVEN IN THIS USER'S GUIDE.
 
      THE FINAL TEST CASE IS THE TEMPLATE USED FOR CODE  GEN-
 ERATIONS  IN THE ELLPACK SYSTEM.  THIS IS A COMPLEX APPLICA-
 TION OF THE MACRO PROCESSOR WHICH INVOLVES DOZENS  OF  VARI-
 ABLES,  WHOSE VALUES ARE SET BY THE PARSER FOR ELLPACK.  THE
 MOST  COMPLEX  PART  OF  THE  TEMPLATE  IS   THE   STATEMENT
 *INCLUDE(SRCALLS)  WHICH  BRINGS MOST OF THE EXECUTABLE CODE
 FOR THE RESULTING FORTRAN PROGRAM.  THIS VARIABLE  IS  BUILT
 UP  BY  THE  PARSER  AND HAS CONSIDERABLE DEPTH OF RECURSIVE
 SUBSTITUTION; IT USUALLY CONSISTS OF A HUNDRED OR  SO  LINES
 OF FORTRAN.
 
 
 VI.  PREPARATION OF A TUNED VERSION OF THE MACRO PROCESSOR
 
 
      THE SIMPLE MACRO PROCESSOR MAY BE TUNED BY SETTING  THE
 FOLLOWING  VARIABLES TO APPROPRIATE VALUES AND THEN APPLYING
 THE BASIC PROCESSOR TO THE TEMPLATE FOR THE MACRO PROCESSOR.
 
 CDC     IF .TRUE., A PURDUE CDC COMPATIBLE VERSION  IS  PRO-
         DUCED.
 
 CSTAR1  IF .TRUE., FORTRAN 77 DECLARATIONS OF THE FORM CHAR-
         ACTER*1 ARE USED INSTEAD OF INTEGER DECLARATIONS FOR
         HOLLERITH VARIABLES.
 
 DEBUG   IF .TRUE., MNF TRACE STATEMENTS  WILL  BE  INSERTED.
         THIS SHOULD ONLY BE USED IF CDC = .TRUE.
 
 ICBDIM  THE DIMENSION OF THE ARRAY CBUFFR.   THIS  DIMENSION
         LIMITS THE SIZE OF TEXT THAT THE APPEND, INCLUDE AND
         SET STATEMENTS CAN PROCESS.  THE DEFAULT IS 2000.
 
 ICSDIM  THE DIMENSION OF THE ARRAY  CSTORE.   THE  DIMENSION
         LIMITS THE TOTAL AMOUNT OF INFORMATION IN THE SYMBOL
         TABLE.  THE DEFAULT IS 20000.
 
 IHADIM  THE DIMENSION OF THE ARRAY  IHASH.   THIS  DIMENSION
         LIMITS  THE  NUMBER OF NAMES USED.  THIS SHOULD BE A
         PRIME NUMBER.  THE DEFAULT IS 601.
 
 ISTDIM  THE DIMENSION OF THE ARRAY ISTORE.   THIS  DIMENSION
         LIMITS  THE  NUMBER  OF POINTERS TO THE MAIN STORAGE
         AREA  CSTORE.  SHOULD  BE  LESS  THAN  ICSDIM.   THE
         DEFAULT IS 6000.
 
 NOPACK  IF .TRUE., ALL REFERENCES TO THE  ARRAY  CSTORE  ARE
         DIRECT  (IN-LINE)  INSTEAD  OF  BEING FORCED THROUGH
         SUBROUTINES.
 
 SHORTB  IF .TRUE. AND CDC = .TRUE., SHORT FILE  BUFFERS  ARE
         USED.
 
 STATS   IF .TRUE., MNF TIMING STATEMENTS WILL  BE  INSERTED.
         THIS SHOULD ONLY BE USED IF CDC = .TRUE.
 
 TESTCH  IF .TRUE.,  CHARACTER  TESTING  USED  TO  CHECK  FOR
         ALPHABETIC AND NUMERIC IS PERFORMED USING IN-LINE IF
         STATEMENTS INSTEAD OF  BEING  ISOLATED  IN  SEPARATE
         SUBROUTINES.
 
 UNIX    PRODUCE A UNIX COMPATIBLE VERSION.
 
 
 
 VII.  ERROR MESSAGES
 
 
      EACH ERROR MESSAGE IS PRECEDED BY THE NAME OF THE  SUB-
 ROUTINE IN WHICH IT OCCCURED.
 
 IOREAD - BUFFER SPACE EXCEEDED
      CAUSE: AN INPUT LINE  OR  THE  MULTI-LINE  TEXT  OF  AN
      APPEND,  INCLUDE,  OR SET WAS TOO LONG.  SOLUTION: MAKE
      THE TEXT SHORTER OR RECOMPILE THE PROCESSOR WITH CBUFFR
      DIMENSIONED LARGER.
 
 MMGET1 - STRING TOO LONG FOR CVALUE(*)
      CAUSE: THE BUFFER PASSED TO MMGET1 WAS TOO  SHORT.   IF
      YOU  ARE NOT CALLING SUBROUTINES OF THE PROCESSOR YOUR-
      SELF, THEN THIS ARGUMENT IS PROBABLY THE INTERNAL ARRAY
      CBUFFR.   SOLUTION:  RECOMPILE  THE  PROCESSOR  WITH  A
      LARGER DIMENSION FOR CBUFFR.
 
 MMHASH - HASH TABLE ARRAY IHASH(*) IS FULL
      CAUSE: THE HASH TABLE IHASH HAS BEEN FILLED BECAUSE THE
      MAXIMUM  NUMBER  OF NAMES HAS BEEN EXCEEDED.  SOLUTION:
      RECOMPILE THE PROCESSOR WITH  A  LARGER  DIMENSION  FOR
      IHASH.
 
 MMNEWI - STORAGE ARRAY ISTORE(*) IS FULL
      CAUSE: ALL OF  THE  POINTERS  USED  IN  DYNAMIC  MEMORY
      MANAGEMENT  HAVE  BEEN  ALLOCATED.   THIS MAY BE DUE TO
      MEMORY FRAGMENTATION OR SIMPLY TO  A  LARGE  NUMBER  OF
      MACRO  DEFINITIONS.   SOLUTION: RECOMPILE THE PROCESSOR
      WITH A LARGER DIMENSION FOR ISTORE.
 
 MMPOPC - STRING TOO LONG FOR BUFFER
      CAUSE: THE BUFFER PASSED TO MMPOPC WAS TOO  SHORT.   IF
      YOU  ARE NOT CALLING SUBROUTINES OF THE PROCESSOR YOUR-
      SELF, THEN THIS ARGUMENT IS PROBABLY THE INTERNAL ARRAY
      CBUFFR.   SOLUTION:  RECOMPILE  THE  PROCESSOR  WITH  A
      LARGER DIMENSION FOR CBUFFR.
 
 MMPUT1 - STORAGE ARRAY CSTORE(*) FULL
      CAUSE: THE CHARACTER  STORAGE  ARRAY  CSTORE  HAS  BEEN
      FILLED.   SOLUTION:  RECOMPILE  THE  PROCESSOR  WITH  A
      LARGER DIMENSION FOR CSTORE.
 
 MMRETI - ATTEMPT TO RETURN INVALID POINTER
      CAUSE: SHOULD NOT  OCCUR  UNDER  NORMAL  CIRCUMSTANCES.
      SOLUTION:  REPORT  THE PROBLEM TO THE TOOLPACK GROUP AT
      PURDUE UNIVERSITY.
 
 MPITEM - VARIABLE NOT DEFINED
      CAUSE: A REFERENCE WAS  MADE  TO  AN  UNDEFINED  MACRO.
      SOLUTION:  CHECK TO SEE IF THE VARIABLE NAME IS SPELLED
      PROPERLY AND IF IT IS ACTUALLY DEFINED.
 
 MPLABL - ILLEGAL LABEL VALUE
      CAUSE: THE VARIABLE LABEL WAS ASSIGNED  A  NON-INTEGRAL
      VALUE  OR A VALUE THAT WAS LONGER THAN 5 DIGITS OR NON-
      POSITIVE.  SOLUTION: CORRECT LABEL ASSIGNMENT.
 
 MPMAC  - VARIABLE NOT DEFINED
      CAUSE: A REFERENCE WAS  MADE  TO  AN  UNDEFINED  MACRO.
      SOLUTION:  CHECK TO SEE IF THE VARIABLE NAME IS SPELLED
      PROPERLY AND IF IT IS ACTUALLY DEFINED.
 
 MPPOPN - ILLEGAL VARIABLE NAME
      CAUSE: AN ILLEGAL VARIABLE NAME WAS ENCOUNTERED.  SOLU-
      TION: CHECK TO MAKE SURE THE NAME BEGINS WITH AN ALPHA-
      BETIC CHARACTER AND THAT IT CONTAINS NO SPECIAL CHARAC-
      TERS.
 
 MPPOPN - MISSING RIGHT PARENTHESIS
      CAUSE: UNBALANCED PARENTHESES
      SOLUTION: BALANCE PARENTHESES.
 
 TPAPPE - APPEND HAS NO MATCHING ENDAPP
      CAUSE: A MULTI-LINE APPEND HAS NO CLOSING ENDAPP.  THIS
      IS  ONLY DETECTED WHEN AN END STATEMENT IS ENCOUNTERED,
      SO AT THIS POINT THE APPEND STATEMENT  HAS  GOBBLED  UP
      THE END OF YOUR TEMPLATE.
 
 TPCOMM - COMMENT HAS NO MATCHING ENDCOM
      CAUSE: COMMENT HAS NO CLOSING  ENDCOM.   THIS  IS  ONLY
      DETECTED  WHEN  AN  END STATEMENT IS ENCOUNTERED, SO AT
      THIS POINT THE COMMENT STATEMENT HAS GOBBLED UP THE END
      OF YOUR TEMPLATE.
 
 TPDO   - DO HAS NO MATCHING ENDDO
      CAUSE: A DO STATEMENT IS NOT CLOSED BY AN ENDDO.   THIS
      IS  ONLY DETECTED WHEN AN END STATEMENT IS ENCOUNTERED,
      SO AT THIS POINT THE DO STATEMENT HAS  GOBBLED  UP  THE
      END OF YOUR TEMPLATE.
 
 TPELSE - IF HAS NO MATCHING ENDIF
      CAUSE: AN IF STATEMENT IS NOT CLOSED BY AN ENDIF.  THIS
      IS  ONLY DETECTED WHEN AN END STATEMENT IS ENCOUNTERED,
      SO AT THIS POINT THE IF STATEMENT HAS  GOBBLED  UP  THE
      END OF YOUR TEMPLATE.
 
 TPENDO - MISPLACED ENDDO
      CAUSE: AN ENDDO NOT PRECEDED BY A MATCHING DO HAS  BEEN
      ENCOUNTERED.
 
 TPENDF - MISPLACED ENDIF
      CAUSE: AN ENDIF NOT PRECEDED BY A MATCHING IF HAS  BEEN
      ENCOUNTERED.
 
 TPEVAL - MISPLACED ENDAPP
      CAUSE: AN ENDAPP NOT PRECEDED BY A MATCHING APPEND  HAS
      BEEN ENCOUNTERED.
 
 TPEVAL - MISPLACED ENDCOM
      CAUSE: AN ENDCOM NOT PRECEDED BY A MATCHING COMMENT HAS
      BEEN ENCOUNTERED.
 
 TPEVAL - MISPLACED ENDSET
      CAUSE: AN ENDSET NOT PRECEDED BY  A  MATCHING  SET  HAS
      BEEN ENCOUNTERED.
 
 TPEVAL - ILLEGAL OR MISSPELLED DIRECTIVE
      CAUSE: AN UNKNOWN DIRECTIVE HAS BEEN ENCOUNTERED.
 
 TPIF   - IF HAS NO MATCHING ENDIF
      CAUSE: AN IF  HAS  NO  CLOSING  ENDIF.   THIS  IS  ONLY
      DETECTED  WHEN  AN  END STATEMENT IS ENCOUNTERED, SO AT
      THIS POINT THE IF STATEMENT HAS GOBBLED UP THE  END  OF
      YOUR TEMPLATE.
 
 TPINCL - VARIABLE NOT DEFINED
      CAUSE: A REFERENCE WAS  MADE  TO  AN  UNDEFINED  MACRO.
      SOLUTION:  CHECK TO SEE IF THE VARIABLE NAME IS SPELLED
      PROPERLY AND IF IT IS ACTUALLY DEFINED.
 
 TPOPT  - ILLEGAL OR MISSPELLED OPTION
      CAUSE: AN UNKNOWN OPTION HAS BEEN ENCOUNTERED.
 
 TPOPT  - OPTION REQUIRES SINGLE CHARACTER
      CAUSE: AN INCORRECT  VALUE  HAS  BEEN  SUPPLIED  TO  AN
      OPTION WHICH REQUIRES A SINGLE CHARACTER.
 
 TPOPT  - OPTION REQUIRES AN INTEGER
      CAUSE: AN INCORRECT  VALUE  HAS  BEEN  SUPPLIED  TO  AN
      OPTION WHICH REQUIRES A INTEGER VALUE.
 
 TPOPT  - OPTION REQUIRES A LOGICAL VALUE
      CAUSE: AN INCORRECT  VALUE  HAS  BEEN  SUPPLIED  TO  AN
      OPTION  WHICH  REQUIRES  A  LOGICAL  VALUE OF .TRUE. OR
      .FALSE.
 
 TPSET  - SET HAS NO MATCHING ENDSET
      CAUSE: A MULTI-LINE SET HAS NO CLOSING ENDSET.  THIS IS
      ONLY  DETECTED WHEN AN END STATEMENT IS ENCOUNTERED, SO
      AT THIS POINT THE SET STATEMENT HAS GOBBLED UP THE  END
      OF YOUR TEMPLATE.
 
 TPSYNT - LEFT PARENTHESIS EXPECTED
      CAUSE: A LEFT PARENTHESIS WAS EXPECTED BUT NOT FOUND.
 
 TPSYNT - RIGHT PARENTHESIS EXPECTED
      CAUSE: A RIGHT PARENTHESIS WAS EXPECTED BUT NOT FOUND.
 
 TPSYNT - COMMA EXPECTED
      CAUSE: A COMMA WAS EXPECTED BUT NOT FOUND.
 
 TPSYNT - EQUALS SIGN EXPECTED
      CAUSE: AN EQUALS SIGN WAS EXPECTED BUT NOT FOUND.
 
 TPSYNT - VARIABLE EXPECTED
      CAUSE: A SPECIAL CHARACTER OR CONSTANT WAS  ENCOUNTERED
      WHERE A VARIABLE NAME WAS EXPECTED.
 
 TPSYNT - CONSTANT OR VARIABLE EXPECTED
      CAUSE: A CONSTANT OR VARIABLE NAME WAS EXPECTED BUT NOT
      FOUND.
 
 TPSYNT - ILLEGAL CHARACTERS AT END OF LINE
      CAUSE: EXTRA CHARACTERS WERE FOUND AT THE  END  OF  THE
      INPUT LINE.
 
 
 
 VIII.  REFERENCES
 
 DONGARRA, J.J., J.R. BUNCH,  C.B.  MOLER  AND  G.W.  STEWART
      [1979], LINPACK USER'S GUIDE, SOC. INDUST. APPL. MATH.,
      PHILIDELPHIA, PA.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         JUNE 4, 1984
 
