                          ░░░▒  ░░▒  ░░░░░▒ ░░░░▒
                         ░▒    ░▒ ░▒ ░▒░▒░▒ ░▒ ░▒
                        ░▒     ░▒ ░▒ ░▒░▒░▒ ░░░░▒
                         ░▒    ░▒ ░▒ ░▒  ░▒ ░▒
                          ░░░▒  ░░▒  ░▒  ░▒ ░▒

                                 Compiler

         (E)dit or (C)ompile or (S)how or (P)rint or (M)ap or (D)elete or Esc  E

         (E)dit loads MACRO EDITOR

         (C)ompile COMPILES edited macro

         (S)how lists existing macro code on SCREEN

         (M)ap lists executable macro on PRINTER

         (P)rint lists existing macro code on PRINTER

         (D)elete ERASES executable macro

         Esc EXITS from compiler
         ╔═════════════════════╗
         ║      Macro Editor   ║
         ╚═════════════════════╝


     SAMPLE.COD    Line:1  Column:1  Page:1  :1-120 :1-264
     ===> _<--hit ENTER to move to TEXT body   (enter HELP for help...
          ┌───────────────────────────────────────────────────────────┐-----
     00001│    |key = concat(last,@,first,@,mid)                      │     |
     00004│    |                                                      │     |
     00002│    |hit HOME to return to command line ===>               │     |
     00003│    |then enter RUN to compile macro                       │     |
     00005│    |                                                      │     |
     00006│    |                                                      │     |
     00007│    |                                                      │     |
     00008│    |                                                      │     |
     00009│    |                                                      │     |
     00010│    |                          auto view change at col 73 >│120 >|
     00011│    |                                                      │     |
     00012│    |                                                      │     |
     00013│    |  auto screen and page advance                        │     |
     00014│    |  v                                                   │     |
          └───────────────────────────────────────────────────────────┘-----








            ■  STATEMENT LINE can be free-form

            ■  KEYNAMES and OPERATORS must be separated by at LEAST 1 SPACE

            ■  CHARACTER constants should be enclosed by QUOTES

            ■  CHARACTER constants containing blanks MUST be enclosed by QUOTES

            ■  CODE can be in UPPER, LOWER, or CAPS case








 Operand 1                     Operator   Operand 2

 LINK KEY[DRIVE:FILE]             =       WRITE
 KEY                              <>      KEY[DRIVE:FILE]
 STRING(KEY,POS,LEN)              >       STRING(KEY,POS,LEN)
 STRING(KEY[DRIVE:FILE],POS,LEN)  <=      STRING(KEY[DRIVE:FILE],POS,LEN)
 IF KEY                           >=      NUMERIC VALUE
 ELSE                             <=      'CHARACTER STRING'
 ENDIF                            EQ      BLANK
 ABORT                            NE      LOWER
                                  GT      UPPER
                                  LT      CAPS
                                  GE      LAST(KEY)
                                  LE      CONCAT(KEY,KEY)
                                          PARSE(KEY)
                                          SYSTIME              Operand 3
                                          SYSDATE
                                          SYSDMIL              1-9R
                                          +                    1-9T
                                          -                    AND
                                          *                    OR
                                          /                    THEN


                             Macro Example:

                . . . . IF RECORD STATUS = BLANK THEN
                .        MAX QTY = 0
                .        LINK REC[C:LA] = REC
                .   . . . LA QTY = LA QTY[C:LA]
                .   .     IF LA QTY > MAX QTY THEN
                .   .      MAX QTY = LA QTY
                .   .      LOC = LA
                .   . . . ENDIF
                .        LINK REC[C:KC] = REC
                .         KC QTY = KC QTY[C:KC]
                .   . . . IF KC QTY > MAX QTY THEN
                .   .      MAX QTY = KC QTY
                .   .      LOC = KC
                .   . . . ENDIF
                .        LINK REC[C:NY] = REC
                .         NY QTY = NY QTY[C:NY]
                .   . . . IF NY QTY > MAX QTY THEN
                .   .      MAX QTY = NY QTY
                .   .      LOC = NY
                .   . . . ENDIF
                .        TOT QTY = LA QTY + KC QTY + NY QTY
                . . . . ENDIF



                                  LINK Rules



               Format:     keyname[drive:file] = keyname
                              ^                     ^
                             LINK                ROOT ARG


                           keyname[drive:file] = constant
                              ^                     ^
                             LINK                LINK ARG












                             LINK REC[C:SALE] = REC

                                One to One LINK

                     ┌──────────┐            ┌──────────┐
                     │Rec 1     │<───LINK───>│Rec 1     │
                     └──────────┘            └──────────┘
                     ┌──────────┐            ┌──────────┐
                     │Rec 2     │<───LINK───>│Rec 2     │
                     └──────────┘            └──────────┘
                         ROOT                    LINK













                             LINK REC[C:SALE] = WRITE

                                One to One LINK

                     ┌──────────┐            ┌──────────┐
                     │Rec 1     │<───LINK───>│ Created  │
                     └──────────┘            └──────────┘
                     ┌──────────┐            ┌──────────┐
                     │Rec 2     │<───LINK───>│ Created  │
                     └──────────┘            └──────────┘
                         ROOT                    LINK


           ╔══════════════════════════════════════════════════════╗
           ║  A link to a target data base with a search argument ║
           ║  of 'WRITE' will create an new OUTPUT RECORD         ║
           ╚══════════════════════════════════════════════════════╝







                             LINK EMPL[C:PERS] = EMPL

                                One to One LINK

                     ┌──────────┐            ┌──────────┐
                     │Empl 1    │<─LINK──┐ ┌>│ Empl 2   │
                     └──────────┘       ┌│─┘ └──────────┘
                     ┌──────────┐       ││   ┌──────────┐
                     │Empl 2    │<─LINK─┘└──>│ Empl 1   │
                     └──────────┘            └──────────┘
                         ROOT                    LINK

                the LINK record is LINKed by looking for a match
                based on the ROOT argument.  Either file may be indexed.
                A non-indexed LINK file will be searched sequentially.
                An indexed LINK file will be binary searched








                             LINK REC[C:LETR] = 1

                                One to Many

                     ┌──────────┐            ┌──────────┐
                     │Rec 1     │<───LINK────│Rec 1     │
                     └──────────┘         │  └──────────┘
                     ┌──────────┐         │
                     │Rec 2     │<───LINK─┘
                     └──────────┘
                         ROOT                    LINK


                for each ROOT record, REC 1 is LINKed

                can be used to propagate data from one file to
                many files, for example, copying a form letter
                from one record and merging it with each empl-
                oyee record to create a mail-merged letter





                             LINK REC[C:1988] = 1

                                Many to One

                     ┌──────────┐            ┌──────────┐
                     │Rec 1     │────LINK───>│Rec 1     │
                     └──────────┘         │  └──────────┘
                     ┌──────────┐         │
                     │Rec 2     │────LINK─┘
                     └──────────┘
                         ROOT                    LINK


                REC 1 is updated by each ROOT record

                can be used to accumulate data from many records
                to one record, for example, creating a statistics
                record by accumulating data from each ROOT record







       Compiler automatically prevents EXECUTION of statements UP TO
       the NEXT LINK statement or END OF MACRO if a RECORD LINKED = N
       condition is detected in the ROOT record


        . . LINK ZIP[C:ZIP] = ZIP
        .     CITY = CITY[C:ZIP]
        .     STATE = STATE[C:STATE]
        . . LINK REC[C:LAB] = WRITE
              L1[C:LAB] = CONCAT(CITY,@,STATE)


       if a MATCH ON ZIP is not found, then RECORD LINKED = N and
       the CITY and STATE move statements will NOT be executed,
       however, the remaining code will be EXECUTED





       to PREVENT ALL EXECUTION following the RECORD LINKED = N
       condition, code the following:

            LINK ZIP[C:ZIP] = ZIP
        . . IF RECORD LINKED = Y THEN
        .     CITY = CITY[C:ZIP]
        .     STATE = STATE[C:STATE]
        .   LINK REC[C:LAB] = WRITE
        .     L1[C:LAB] = CONCAT(CITY,@,STATE)
        . . ENDIF

       to CAUSE an IMMEDIATE ABORT following the RECORD LINKED = N
       condition, code the following:

            LINK ZIP[C:ZIP] = ZIP
            IF RECORD LINKED = N THEN
        . . . ABORT
        .     CITY = CITY[C:ZIP]
        .     STATE = STATE[C:STATE]
        .   LINK REC[C:LAB] = WRITE
        .     L1[C:LAB] = CONCAT(CITY,@,STATE)
        .
        v
       EXIT

                           CONSTANT to KEY MOVE

               ■  TARGET field is on left side of '=' OPERATOR

               ■  SOURCE field is on right side of '=' OPERATOR

               ■  TARGET must be a valid KEYNAME

               ■  SOURCE may be a NUMERIC or CHARACTER constant

               ■  CHARACTER constants should be enclosed by QUOTES

               ■  CHARACTER constants longer than TARGET field are TRUNCATED

               ■  CHARACTER data MAY NOT be moved to a NUMERIC field

               ■  NUMERIC constants may contain imbedded decimal point


                  Examples:   NAME = 'BLOW JOE A'
                              RATE = 9.50



                               KEY to KEY MOVE

               ■  TARGET field is on left side of '=' OPERATOR

               ■  SOURCE field is on right side of '=' OPERATOR

               ■  TARGET must be a valid KEYNAME

               ■  SOURCE must be a valid KEYNAME


                  Example:   VALU = SALES











                                 KEY CALCULATION

               ■  TARGET field is on left side of '=' OPERATOR

               ■  SOURCE field(s) on right side of '=' OPERATOR

               ■  TARGET must be a valid KEYNAME

               ■  SOURCE can be a valid KEYNAME or a CONSTANT

               ■  CONSTANTS may be NUMERIC only

               ■  TARGET field may also be a SOURCE field in a
                  calculation    for example:   VALU = VALU + 1

               ■  NUMERIC constants may contain imbedded decimal point

               ■  ALL calculations are based on WHOLE NUMBERS

               ■  TRUNCATION and ROUNDING OPERATORS resolve DECIMAL PLACEMENT

                      R = Round             1-9  Decimal Places
                      T = Truncate          1-9  Decimal Places



                      TOTAL = SALE * 1.06 2R

                      contents of SALE is 1000
                      1000 * 106 equals calculated value: 106000
                      2R rounds 106000 2 decimal places
                      value of 1060 is stored into TOTAL


               ■  SOURCE CALCULATION is from LEFT to RIGHT

                      PROFIT = SALE - COST + EXPENSE

                      would produce INVALID results


                      WORK = COST + EXPENSE
                      PROFIT = SALE - WORK

                      CORRECT technique






                             STRING MOVE


               Format:     STRING(keyname,pos,len)


               ■  STRING field can be TARGET or SOURCE

               ■  POS+LEN longer than TARGET field will be TRUNCATED

               ■  CHARACTER data MAY NOT be moved to a NUMERIC
                  field

                  Examples:   STRING(DATA,2,3) = S3
                              STRING(DATA[B:LINK],2,3) = XXX









                             BLANK MOVE


               Format:     KEY = BLANK


               ■  TARGET can be CHARACTER or NUMERIC field

               ■  causes entire TARGET field to be blanked

                  Examples:   NAME = BLANK
                              VALU = BLANK












                             LOWER TRANSLATE


               Format:     KEY = LOWER


               ■  TARGET can be CHARACTER field only

               ■  causes TARGET field to be translated to LOWERCASE

                  Example:   NAME = LOWER













                             UPPER TRANSLATE


               Format:     KEY = UPPER


               ■  TARGET can be CHARACTER field only

               ■  causes TARGET field to be translated to UPPERCASE

                  Example:   NAME = UPPER













                             CAPS TRANSLATE


               Format:     KEY = CAPS


               ■  TARGET can be CHARACTER field only

               ■  causes FIRST letter of each word in TARGET
                  field to be translated to UPPERCASE and
                  remaining letters to LOWERCASE

                  Example:   NAME = CAPS











                             MOVE LAST


               Format:     KEY = LAST(KEY)


               ■  TARGET can be CHARACTER or NUMERIC field

               ■  moves FIELD of LAST RECORD to TARGET

               ■  can be used in FILE to DUPLICATE common data


                  Example:   NAME = LAST(NAME)










                             CONCAT MOVE


               Format:     KEY = CONCAT(KEY,KEY,KEY)


               ■  TARGET can be CHARACTER field only

               ■  SOURCE is a LIST of 1-7 fields

               ■  SOURCE can be CHARACTER or NUMERIC

               ■  CHARACTER fields are stripped of trailing BLANKS

               ■  NUMERIC fields are stripped of leading ZEROS

               ■  @  (1-9) inserts a BLANK(s) into CONCAT field


                  Example:   NAME = CONCAT(FIRST,@,MIDDLE,@,LAST)




                             PARSE MOVE


               Format:     KEY = PARSE(KEY)


               ■  TARGET can be CHARACTER field only

               ■  SOURCE can be CHARACTER field only

               ■  SOURCE can be CHARACTER or NUMERIC

               ■  FIRST word of SOURCE field is trimmed of leading BLANKS

               ■  FIRST word of SOURCE field is moved to TARGET field

               ■  SOURCE field contains remaining words after PARSE


                  Example:   FIRST = PARSE(NAME)




                             SYSTIME MOVE


               Format:     KEY = SYSTIME


               ■  SYSTIME TARGET should be TYP=C LEN=08

               ■  SYSTIME is in format '10:25 AM'


                  Example:   TIME = SYSTIME












                             SYSDATE MOVE


               Format:     KEY = SYSDATE


               ■  SYSDATE TARGET should be TYP=C LEN=16

               ■  SYSDATE is in format '891228 THURSDAY'


                  Example:   DATE = SYSDATE












                             SYSDMIL MOVE


               Format:     KEY = SYSDMIL


               ■  SYSDMIL TARGET should be TYP=C LEN=21

               ■  SYSDMIL is in format '28 DEC 1989 THURSDAY'


                  Example:   DMIL = SYSDMIL












                             IF STATEMENT


               Format:     IF KEY = argument THEN
                                             AND
                                             OR
               ■  KEY can be STRING key

               ■  KEY can be LINKED or UNLINKED

               ■  argument can be KEY or CONSTANT

               ■  argument KEY can be LINKED or UNLINKED

               ■  IF must be ENDED by ENDIF


                  Examples:   IF REC = 23 THEN
                               A = B
                              ENDIF


                              IF LAST = BLOW AND
                              IF FIRST = JOE THEN
                               A = B
                              ENDIF


                              IF RECIPE = COOKIE OR
                              IF RECIPE = CAKE THEN
                               A = B
                              ELSE
                               A = C
                              ENDIF


                              IF REC = 1 THEN
                                A = B
                              ELSE
                              IF REC = 2 THEN
                                A = C
                              ELSE
                              IF REC = 3 THEN
                                A = D
                              ENDIF
