*DECK SYNGEN
OVERLAY(SYNGEN,0,0) 
 PRGM SYNGEN; 
      BEGIN 
#**********************************************************************#
      ITEM COPYRIGHT C(34) =
          "COPYRIGHT CONTROL DATA SYSTEMS INC.1994";
#**********************************************************************#
      ITEM ABTFLAG B = FALSE;  # TRUE IF *ABORT-ON-ERRORS* PARAMETER   #
                               # WAS SPECIFIED ON CONTROL STATEMENT    #
      XREF
        BEGIN 
          ITEM LFLAG;          #FLAG FOR LISTING OPTION CHOSEN         #
                               #     1 = FULL OUTPUT LISTING REQUESTED.#
                               #     0 = DIAGNOSTICS ONLY.             #
          ITEM TFLAG;          #FLAG FOR CONSTRUCTION OF A TABLE OF    #
                               #TRACING INFORMATION FOR USE IN TRACING #
                               #PATHS THRU SYNTBLE. 1 = TRACEM TABLE IS#
                               #BUILT (DEFAULT CASE). 0 = NOT BUILT.   #
          ITEM REWIND;         #FLAG FOR FILE POSITION OPTION CHOSEN   #
                               #     1 = ALL FILES REWOUND AT END.     #
                               #     0 = NO FILES REWOUND AT END.      #
          ITEM LXREFWS;        #WSA FOR LXREF FILE WRITING.            #
          ITEM DXREFWS;        #WSA FOR DXREF FILE WRITING.            #
          ITEM SXREFWS;        #WSA FOR SXREF FILE WRITING.            #
          PROC SYNOPEN;        #COMPASS RTN WHICH OPENS ALL SYNGEN FILE#
          PROC SYNABT;         #COMPASS RTN WHICH ABORTS JOB AFTER     #
                               #WRITING DAYFILE DIAGNOSTICS.           #
          PROC SYNCOM;         #COMPASS RTN WHICH WRITES PRESET ARRAY  #
                               #RECORDS TO SYNGEN"S OUTPUT FILE.       #
          PROC SYNCOPY;        #COMPASS RTN WHICH COPIES THE SYNTBLE   #
                               #FILE, AND TRACEM FILE IF BUILT, TO THE #
                               #SYNGEN OUTPUT FILE.                    #
          ARRAY SYNIWSA[8];    #WORKING STORAGE FOR SYNGEN"S INPUT FILE#
            ITEM INWORD C(0,0,10);
          ITEM SYNIRL;         #INPUT RECORD LENGTH IN CHARACTERS.     #
          ITEM SYNORL;          #OUTPUT RECORD LENGTH IN CHARACTERS.   #
          ITEM SYNEOF;         #EOF FLAG, 1=EOF.                       #
          ARRAY SYNTWSA[5];    #WSA FOR TRACEM FILE I/O.               #
            ITEM TRACEWSAWD C(0,0,10);
          PROC SYNPRNT;        #COMPASS RTN WHICH WRITES RECORDS ON THE#
                               #SYSTEM OUTPUT FILE.                    #
          PROC SYNREAD;        #COMPASS RTN WHICH READS RECORDS (CARD  #
                               #IMAGES) FROM SYNGEN"S INPUT FILE.      #
          PROC LXREFW;         #COMPASS RTNS TO WRITE AND READ THE     #
          PROC LXREFR;         #LABEL CROSS REFERENCE FILE, THE DIAG-  #
          PROC DXREFW;         #NOSTIC CROSS REFERENCE FILE AND THE    #
          PROC DXREFR;         #SUBROUTINE CROSS REFERENCE FILE,       #
          PROC SXREFW;         #RESPECTIVELY.                          #
          PROC SXREFR;
          PROC TRACEW;         #COMPASS RTN WHICH WRITES ON THE TRACEM #
                               #FILE.                                  #
          PROC SYNCLSE;        #COMPASS RTN WHICH CLOSES ALL FILES AND #
                               #WRITES OUT THE PRESET ARRAYS BUILT BY  #
                               #SYNGEN.                                #
        END 
      XDEF PROC SYNTBLR;
      XDEF ITEM HDRDATE C(10);
      XDEF ITEM HDRTIME C(10);
      XREF PROC SYNTIDA;
      XREF ITEM OUTLEN;      #  RECORD LENGTH FOR COMPILE FILE  # 
      XREF ITEM REALEOF;
      STATUS CHARTYPE ALPHABETIC, NUMERIC, DELIMITER; 
      DEF SCALL # #;               # FOR READABILITY OF PROC CALLS     #
      ITEM TYPE;                   # TYPE OF CHARACTER FROM -GETCHAR-  #
      ARRAY AINCHAR[0];            # HOLDS CHARACTER FROM -GETCHAR-    #
        BEGIN 
        ITEM INCHARC C(0,54,1);    # FOR CHARACTER USAGE               #
        ITEM INCHARI U(0,54,6);    # FOR NUMBER USAGE                  #
        END 
      ITEM FC;                     # FROM CHAR IN -INWORD- #
      ITEM FW;                     # FROM WORD IN QUIWSA ARRAY #
      ITEM TOPENTRY;               # TOP ENTRY IN THE SKIPTBL # 
      XREF ITEM DIRFLAG;           # FLAG FOR A SKIP DIRECTIVE. 1 A # 
                                   # DIRECTIVE, 0- NOT A DIRECTIVE #
      XREF ITEM SKIPFLG;           # FLAG FOR SKIPPING.  1- SKIP,   # 
                                   # 0- NOSKIP, -1 - A TRUE IFEQ #
      XREF PROC ENDINP; 
      ARRAY HASHEDTABLE[127];  #TABLE OF POINTERS TO DATA ACCESSED VIA #
        ITEM HASHENTRY = [128(0)];#HASHED CODES.                       #
      BASED ARRAY SYMBOLTABLE; #ARRAY FOR ACCESSING SYMBOL TABLE       #
        BEGIN                  #ENTRIES.                               #
          ITEM SNAME C(1,0,10);#WORD OF SYMBOL NAME.                   #
          ITEM SDEFINEBIT B(0,0,1);#TRUE IF DEFINED, FALSE OTHERWISE.  #
          ITEM SLENGTH I(0,6,6);#LENGTH OF SYMBOL IN WORDS.            #
          ITEM STYPE I(0,12,6); #TYPE OF SYMBOL (LABEL, ROUTINE, ETC.) #
          ITEM NEXTPTR I(0,24,18);#PTR TO NEXT ENTRY IN A CHAIN.       #
          ITEM SVALUE I(0,42,18);#VALUE OF THE SYMBOL.                 #
        END 
      BASED ARRAY SYMBOLTABLE2;#ARRAY FOR ACCESSING A 2ND SYMBOL TABLE #
        BEGIN                  #ENTRY SIMULTANEOUSLY.                  #
          ITEM SNAME2 C(1,0,10);
          ITEM SLENGTH2 I(0,6,6); 
        END 
      BASED ARRAY SORT;        #USED FOR SORTING THE CROSS REFERENCES. #
        ITEM SORTWORD;
      BASED ARRAY SYNTBLE;   #  USED FOR THE -SYNTBLE- -FILE-  #
        ITEM SYNTBLEWD; 
      ARRAY [1];               #RESULT OF BINARY NUMBER CONVERTED TO   #
        ITEM OCTAL;            #DISPLAY-CODED OCTAL.                   #
      ARRAY [3];               #HOLDS SYMBOL TO BE INSERTED IN SYMBOL  #
                               # TABLE OR EXTRACTED FROM IT.           #
        ITEM NAME C(0,0,10);   #NAME OF SYMBOL .                       #
      ARRAY SCRATCH[13];       #SCRATCH STORAGE FOR I/O RECORDS.       #
        ITEM SCRATCHWD C(0,0,10); 
      BASED ARRAY RA;          #ARRAY FOR EXAMINING THE SYSTEMS COMMUN-#
        BEGIN                  #ICATION AREA                           #
          ITEM CCPARAM C(0,0,1);#ACCESSES 1ST CHAR OF CONTROL CARD PARS#
          ITEM NEXTAVAIL I(0,42,18);#ACCESSES NEXT AVAILABLE WORD IN FL#
          ITEM NRCCPARAMS I(0,42,18);#COUNT OF PARAMS ON CONTROL CARD. #
      ITEM FULLWORD I(0,0,60);
          ITEM CCFILENAME  I(,,42);#ACCESSES LFN CONTROL CARD PARAMS.  #
        END 
      BASED ARRAY LABELPTRS;   #ARRAY OF POINTERS TO LABELLED SECTIONS #
        ITEM LABELPTR;         #OF THE SYNTABLE. AS EACH LABEL IS DE-  #
                               #FINED AN ENTRY IN THIS TABLE IS ASSIGN-#
                               #ED TO IT AND A POINTER VALUE STORED IN #
                               #THE ASSIGNED ENTRY.                    #
      BASED ARRAY SUBLABELPTRS[99];#POINTERS TO SUBLABEL SECTIONS      #
        ITEM SUBLABELPTR (,,60);#WITHIN EACH LABELLED SECTION. RE-     #
                               #INITIALIZED FOR EACH LABELLED SECTION. #
                               #POINTER VALUE IS NEG IF SUBLABEL IS UN-#
                               #DEFINED, POS IF DEFINED. ARRAY IS IN-  #
                               #DEXED BY SUBLABEL NUMBER.              #
      ARRAY DUPELABELMSG[7];
        ITEM DUPELABEL C(0,0,10) = [" ******** ","          ",
                                    "          ","          ",
                                    "    DOUBLY","-DEFINED, ",
                                    "LATEST OVE","RRIDES.   "]; 
      ARRAY UNDEFMESSAGE[6];
        ITEM UNDEFMESS C(0,0,10) = [" ******** ","          ",
                                    "          ","          ",
                                    "    UNDEFI","NED       ",
                                    "          "];
      ARRAY [2];               #DISPLAY-CODED LABEL OF SYNTBLE SECTION #
        ITEM CURRENTLABEL C(,,10); #CURRENTLY BEING BUILT.             #
      ARRAY BADDIGITMSG[4]; 
        ITEM BADDIGIT C(0,0,10) = [" ******** ","          ", 
                                   "IS NOT A V","ALID INTEG", 
                                   "ER.       "]; 
      ARRAY LEXSEQ[6];
        ITEM LSWORD C(0,0,10) = [" ******** ","KEYWORD OU", 
                                 "T OF SEQUE","NCE  -    ", 
                                 3("          ")];
      ARRAY BADOCTALMSG2[4];
        ITEM BADOCT2 C(0,0,10) = [" ******** ","PRECEDING ",
                                  "CARD CONTA","INS BAD OC",
                                  "TAL DIGIT."];
      ARRAY LABELCOMMENT[5];   #COMMENT FOR LABEL IN SYNTBLE PRESET.   #
        ITEM LABELCOMWORD C(,,10) = [" # :      ",4("          "),
                                     " #        "]; 
      ARRAY INSTRCOMMENT[5];   #COMMENT FOR WORD OF CODE IN SYNTBLE.   #
        ITEM INSTRUCTCOM C(,,10) = [" #        ",4("          "), 
                                    " #        "];
      ARRAY PRESETCODE[5];     #FORMAT FOR PRESET LINE OF SYNTBLE CODE.#
        BEGIN 
          ITEM PRESET C(,,10) = ["       O"" ",4("          "), 
                                 """,        "];
          ITEM PRESETI;        #REDEFINITION OF WORD USAGE.            #
        END 
      BASED ARRAY LABELENTRY;  #FORMATS AN ENTRY IN THE LBLPTRS PRESET #
        BEGIN                  #ARRAY                                  #
          ITEM LABELNAME C(0,0,10);   #NAME OF LABEL.                  #
          ITEM LABELPRESET C(5,0,10); #DECIMAL PTR TO SYNTBLE SECTION. #
        END 
      ARRAY PROCNAME[5];
        ITEM PNAME C(,,10) = ["  PROC SYN","TAXTABLE; ",4(" ")];
      ARRAY LABELPTRHEDR[5];   #HEADER RECORD FOR LBLPTRS PRESET ARRAY.#
        ITEM LABELPTRHDR C(0,0,10) = [" ARRAY LBL","PTRS     [",
                                      "     ];   ",3("          ")];
      ARRAY LABELPTRITEM[5];   #ITEM DEF RECORD FOR LBLPTRS ARRAY PRE- #
        ITEM LBLPTRITEM C(0,0,10) = ["   ITEM LB","LPTR U = [", #SET.  #
                                    4("          ")]; 
      ARRAY LABELPTRTAIL[5];   #RECORD FOR TERMINATION OF LBLPTRS PRE- #
        ITEM LBLPTRTAIL C(0,0,10) = [5("          "),"      ];  "];#SET#
      ARRAY TRACEMTAIL[5];     #TAILEND RECORD FOR TRACEM PRESET.      #
        ITEM TRACEMTAILWD C(0,0,10) = [5("          "),"      ];  "]; 
      ARRAY TRACEMHDR[5];      #1ST RECORD FOR TRACEM ARRAY PRESET.    #
        ITEM TRACEMHDRWD C(0,0,10) = [" ARRAY TRA","CEM [     ",
                                      "];        ",3("          ")];
      ARRAY SKIPLINE[5];
        ITEM SKIP C(,,10) = [6("          ")];
      ARRAY DXREFHEADER2[3];
        ITEM DXREFHDR2 C(,,10) = [" DIAGNOSTI","C         ",
                                    "REFERENCED"," AT       "]; 
      ARRAY LXREFHEADER2[5];
        ITEM LXREFHDR2 C(0,0,10) = [" LABEL    ","          ",
                                    "          ","          ",
                                    "REFERENCED"," BY       "]; 
      ARRAY SXREFHEADER2[5];
        ITEM SXREFHDR2 C(0,0,10) = [" SUBROUTIN","E    SWITC",
                                    "H POSITION","          ",
                                    "REFERENCED"," BY       "]; 
      ARRAY SXREFHEADER3[3];
        ITEM SXREFHDR3 C(0,0,10) = ["          ","     BASE ",
                                    "10   BASE ","8         "]; 
      BASED ARRAY LEXICON [0];         #                               #
        BEGIN                          #                               #
          ITEM LEXWRD     C(0,00,10);  # KEYWORD (MAX LENGTH IS 30 CHR)#
          ITEM LEXID      I(0,00,15);  # UNIQUE OCTAL VALUE ASSOCIATED #
                                       # WITH THE KEY WORD.            #
          ITEM LEX1PARAM  I(0,15,15);  # PARAMETER VALUE TO BE ASSOCIAT#
          ITEM LEX2PARAM  I(0,30,15);  # ED WITH THE KEY WORD          #
          ITEM LEXSYNSECT I(0,45,15);  # CONTAINS KEYWORD = LABEL FLAG.#
                                       # IF A KEYWORD IS THE SAME AS A #
                                       # LABEL, THE ADDRESS OF THE     #
                                       # LABEL IN SYNTABLE WILL OVERLAY#
                                       # THE FLAG IN LEXSYNSECT.       #
        END 
      BASED ARRAY SYN1SCRATCH [0];     # BASED ARRAY POINTING TO ONE   #
        ITEM KEY1WRD C(0,00,10);       # WORD KEYWORDS.                #
      BASED ARRAY SYN2SCRATCH [0];     # BASED ARRAY POINTING TO TWO   #
        ITEM KEY2WRD C(0,00,10);       # WORD KEYWORDS.                #
      BASED ARRAY SYN3SCRATCH [0];     # BASED ARRAY POINTING TO THREE #
        ITEM KEY3WRD C(0,00,10);       # WORD KEYWORDS.                #
      ARRAY LOCWORDS [26];
        ITEM LOCWRD I(0,0,60) = [27(0)];
      ARRAY KEYWRDHDR [5]; # HEADER FOR LEXWORDS PRESET ARRAY.         #
        ITEM KEYHDR C(0,0,10) = [" ARRAY LEX","WORDS    [", 
                                "     ];   ",3("          ")];
      ARRAY KEYWRDITEM [5]; # ITEM DEF FOR LEXWORDS PRESET ARRAY.      #
        ITEM KEYITEM C(0,0,10) = ["   ITEM LE","XWRD U = [",
                                 4("          ")];
      ARRAY KEYWRDTERM [5]; # TERM FOR LEXWORDS PRESET ARRAY.          #
        ITEM KEYTERM C(0,0,10) = [5("          "),"     ];   "];
      ARRAY KEYWRDLINE [5]; # KEYWRD ENTRY IN LEXWORDS PRESET ARRAY.   #
        ITEM KEYLINE C(0,0,10) = ["        O""",2("          "),
                                """,      # ","          ", 
                                 " #        "]; 
      ARRAY LEXICONHDR [5]; # HEADER FOR THE LEXICON PRESET ARRAY.     #
        ITEM LEXHDR C(,,10) = [" ARRAY LEX","ICON [26];","          ",
                                3("          ")]; 
      ARRAY LEXICONITEM [5]; # ITEM DEF FOR THE LEXICON PRESET ARRAY.  #
        ITEM LEXITEM C(0,0,10) = ["   ITEM LE","X  U = [  ",
                                 4("          ")];
      ARRAY LEXICONTERM [5]; # TERM FOR THE LEXICON PRESET ARRAY.      #
        ITEM LEXTERM C(0,0,10) = [5("          "),"       ];  "]; 
      ARRAY LEXICONLINE [5]; # ENTRY IN THE LEXICON PRESET ARRAY.      #
        ITEM LEXLINE C(0,0,10) = ["        O""",2("          "),
                                """,        ",2("          ")]; 
      ITEM NUMBER1WRD;
      ITEM NUMBER2WRD;
      ITEM NUMBER3WRD;
      ITEM KEYFIRSTCHAR;
      ITEM MAXKEYWRDS;
      ITEM KEY1PTR = 0;                # INDEX TO   ONE WORD KEYWORDS. #
      ITEM KEY2PTR = 0;                # INDEX TO   TWO WORD KEYWORDS. #
      ITEM KEY3PTR = 0;                # INDEX TO   THREE WORD KEYWORDS#
      ITEM LEXPTR;                     # INDEX TO LEXID,LEX1PARAM,     #
                                       #          LEX2PARAM, LEXSYNSECT#
      ITEM ENTRIES;                    # COUNTER CONTAINING THE NUMBER #
                                       # OF ENTRIES BASED ON THE FIRST #
                                       # CHARACTER.                    #
      ITEM FIRSTCHAR;                  # CONTAIN THE DISPLAY CODE VALUE#
                                       # 01 THRU 32. COMPARED AGAINST  #
                                       # THE FIRST CHARACTER OF THE KEY#
                                       # WORD TO DETERMINE THE NUMBER  #
                                       # OF ENTRIES.                   #
      ITEM WRDLOCPTR;                  # INDEX INTO THE LEXWORDLOC     #
                                       # TABLE.                        #
      ITEM TOTALWORDS;                 # COUNT OF TOTAL NUMBER OF WORDS#
                                       # PROCESSED IN LEXWORDS.        #
      ITEM NUMBER1KEY;                 # TOTAL NUMBER OF 1 WORD KEYWRDS#
      ITEM NUMBER2KEY;                 # TOTAL NUMBER OF 2 WORD KEYWRDS#
      ITEM NUMBER3KEY;                 # TOTAL NUMBER OF 3 WORD KEYWRDS#
                                       #                               #
                                       #                               #
                                       #                               #
                                       #                               #
                                       #                               #
      ARRAY SYNCHARS[72];              # CONTAINS SYNTAX SPECIFICATIONS#
        ITEM CHAR C(0,0,10);           # INPUT TO SYNGEN. 1 CHAR PER   #
                                       # WORD.                         #
      BASED ARRAY STATETRANS [15,12]; 
        ITEM SWITCHVALUE I(0,0);
      ARRAY STATTRNS [207]; 
        ITEM SWTHVAL I(0,0,60) = [1,15(0),
                                  2,3,3(0),42,0,7(28),31,0, 
                                  32,6,7,8,11,12,15,16,19,2(29),24, 
                                         2(29),31,0,
                                  33,9,10,0,30,2(0),7(30),31,0, 
                                  34,13,14,13(30),
                                  39,40,41,4(0),7(30),2(0), 
                                  35,17,18,4(0),7(29),31,0, 
                                  36,4,5,2(0),43,0,8(30),0, 
                                  36,4,5,2(0),43,0,3(29),21,4(29),0,
                                  37,22,23,4(0),8(29),0,
                                  36,4,5,2(0),43,0,5(29),25,2(29),0,
                                  38,26,27,2(0),43,0,8(29),0, 
                                  36,4,5,2(0),43,0,2(29),20,5(29),0]; 
      STATUS SCHAR COLN,COMA,SLSH,ASK, # MUST CORRESPOND TO THE STATUS #
                   DSGN,MINUS,PLUS,D,  # ENTRIES IN THE STATE TRANSIT- #
                   Y,E,S,N,O,LETTER,   # ION TABLE.                    #
                   DIGIT,SPC;          #                               #
      ARRAY STATUSLIST[72];            #CONTAINS THE LEXICAL STATUS OF #
        ITEM STATLIST S:SCHAR (0,0,60) # CORRESPONDING ENTRY IN THE    #
                   = [72(S"COMA")];    # SYNCHARS ARRAY.               #
      ARRAY DREQ[41] S(1);             # DRIVER REQUESTS AND THEIR     #003860
        BEGIN                          # OPERAND VALUES.               #
          ITEM SYNR C(,,10) = ["SUBS",,"KEY",,"NAME",,"LIT",,"NUM",,
                               "INT",,"FLT",,"FIX",,"SNW",,"SNC",,
                               "FNAME",,"SNS",,"EOS",,                  003880
                             "SPREC",,"DPREC",,"CHARLIT",,"CHRMSK",,
                               "OCTAL",,"CMPLX",,"EOT",,"EOF"]; 
          ITEM REQSTRUCTION I(1,0,60) = [  3 ,,#  +SUBS         # 
                                         100 ,,#  +KEY          # 
                                         101 ,,#  +NAME         # 
                                         102 ,,#  +LIT          # 
                                         105 ,,#  +NUM          # 
                                         107 ,,#  +INT          # 
                                         110 ,,#  +FLT          # 
                                         108 ,,#  +FIX          # 
                                          13 ,,#  +SNW          # 
                                          14 ,,#  +SNC          # 
                                          99 ,,#  +FNAME        #       003900
                                          15 ,,#  +SNS          #       003910
                                          10 ,,#  +EOS          #       003920
                                         111 ,,#  +SPREC        # 
                                         112 ,,#  +DPREC        # 
                                         103 ,,#  +CHARLIT      # 
                                         104 ,,#  +CHRMSK       # 
                                         106 ,,#  +OCTAL        # 
                                         109 ,,#  +CMPLX        # 
                                          12 ,,#  +EOT          # 
                                          11   #  +EOF          #]; 
        END 
      ARRAY USTATE [7]; 
        ITEM US C(0,0,10) = [" ******** ","UNRECOGNIZ","ABLE STATE",
                             "MENT------",,,,]; 
      ARRAY UKEY[7];
        ITEM UK C(0,0,10) = [" ******** ","UNDEFINED ","KEYWORD IG",
                             "NORED --- ",,,,]; 
      ARRAY UACT[7];
        ITEM UA C(0,0,10) = [" ******** ","UNRECOGNIZ","ABLE ACTIO",
                             "N IGNORED-",,,,]; 
      ARRAY NOSYNSECT[6]; 
        ITEM NOSYNS C(,,10) = [" ******** ","PRECEDING ","KEYWORD HA",
                               "S NO CORRE","SPONDING S","YNTAX SECT",
                               "ION       "]; 
      BASED ARRAY SERR [0]; 
        ITEM SYNERROR C(0,0,10);
      ARRAY HEADERLINE[0] S(13);
        BEGIN 
          ITEM HDREJECT C(0,0,10) = ["1 "]; 
          ITEM HDRPROC C(1,0,10); 
          ITEM HDRPROC1 C(2,0,10) = [" "];
          ITEM HDRTITLE C(3,0,40);
          ITEM HDRSYNGEN C(7,0,20) = ["SYNGEN "]; 
          ITEM HDRDATE1 C(9,0,10);
          ITEM HDRTIME1 C(10,0,10); 
          ITEM HDRPAGE C(11,0,10) = ["  PAGE    "]; 
          ITEM HDRPAGENO C(12,0,5); 
        END 
      ITEM                             #                               #
        BP = 0,                        # CONTAINS THE BIT POSITION OF  #
                                       # CURRENT CHARACTER.            #
        WRDPTR,                        # POINTER TO THE WORD THAT CONT-#
                                       # AINS THE CURRENT CHARACTER.   #
        CHRPTR = 73,                   # INDEX INTO THE SYNCHARS AND   #
                                       # STATUSLIST ARRAYS.            #
        LASTCHAR = 72,                 # PTR TO THE ENTRY IN SYNCHARS  #
                                       # CONTAINING THE LAST SOURCE    #
                                       # CHAR IN AN INPUT RECORD.      #
        CHARIND ,                      # CONTAINS CHARACTER OR NUMERIC #
                                       # INDICATOR.                    #
        STATE = 0;                     # CONTAINS SUBSCRIPT INTO THE   #
                                       # STATE TRANSITION TABLE.       #
      STATUS SFLAG INSERT, EXTRACT;#STATUS LIST FOR INS$EXT.           #
      ITEM
           COUNTER = 0,        #SCRATCH VARIABLE USED IN COUNTING.     #
           CTEMP C(10),        #SCRATCH STORAGE - CHARACTERS.          #
           CURNTLABLPTR,       #PTR TO ENTRY IN SYMBOL TABLE FOR LABEL #
                               #OF SYNTBLE SECTION CURRENTLY BEING BILT#
           CURNTSUBLABL C(2),  #DISPLAY-CODED NAME OF CURRENT SUBSEC-  #
                               #TION BEING BUILT.                   .  #
           FIRSTSUBLABL,       #FLAG INDICATING WHETHER FIRST SUBLABEL #
                               #IN THE SECTION HAS BEEN FOUND.         #
           DISPLAYINSTR C(7),  #DISPLAY-CODED INSTRUCTION (\ 7 CHARS.) #
           ERRORCOUNT = 0,     #TALLY OF ERRORS IN CURRENT COMPILATION.#
           ERRORFLAG,          #FLAG FOR ERROR OCCURRENCE, 0=NO ERROR. #
           I,                  #TEMPORARY SCRATCH VARIABLE.            #
           INS$EXT S:SFLAG =   #FLAG FOR SYNHASH ROUTINE INDICATING    #
                     S"INSERT",#WHETHER A SYMBOL IS TO BE INSERTED OR  #
                               #EXTRACTED FROM THE SYMBOL TABLE.       #
           J,                  #TEMPORARY SCRATCH VARIABLE.            #
           K,L,M,N,ITEMP,      #SCRATCH VARIABLES.                     #
           P,                  #  INDEX FOR SYNTBLR AND W  #
           LABELCOUNTER = 0,   #INDEX INTO THE LABELPTRS ARRAY TO THE  #
                               #LAST SYMBOL WHICH HAS BEEN DEFINED.    #
           LASTAVAIL,          #PTR TO LAST UNALLOCATED WORD IN JOB"S  #
                               #FIELDLENGTH.                           #
           LASTRANSFER,        #PTR TO LAST PREVIOUS TRANSFER POINT IN #
                               #THE SYNTBLE.                           #
           RTEMP R,            #SCRATCH STORAGE - REAL VALUES.         #
           SECTIONWORD = 0,    #NR OF CURRENT WORD OF SYNTBLE INSTRUC- #
                               #TIONS RELATIVE TO 1ST WORD OF LABELLED #
                               #SECTION.                               #
           SUBLABEL,           #BINARY VALUE OF SUBLABEL INTEGER.      #
           SYMBOLTYPE = O"23", #TYPE OF SYMBOL IN "NAME". (PRESET FOR  #
                               #SUBRBUILD ROUTINE).                    #
           SYMBOLLENGTH = 2,   #LENGTH OF SYMBOL IN "NAME" IN WORDS.   #
                               #(PRESET FOR SUBRBUILD ROUTINE).        #
           SYMBOLVALUE,        #VALUE OF SYMBOL IN "NAME".             #
           SYNSTRUCTION,       #ENCODED SYNTBLE INSTRUCTION.           #
           SYNTBLEPARCL = 0,   #NR OF NEXT PARCEL TO BE BUILT.         #
           SYNTBLEWORD,        #TALLY OF WORDS IN THE SYNTBLE FILE.    #
           TRACESKEL C(10) =   #SKELETON FOR AN ENTRY IN THE PRESET    #
               """       "",", #TRACEM ARRAY.                          #
           UNDEFSYMBOLS = 0;   #TALLY OF UNDEFINED SYMBOLS IN SYMBOL   #
                               #TABLE.                                 #
      ITEM OLDFL; 
      ITEM OLDLA; 
      ITEM OLD65; 
      ITEM PTC B; 
      ITEM FL I=0;             # MAX FL FOR RUN. DISPLAYED AT END.     #
      ITEM ERRORS I=0;         # TOTAL ERRORS FOR RUN. DISPLAYED AT END#
      ITEM WORD1 = 0;          #STARTING WORD IN SOURCE FOR KEYWORDS   #
                               #AND SUBROUTINE NAMES - EITHER CARD COL #
                               #1 OR 11.                               #
      ITEM SYNORL1;            #NO OF CHAR FOR PRINTER TO PRINT        #
      ITEM LINENO;             #LINE NUMBER OF LINE JUST PRINTED       #
      ITEM PAGENO;             #PAGE NUMBER OF LINE JUST PRINTED       #
      ITEM SORTFL;             #FL AVAILABLE FOR SORTING               #
      DEF LINELIMIT #55#;      #NO OF LINES PER PAGE                   #
      DEF INFILE #B<0,60>INWORD[0]#;#LFN OF SYNGEN"S INPUT. DEFAULT IS #
                               #THE SYSTEM INPUT FILE.                 #
      DEF OUTFILE #B<0,60>INWORD[1]#;#LFN OF THE OUTPUT FILE FOR THE   #
                               #ARRAY PRESETS BUILT BY SYNGEN. DEFAULT #
                               #IS "COMPILE".                          #
        DEF LSTFILE #B<0,60>INWORD[2]#; # LFN FOR THE LISTINGS OF INPUT#
                               # CROSS REFERENCES,ETC. DEFAULT IS      #
                               # OUTPUT.                               #
      DEF LXREFWSA #LXREFWS#;  #WSA FOR WRITING ON LXREF FILE.         #
      DEF DXREFWSA #DXREFWS#;  #WSA FOR WRITING ON DXREF FILE.         #
      DEF SXREFWSA #SXREFWS#;  #WSA FOR WRITING ON SXREF FILE.         #
      CONTROL EJECT;
      PROC GETCHAR; 
#**********************************************************************#
#                                                                      #
#                            GETCHAR                                   #
#                                                                      #
#**********************************************************************#
# GETS THE NEXT CHARACTER FROM -SYNIWSA-. THE CHARACTER IS SCREENED FOR#
# ITS TYPE AND -TYPE- IS SET TO THE APPROPRIATE STATUS CONSTANT. THE   #
# CHARACTER IS STORED IN -AINCHAR-, WHICH HAS ITEMS OF -INCHARI- AND   #
# -INCHARC-. ALSO ADVANCES -FC- AND -FW- AS NECESSARY TO INDICATE WHICH#
# CHARACTER HAS BEEN SELECTED FROM -SYNIWSA-.                          #
#**********************************************************************#
      BEGIN 
      IF FC LS 9 THEN              # STILL MORE  CHARS IN THIS WORD    #
        FC = FC + 1;               # WE USE THE NEXT CHARACTER         #
      ELSE
        BEGIN                      # START WITH THE NEXT WORD          #
        FC = 0;                    #  FIRST CHAR POSITION IN NEW WORD  #
        FW = FW + 1;               # NEXT  WORD                        #
        END 
      INCHARI[0] = B<FC*6, 6>INWORD[FW];  # AVOID THE CHARACTER BEAD   #
      I = INCHARI[0];              # TEMPORARY STORAGE OF CHARACTER    #
      TYPE = CHARTYPE"DELIMITER";  # ASSUME CHARACTER TYPE IS DELIMITER#
      IF I EQ O"53" THEN           # CHARACTER IS A $                  #
        TYPE = CHARTYPE"ALPHABETIC"; #  $ IS A LEGAL CHARACTER         #
      ELSE
        IF I LQ O"44" THEN         # NINE OR  UNDER                    #
          IF I GQ O"33" THEN       # IN ZERO TO NINE RANGE             #
            TYPE = CHARTYPE"NUMERIC"; 
          ELSE
            IF I EQ 0 THEN         # -A- IS LOWEST LEGAL CHAR          #
              TYPE = CHARTYPE"DELIMITER"; 
            ELSE                   # IN NORMAL A-Z RANGE               #
              TYPE = CHARTYPE"ALPHABETIC";
      RETURN; 
      END 
      CONTROL EJECT;
      PROC CHKERRCNT; 
#**********************************************************************#
#                                                                      #
#                              CHKERRCNT                               #
#                                                                      #
#ROUTINE THAT UPDATES THE ERROR COUNT AND ABORTS THE COMPILATION IF    #
#THE ERROR COUNT EXCEEDES THE LIMIT OF 100 ERRORS.                     #
#                                                                      #
      BEGIN 
      DEF ERRLIMIT #100#;          # ERROR LIMIT #
      ERRORCOUNT = ERRORCOUNT + 1; # UPDATE ERROR COUNT # 
      IF ERRORCOUNT GQ ERRLIMIT THEN
        SYNABT(3);                 # ERROR LIMIT EXCEEDED, ABORT       #
                                   # COMPILATION.                      #
      RETURN; 
      END 
      CONTROL EJECT;
      XDEF PROC CHKSKIP;
      PROC CHKSKIP; 
#**********************************************************************#
#                                                                      #
#                            CHKSKIP                                   #
#                                                                      #
#ROUTINE WHICH CONSTRUCTS AND MAINTAINS A TABLE OF DEFINED NAMES AND   #
#VALUES. IT PERFORMS INSERTS, VALUE ASSIGNMENTS, AND CHECKS VALUES     #
#DEPENDING ON ITS DIRECTIVES..... IFEQ, DEF, ENDIF.                    #
#ALSO HANDLES A DIRECTIVE TO FORCE A NEW PAGE ON THE LISTING.... EJECT #
#                                                                      #
#ALL DIRECTIVES MUST START IN THE VERY FIRST CHARACTER POSITION OF THE #
#INPUT RECORD, AND MUST HAVE A SPACE FOLLOWING THE DIRECTIVE VERB.     #
#THE FOLLOWING SYNTAX DESCRIPTION APPLIES TO *EJECT* AND ALL NEW       #
#COMPILER DIRECTIVES. EVENTUALLY, IT SHOULD BE THE STANDARD...         #
#ALL COMPILER DIRECTIVES MUST BE IMMEDIATELY PRECEDED BY, AND FOLLOWED #
#BY A SYMPL COMMENT DELIMITER. IN THIS WAY, UNRECOGNIZED COMMANDS CAN  #
#CAN BE TREATED AS COMMENTS. THE STARTING DELIMITER MUST APPEAR IN THE #
#FIRST CHARACTER POSITION OF THE INPUT RECORD, WITH THE COMMAND VERB   #
#STARTING IN THE SECOND CHARACTER POSITION.                            #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  A NEW RECORD IN SYNIWSA                                             #
#                                                                      #
#EXTERNAL REFERENCES:                                                  #
#  SYNIWSA - INPUT WORKING STORAGE AREA                                #
#  SKIPFLG - FLAG FOR CONDITIONAL SKIPPING                             #
#  DIRFLAG - FLAG FOR COND. SKIP. DIRECTIVE ON INPUT                   #
#  SKIPCNT - INCREMENTED FOR AN IFEQ, DECREMENTED FOR AN ENDIF         #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#                                                                      #
#    FLAGS, DIRFLAG AND SKIPFLG, WILL BE SET BY CHKSKIP TO INDICATE    #
#    WHETHER OR NOT THE INPUT LINE IS TO BE PROCESSED BY THE COMPILER. #
#    SYNREAD PERFORMS SPECIAL PROCESSING FOR THE FLAG VALUES:          #
#                                                                      #
#       DIRFLAG = 1,  THE INPUT LINE WAS A COMPILER DIRECTIVE, AND IS  #
#                     NOT TO BE PROCESSED BY THE COMPILER. THE VALUE   #
#                     OF SKIPFLG IS IRRELEVANT.                        #
#                                                                      #
#       DIRFLAG = 0,  THE INPUT LINE WAS NOT A COMPILER DIRECTIVE, AND #
#                     THE VALUE OF SKIPFLG CONTROLS WHETHER OR NOT THE #
#                     LINE WILL BE PROCESSED BY THE COMPILER.          #
#                                                                      #
#       SKIPFLG = 0,  THE INPUT LINE IS NOT UNDER THE CONTROL OF       #
#                     CONDITIONAL COMPILATION DIRECTIVES, AND SHOULD   #
#                     BE PROCESSED BY THE COMPILER.                    #
#                                                                      #
#       SKIPFLG = 1,  THE INPUT LINE IS BEING SKIPPED BY CONDITIONAL   #
#                     COMPILATION DIRECTIVES, AND SHOULD NOT BE        #
#                     PROCESSED BY THE COMPILER.                       #
#                                                                      #
#       SKIPFLG = -1, THE INPUT LINE IS BEING INCLUDED BY CONDITIONAL  #
#                     COMPILATION DIRECTIVES, AND SHOULD BE PROCESSED  #
#                     BY THE COMPILER.                                 #
#                                                                      #
#                                                                      #
#ERROR CONDITIONS:                                                     #
#  NONE                                                                #
#                                                                      #
      BEGIN 
      ITEM DIGIT B;                # ITEM SAYS FIRST CHAR IS DIGIT #
      ITEM DIRCODE;                # CODE USED TO REMEMBER WHAT DIRECT #
                                   # IVE IS BEING PROCESSED            #
                                   #   1=DEF, 2=IFEQ, 3=ENDIF          #
      ITEM TC;                     # TO CHAR IN -CONDNAME-  # 
      ITEM TW;                     # TO WORD IN -ACOND-  #
      ARRAY ACOND [0:1] S(2) ;     # ARRAY OF SCRATCH CONDITIONAL STUFF#
        BEGIN 
        ITEM CONDNAME   C(00,00,10);   # NAME OF THESKIPITEM #
        ITEM CONDENTRY  I(01,24,18);   # ENTRY NUM. INTO SKIPTBL FOR #
                                   # THIS NAME #
        ITEM CONDVALUE  I(01,42,18);   # VALUE OF THIS NAME/NUMBER #
        END 
      ARRAY SKIPTBL [1:25] S(2);   # HOLDS THE TABLE OF SKIP ITEMS #
        BEGIN 
        ITEM SKIPNAME   C(00,00,10);   # NAME OF THE ITEM # 
        ITEM SKIPVALUE  I(01,42,18);   # VALUE OF THE ITEM #
        END 
      FW = 0;                      # FROM-WORD IS FIRST WORD #
      DIRFLAG = 1;                 # ASSUME IT IS A DIRECTIVE # 
      IF C<0,7>INWORD[0] EQ "#EJECT#" 
      THEN
        BEGIN 
        SCALL PRNTHDR;
        RETURN; 
        END 
  
      SCALL CHKLINO;               # INCREMENT LINENO OR PAGENO        #
      IF C<0,4>INWORD[0] EQ "DEF " THEN 
        BEGIN 
        FC = 3;                    # LAST CHAR POS CHECKED HERE        #
        DIRCODE = 1;               # CODE FOR DEF # 
        END 
      ELSE
        IF C<0,5>INWORD[0] EQ "IFEQ " THEN
          BEGIN 
          FC = 4;                  # LAST CHAR POS CHECKED HERE        #
          DIRCODE = 2;             # CODE FOR IFEQ #
          END 
        ELSE
          IF C<0,6>INWORD[0] EQ "ENDIF " THEN 
            BEGIN 
            DIRCODE = 3;            # CODE FOR -ENDIF- #
            SKIPFLG = 0;            # TERMINATE SKIPPING #
            RETURN; 
            END 
          ELSE
            BEGIN 
            DIRFLAG = 0;           # NOT A DIRECTIVE #
            RETURN; 
            END 
      FOR TW = 0 STEP 1 UNTIL 1 DO # FOR EACH OF THE TO-WORDS          #
        BEGIN 
        CONDNAME[TW] = " ";        # INITIALIZE NAME TO BLANKS #
        CONDVALUE[TW] = 0;         # INITIALIZE VALUE TO ZERO # 
        CONDENTRY[TW] = 0;         # NULL ENTRY POS IN -SKIPTBL- IS 0 # 
        DIGIT = FALSE;             # START WITH ASSUMPTION OF NOT DIGIT#
        FOR TC = 0 STEP 1 UNTIL 9 DO # FOR EACH POSSIBLE CHAR POS      #
          BEGIN 
          SCALL GETCHAR;           # MOVE NEXT CHAR TO -AINCHAR-       #
          IF TYPE EQ CHARTYPE"DELIMITER" THEN 
            TEST TW;               # MARKS THE END OF THIS TOKEN       #
          IF TYPE EQ CHARTYPE"NUMERIC" AND TC EQ 0 THEN 
            DIGIT = TRUE;          # FIRST CHAR NUMERIC...INT LITERAL  #
          IF DIGIT THEN            # IF AN INTEGER LITERAL             #
            IF TYPE EQ CHARTYPE"NUMERIC" THEN   # ADD IN NUMBER VALUE  #
              CONDVALUE[TW] = CONDVALUE[TW] * 10 + INCHARI[0] - O"33";
            ELSE                   #ONLY NUMERIC ALLOWED IN INT LITERAL#
              BEGIN 
              TC = 10;             # TO FORCE OUT OF -TC- LOOP         #
              TEST TC;             # WHERE WE SKIP TO NEXT DELIMITER   #
              END 
          ELSE
            C<TC,1>CONDNAME[TW] = INCHARC[0]; 
          END 
        FOR TYPE = TYPE WHILE TYPE NQ CHARTYPE"DELIMITER" DO
          SCALL GETCHAR;           # SKIP TO NEXT DELIMITER            #
        END 
      FOR I = 0 STEP 1 UNTIL 1 DO      # FOR EACH OF THE SCRATCH ENTRIE#
        IF CONDNAME[I] NQ " " THEN   # HAVE AN ITEM NAME...FIND IT #
          BEGIN 
          FOR J = 1 STEP 1 UNTIL TOPENTRY DO   # FOR EACH SKIP ITEM # 
            IF SKIPNAME[J] EQ CONDNAME[I] THEN
              BEGIN 
              CONDVALUE[I] = SKIPVALUE[J];   # SCRATCH ITEM GETS VALUE #
              CONDENTRY[I] = J;    # ALSO ENTRY POSITION #
              TEST I;              # FOUND THIS ONE, GO BACK FOR MORE # 
              END 
          TOPENTRY = TOPENTRY + 1; # NOT FOUND IN TABLE..ALLOCATE ENTRY#
          SKIPNAME[TOPENTRY] = CONDNAME[I];  # NAME THE ENTRY # 
          SKIPVALUE[TOPENTRY] = 0;     # GIVE IT A NULL VALUE # 
          CONDVALUE[I] = 0;        # GIVE THE SCRATCH ITEM NULL ALSO #
          CONDENTRY[I] = TOPENTRY; # ITS ENTRY POS IS THE TOP # 
          END 
      IF DIRCODE EQ 1 THEN         # IF A -DEF- DIRECTIVE # 
        BEGIN 
        SKIPVALUE[CONDENTRY[0]] = CONDVALUE[1];    # IT RECEIVES VALUE #
        RETURN;                    # -DEF- ALL DONE. #
        END 
      IF DIRCODE EQ 2 THEN         # IT IS AN -IFEQ- DIRECTIVE #
        BEGIN 
        IF CONDVALUE[0] NQ CONDVALUE[1] THEN SKIPFLG = 1;  # SKIPPING # 
        ELSE SKIPFLG = -1;         # SIGNIFIES A GOOD COMPARE # 
        RETURN;                    # -IFEQ- ALL DONE #
        END 
      END 
      CONTROL EJECT;
      PROC CHKLINO; 
#**********************************************************************#
#                                                                      #
#                              CHKLINO                                 #
#                                                                      #
#ROUTINE WHICH ADDS 1 TO LINE NO AND COMPARES LINE NO TO LINE LIMIT.   #
#IF LINENO = LINELIMIT CALLS PRNTHDR TO PRINT HEADER AND RESET LINE NO #
#                                                                      #
#ENTRY CONDITIONS                                                      #
#  LINENO AND PAGENO EQUAL LINE NUMBER AND PAGE NUMBER OF LAST LINE    #
#  ANOTHER LINE IS ABOUT TO BE PRINTED                                 #
#                                                                      #
#EXIT CONDITIONS                                                       #
#  LINENO AND PAGENO = LINE AND PAGE NUMBER OF LINE ABOUT TO BE PRINTED#
#  USES SYNORL, CTEMP, ITEMP                                           #
#                                                                      #
      BEGIN 
      IF LINENO LS LINELIMIT THEN 
        BEGIN 
          LINENO = LINENO + 1;     #INCREMENT LINE NO. IF ROOM ON PAGE #
        END 
      ELSE
        BEGIN 
          SCALL PRNTHDR;           #PRINT HDR, RESET PAGENO, LINENO    #
        END 
      RETURN; 
      END 
      CONTROL EJECT;
      PROC PRNTHDR; 
#**********************************************************************#
#                                                                      #
#                              PRNTHDR                                 #
#                                                                      #
#ROUTINE TO RESET LINENO AND PAGENO TO FIRST LINE ON NEXT PAGE AND     #
#PRINT HEADER AT TOP OF PAGE                                           #
#                                                                      #
#ENTRY CONDITIONS                                                      #
#  PAGENO = PAGE NUMBER OF LAST LINE ON OUTPUT FILE                    #
#  HEADER IN ARRAY HEADERLINE                                          #
#                                                                      #
#EXIT CONDITIONS                                                       #
#  HEADER PRINTED AT TOP OF NEXT PAGE                                  #
#  LINENO AND PAGENO SET TO FIRST LINE ON NEXT PAGE                    #
#  USES SYNORL, CTEMP, ITEMP                                           #
#                                                                      #
#EXTERNAL REFERENCES                                                   #
#  SYNPRNT  OUTPUT HEADER LINE AND TRIPLE SPACE LINE                   #
#                                                                      #
      BEGIN 
      LINENO = 0;                  #RESET LINE NO                      #
      PAGENO = PAGENO + 1;         #INCREMENT PAGE NO BY 1             #
      IF LFLAG NQ 0 THEN           #IF LISTING BEING WRITTEN, NOT L=0  #
        BEGIN 
          ITEMP = PAGENO;          #INPUT PARAMETER TO BINTODISPDEC    #
          SCALL BINTODISPDEC;      #CONVERT PAGENO TO DISPLAY CODE DEC #
          HDRPAGENO[0] = CTEMP;    #TRANSFER OUTPUT FROM BINTODISPDEC  #
          SYNORL = 125; 
          SYNPRNT(HEADERLINE);     #PRINT HEADER LINE                  #
          SYNORL = 8; 
          SYNPRNT("-       ");     #PRINT TRIPLE SPACE                 #
        END 
      RETURN; 
      END 
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                       S Y N G E N                                    #
#                                                                      #
#THE SYSTEMS COMMUNICATION AREA MUST BE EXAMINED FOR PARAMETERS IN THE #
#SYNGEN CONTROL CARD CALL. POSSIBILITIES ARE:                          #
#SYNGEN CONTROL STATEMENT. NOTE - ONLY THE FIRST CHARACTER OF EACH     #
#PARAMETER IS USED TO CHECK AGAINST THE OPTION LIST. PARAMETER VALUES  #
#FOR FILENAMES ARE ACCEPTED UP TO SEVEN CHARACTERS LONG. THE           #
#POSSIBLE OPTIONS ARE:                                                 #
#                                                                      #
# ABORT - OPTION TO CAUSE SYNGEN TO ABORT AFTER ALL COMPILATIONS IF    #
#         ANY SOURCE ERRORS OCCURED. IF OMITTED, SYNGEN WILL JUST      #
#         TERMINATE NORMALLY IF ERRORS HAVE OCCURRED.                  #
# L=LFN - LFN OF THE FILE SYNGEN WILL WRITE A LISTING OF INPUT PLUS    #
#         CROSS-REFERENCE AND DIAGNOSTICS REFERENCES. ALSO DIAGNOSTICS #
#         OF BAD INPUT. L=0 SUPPRESSES ALL OUTPUT EXCEPT DIAGNOSTICS.  #
#         DEFAULT LFN IS OUTPUT                                        #
# I=LFN - LFN OF THE FILE SYNGEN IS TO USE AS IT"S INPUT FILE. THE     #
#         THE DEFAULT NAME IS INPUT (SYSTEM INPUT FILE).               #
# O=LFN - LFN OF THE FILE SYNGEN IS TO USE FOR THE PRESET ARRAYS (THE  #
#         DRIVING TABLES FOR SYNTAX ANALYZERS) WHICH IT BUILDS.        #
#         DEFAULT NAME IS COMPILE.                                     #
# NOREWIND - FLAG INDICATING THE REQUEST FOR NOT REWINDING ALL FILES AT#
#         END OF SYNGEN EXECUTION. THE DEFAULT CASE IS REWINDING ALL   #
#         FILES USED BY SYNGEN.                                        #
#  T=1 - TRACEM TABLE IS BUILT. THE DEFAULT IS NO TRACE TABLE  #
#         WHICH CORRESPONDS TO THE SYNTBLE, IS BUILT AND WRITTEN ON THE#
#         FILE WHICH IS TO CONTAIN ALL THE OTHER PRESET ARRAYS.        #
# CARDCOL=11 - SPECIFIES THAT THE KEYWORDS AND SUBROUTINE NAMES WILL BE#
#         OFFSET 10 COLUMNS TO THE RIGHT.                              #
#                                                                      #
# OBSOLETE OPTIONS:                                                    #
#                                                                      #
# P=PROC - NAME OF THE PROC TO BE COMPILED BY SYNGEN. THIS WILL BE THE #
#         NAME USED IN THE SYMPL SOURCE. THE USE OF THIS OPTION IS     #
#         DISCOURAGED. THE PROC NAME SHOULD INSTEAD BE GIVEN ON THE    #
#         FIRST SOURCE LINE GIVEN TO SYNGEN. THIS LINE SHOULD CONTAIN  #
#         *PROC XXXXXXX* (FOR EXAMPLE) WITH THE *P* IN COLUMN 1.       #
#         MULTIPLE PROCS CAN BE COMPILED BY ENDING EACH PROC WITH      #
#         *TERM* IN COLUMN 1, THEREAFTER FOLLOWED BY THE NEXT          #
#         *PROC XXXXXXX* IN COLUMN 1.                                  #
#                                                                      #
#                                                                      #
# ERRORS DIAGNOSED: ERRORS IN THE SYNGEN CONTROL CARD CAUSE A DAYFILE  #
#                   DIAGNOSTIC MESSAGE AND THE JOB IS ABORTED.         #
  
      BEGIN 
      LFLAG = 1;               #INITIALIZE CONTROL CARD OPTIONS TO THE #
      INFILE = O"11162025240000000000";#DEFAULT VALUES.                #
      OUTFILE = O"03171520111405000000";
      LSTFILE = O"17252420252400000000";
      TFLAG = 0;
      REWIND = 1; 
      ERRORFLAG = 0;
      P<RA> = 2;
      J = NRCCPARAMS[50] - 1;  #PICK NR OF PARAMS FOR INDEXING.        #
      FOR I=0 STEP 2 UNTIL J DO 
        BEGIN 
          CTEMP = CCPARAM[I];  #ISOLATE 1ST CHAR IN CONTROL CARD PARAM.#
          IF CTEMP EQ "A" THEN     # IF ABORT OPTION SPECIFIED BY USER #
            BEGIN 
              ABTFLAG = TRUE;      # ABORT-ON-ERRORS REQUESTED         #
              I = I - 1;           # THIS PARAM TAKES UP ONLY ONE WORD #
              TEST I; 
            END 
          IF CTEMP EQ "L" THEN #LISTING OPTION MAY BE SPECIFIED BY USER#
            BEGIN 
              IF CCPARAM[I+1] NQ "0" THEN 
                B<0,42>INWORD[2] = CCFILENAME[I+1]; 
              ELSE LFLAG = 0; 
              TEST I; 
            END 
          IF CTEMP EQ "T" THEN #TRACE OPTION SPECIFIED BY USER MAY ONLY#
            BEGIN              #BE FOLLOWED BY A ZERO, TURNING OFF THE #
              IF CCPARAM[I+1] NQ "0" THEN #OPTION AND FLAG.            #
                TFLAG = 1;
              ELSE TFLAG = 0; 
              TEST I; 
            END 
          IF CTEMP EQ "I" THEN #INPUT FILE OPTION IS EXERCISED BY THE  #
            BEGIN              #USER.                                  #
              B<0,42>INWORD[0] = CCFILENAME[I+1]; 
              TEST I; 
            END 
          IF CTEMP EQ "O" THEN #OUTPUT FILE OPTION IS EXERCISED BY     #
            BEGIN                  #THE USER.                          #
              B<0,42>INWORD[1] = CCFILENAME[I+1]; 
              TEST I; 
            END 
          IF CTEMP EQ "N" THEN #NOREWIND OPTION IS EXERCISED BY THE    #
            BEGIN                  #USER.                              #
              I = I - 1;       #THIS PARAM TAKES UP ONLY ONE WORD.     #
              REWIND = 0; 
              TEST I; 
            END 
          IF CTEMP EQ "C" THEN #KEYWORDS AND SUBROUTINE NAMES START IN #
            BEGIN              #A COLUMN OTHER THAN ONE.               #
              IF B<0,12>CCFILENAME[I+1] EQ O"3434" THEN #ONLY VALID    #
                WORD1 = 1;     #VALUE IS CARDCOL = 11.                 #
              ELSE ERRORFLAG = 1; 
              TEST I; 
            END 
          IF CTEMP EQ "P" THEN #PROC NAMING OPTION EXERCISED.          #
            BEGIN 
              PNAME[0] = "  PROC    ";
              PNAME[1] = " "; 
              K = 42; 
              L = 0;
              FOR M=0 STEP 6 UNTIL 36 DO
                BEGIN 
                  ITEMP = B<M,6>CCFILENAME[I+1];
                  IF ITEMP EQ 0 THEN
                    GOTO ENDWITHSEMI; 
                  B<K,6>PNAME[L] = ITEMP; 
                  IF K GR 53 THEN 
                    BEGIN 
                      K = 0;
                      L = 1;
                    END 
                  ELSE K = K + 6; 
                END 
 ENDWITHSEMI: 
              B<K,6>PNAME[L] = ";"; 
              TEST I; 
            END 
          ERRORFLAG = 1;           #ERROR IF PARAM NOT ONE OF ABOVE.   #
        END 
      IF ERRORFLAG NQ 0 THEN       #CONTROL CARD ERRORS CAUSE A JOB    #
        SYNABT(1);                 #ABORT.                             #
      SYNOPEN;                     #SYNOPEN IS A COMPASS ROUTINE WHICH #
                                   #OPENS ALL FILES TO BE USED IN THIS #
                                   #SYNGEN RUN.                        #
      LASTAVAIL = B<0,60>INWORD[0] - 1; #PTR RETURNED BY SYNOPEN.      #
      IF LASTAVAIL GR O"77777" THEN #HASHEDTABLE ENTRIES HAVE ONLY 15  #
        LASTAVAIL = O"77777";  #BITS FOR POINTERS, SO 77777 IS THE MOST#
                               #CORE USABLE BY THIS VERSION. IF MORE   #
                               #CORE IS NECESSARY, THE SYMBOL TABLE    #
                               #ENTRIES MAY BE ADDRESSED RELATIVE TO   #
                               #THE HIGH END OF FL, RATHER THAN        #
                               #DIRECTLY.                              #
      OLD65 = NEXTAVAIL[51];
      OLDLA = LASTAVAIL;
      SCALL SYNTIDA;           #SET TIME AND DATE INTO HEADER          #
      HDRDATE1[0] = HDRDATE;
      HDRTIME1[0] = HDRTIME;
PROCLOOP: 
#  THE FOLLOWING IS CODE TO PRESET CM FOR A COMPILE OF A PROGRAM  # 
      NEXTAVAIL[51] = OLD65;
      P<SYNTBLE> = NEXTAVAIL[51];  # INITIAL POSITION OF SYNTBLE       #
      SYNTBLEWORD = 1;             # FIRST AVAILABLE WORD ADDRESS IN   #
                                   # PSEUDO-WA FILE *SYNTBLE*          #
      LASTAVAIL = OLDLA;
      FOR I = OLD65-2 STEP 1 UNTIL LASTAVAIL-2 DO FULLWORD[I] = 0;
      COUNTER = 0;
      ERRORCOUNT = 0; 
      LABELCOUNTER = 0; 
      SECTIONWORD = 0;
      SYMBOLTYPE = O"23"; 
      SYMBOLLENGTH = 2; 
      SYNTBLEPARCL = 0; 
      UNDEFSYMBOLS = 0; 
      KEY1PTR = 0;
      KEY2PTR = 0;
      KEY3PTR = 0;
      BP = 0; 
      STATE = 0;
      FOR I = 0 STEP 1 UNTIL 127 DO HASHENTRY[I] = 0; 
      FOR I = 0 STEP 1 UNTIL 26 DO LOCWRD[I] = 0; 
      FIRSTSUBLABL = 0; 
      SECTIONWORD = 0;
      LASTRANSFER = 0;
      FIRSTCHAR = 0;
      CURRENTLABEL[0] = 0;
      CURRENTLABEL[1] = 0;
      CURRENTLABEL[2] = 0;
      INS$EXT = S"INSERT";
      P<SYMBOLTABLE> = 0; 
      CHRPTR = 73;
      PTC = FALSE;
      SYNEOF = 0; 
      ENDINP;     # REWIND THE XREF FILES  #
      OUTLEN = 60;           #  SET LENGTH FOR COMPILE RECORDS  # 
      LEXBUILD;                    #LEXBUILD IS A SYMPL PROC WHICH     #
                                   #BUILDS THE LEXICON TABLES.         #
      ITEMP = (OLDLA - LASTAVAIL) + (P<SYNTBLE> + SYNTBLEWORD); 
      IF ITEMP GR FL
      THEN
        BEGIN 
        FL = ITEMP;                # MAINTAIN -FL- AS MAXIMUM FL       #
        END 
  
      P<SYNTBLE> = NEXTAVAIL[51];  # POSITION TO END OF LEXICAL TABLES #
      IF LFLAG NQ 0 THEN
        BEGIN 
          HDRTITLE[0] = "INPUT SEMANTIC ROUTINES "; 
          SCALL PRNTHDR;       #START NEXT PAGE WITH HEADER            #
        END 
      SUBRBUILD;                   #SUBRBUILD IS A SYMPL PROC WHICH    #
                                   #BUILDS A SUBROUTINE NAME TABLE FOR #
                                   #LATER IN BUILDING THE SYNTAX TABLE.#
      IF LFLAG NQ 0 THEN
        BEGIN 
          HDRTITLE[0] = "INPUT SYNTAX SPECIFICATIONS "; 
          SCALL PRNTHDR;
        END 
      P<STATETRANS> = LOC(STATTRNS);#BUG IN SYMPL COMPILER COULD NOT   #
                               #PRESET A 2-D ARRAY, SO HAD TO PRESET A #
                               #1-D ARRAY AND SET A 2-D BASED ARRAY TO #
                               #IT FOR USE.                            #
      SYNBUILD;                    #SYNBUILD IS A SYMPL PROC WHICH     #
                                   #CONSTRUCTS THE OUTPUT PRESET ARRAYS#
                                   #SYNTBLE, LBLPTRS, AND TRACEM, AS   #
                                   #WELL AS THE CROSS REFERENCE FILES, #
                                   #IF LFLAG IS SET TO ONE.            #
      SYNCOPY(SYNTBLEWORD);    #COMPASS RTN WHICH COPIES SYNTBLE AND   #
                               #TRACEM.                                #
      CONLEXTABLES;            #RTN WHICH CONVERTS BINARY LEXICON      #
                               #TABLES TO OUTPUT DISPLAY CODE AND      #
                               #WRITES THEN OUT.                       #
      IF NOT PTC THEN 
        SYNCOM ("     END 
          "); 
      ELSE
        BEGIN 
        OUTLEN = 90;
PTCTRANS: 
        SYNREAD;
        IF C<0,3>INWORD[0] EQ "END" OR REALEOF GR 0 THEN GOTO PTCEOF; 
        SYNCOM(SYNIWSA);
        GOTO PTCTRANS;
PTCEOF:  #    # 
        END 
      SYNCOM("       END
        "); 
      SYNCOM("     TERM;
        "); 
      IF LFLAG NQ 0 THEN           #IF THE USER REQUESTED A LISTING,   #
        SYNXREF;                   #SYNREF IS A SYMPL ROUTINE WHICH    #
                                   #SORTS THE CROSS REFERENCE LISTS AND#
                                   #PRINTS THEM.                       #
      ITEMP = (OLDLA - LASTAVAIL) + (P<SYNTBLE> + SYNTBLEWORD); 
      IF ITEMP GR FL THEN FL = ITEMP;   # MAINTAIN -FL- AS MAXIMUM FL  #
      ERRORS = ERRORS + ERRORCOUNT;   # MAINTAIN TOTAL ERRORS          #
      IF REALEOF EQ 0 THEN GOTO PROCLOOP; 
WRAPUP:   #   # 
  
#     ROUND THE MAXIMUM FL UP TO THE NEXT 100B WORDS                   #
  
      ITEMP = ((FL + O"100") / O"100") * O"100";
      BINTODISPOCT; 
      ITEMP = ERRORS;          # TOTAL ERRORS IN THIS RUN              #
      BINTODISPDEC; 
      SYNCLSE(CTEMP,OCTAL[1]); #SYNCLSE IS A COMPASS ROUTINE WHICH     #
                               #WRITES OUT THE PRESET ARRAYS WHICH HAVE#
                               #BEEN BUILT BY SYNGEN, THEN CLOSES ALL  #
                               #THE FILES USED IN THIS SYNGEN RUN.     #
      IF ABTFLAG                   # IF ABORT-ON-ERRORS REQUESTED      #
        AND (ERRORS NQ 0)          #   AND ERRORS DID OCCUR            #
      THEN
        BEGIN 
        SYNABT(5);                 # SOURCE ERRORS -- ABORT REQUESTED  #
        END 
  
      STOP;                        # NORMAL TERMINATION OF SYNGEN      #
      END 
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          SYNALLOCATE                                 #
#                                                                      #
#**********************************************************************#
#FUNCTION WHICH ALLOCATES SPACE WITHIN THE JOB"S FIELDLENGTH, IN A CON-#
#TIGUOUS FASHION, AND RETURNS A POINTER TO THE FWA OF THE ALLOCATED    #
#SPACE. THE LWA OF AVAILABLE SPACE IS OBTAINED FROM RA+54 AND THE FWA  #
#OF AVAILABLE SPACE IS OBTAINED FROM RA+53. AS SPACE IS ALLOCATED, RA+ #
#53 OR RA+54 IS UPDATED. A NEGATIVE SIZE REQUEST IS ALLOCATED FROM FL  #
#BACKWARDS WHILE A POSITIVE SIZE REQUEST IS ALLOCATED FROM LWA CURRENT-#
#LY ALLOCATED FORWARDS TOWARDS FL.                                     #
#  ERRORS DIAGNOSED: REQUESTS THAT EXCEED THE JOB"S FIELDLENGTH RESULT #
#                    IN DIAGNOSTIC MESSAGES FOLLOWED BY A HALT.        #
#                                                                      #
 FUNC SYNALLOCATE(SIZE);
   BEGIN
      ITEM SIZE;               #SIZE OF THE SPACE REQUESTED.           #
      IF (P<SYNTBLE> + SYNTBLEWORD + ABS(SIZE)) GR LASTAVAIL
      THEN                         # THEN NOT ENOUGH ROOM FOR -SIZE-   #
        BEGIN 
        SYNABT(0);                 # INSUFFICIENT FL MESSAGE AND ABORT #
        END 
  
      IF SIZE LS 0 THEN 
        GOTO NEGSIZE; 
      NEXTAVAIL[51] = NEXTAVAIL[51] + SIZE;#UPDATE PTR TO NEXT WORD    #
      IF NEXTAVAIL[51] GR P<SYNTBLE> THEN  #  MOVE SYMTBLE OUT OF THE  #
        BEGIN                              #  WAY OF THE NEW TABLE  # 
        P<SORT> = NEXTAVAIL[51];
        FOR I = SYNTBLEWORD STEP -1 UNTIL 0 DO
          SORTWORD[I] = SYNTBLEWD[I]; 
        P<SYNTBLE> = P<SORT>; 
        END 
      SYNALLOCATE = NEXTAVAIL[51] - SIZE;#AVAILABLE AND RETURN PTR TO  #
      RETURN;                  #ALLOCATED SPACE.                       #
 NEGSIZE: 
      LASTAVAIL = LASTAVAIL + SIZE;#UPDATE PTR TO END OF AVAILABLE     #
      SYNALLOCATE = LASTAVAIL + 1; #SPACE AND RETURN PTR TO THE ALLOCAT#
      RETURN;                  # ED SPACE.                             #
   END
      CONTROL EJECT;
 #*********************************************************************#
 #                              LEXBUILD                               #
 #*********************************************************************#
  PROC LEXBUILD;
    BEGIN 
      HDRPROC[0] = " ";        #BLANK FILL PROC NAME                   #
      HDRPROC1[0] = " ";
      HDRTITLE[0] = "INPUT KEYWORDS ";
      PAGENO = 0;              #FORCE SYNREAD TO PRINT HEADER AT PAGE 1#
      LINENO = LINELIMIT;      #ON NEXT (NONEOF) READ                  #
      P<SYN1SCRATCH> = SYNALLOCATE(750); # ALLOCATE SPACE FOR ONE      #
      P<SYN2SCRATCH> = SYNALLOCATE(500); #TWO                          #
      P<SYN3SCRATCH> = SYNALLOCATE(300); #THREE WORD KEYWORDS          #
      SYNREAD;
      IF REALEOF GR 0 THEN GOTO WRAPUP; 
      IF C<0,4>INWORD[0] NQ "PROC" THEN GOTO READKEYWD1;
      PNAME[0] = "          ";
      PNAME[1] = INWORD[0]; 
      PNAME[2] = INWORD[1]; 
      PNAME[3] = ";"; 
      HDRPROC[0] = INWORD[0];  #INSERT PROC **** IN HEADER             #
      HDRPROC1[0] = INWORD[1];
  READKEYWRD:                          #                               #
      SYNREAD;                         # READ KEYWORD LIST (80 CHAR).  #
READKEYWD1: 
      IF SYNEOF GR 0 THEN              #STOP IF EOF ENCOUNTERED.       #
        SYNABT(2);
      IF C<0,1>INWORD[WORD1] EQ " " THEN #IF 1ST CHAR IS BLANK THE CARD#
        GOTO READKEYWRD;       #IS ASSUMED BLANK AND SKIPPED.          #
      IF WORD1 NQ 0 THEN           # MOVE WORDS 1,2 TO 0,1 AND IGNORE  #
        BEGIN                          # WORD 0.                       #
          INWORD[0] = INWORD[1];
          INWORD[1] = INWORD[2];
          INWORD[2] = " ";
        END 
      IF INWORD[0] EQ "+" AND      #A + MAY BE A KEYWORD OR TERMINATOR.#
         C<6,4>INWORD[3] EQ " " THEN       # IF NO LEXID FIELD, ASSUME #
        BEGIN                  #CARD IS TERMINATOR.                    #
          IF KEY1PTR EQ KEY2PTR AND #IF NO KEYWORDS READ BEFORE + THEN #
             KEY2PTR EQ KEY3PTR AND #NO LEXICON TO BUILD.              #
             KEY3PTR EQ 0 THEN
               RETURN;
          NUMBER1WRD = KEY1PTR - 2;    # SET KEYWORD SECTION BOUNDRIES.#
          NUMBER2WRD = KEY2PTR - 3;    #                               #
          NUMBER3WRD = KEY3PTR - 4;    #                               #
          GOTO PASS1;                  #                               #
        END 
      K = 0;                           # WORD POINTER IN FOR-LOOP.     #
      J = 0;                           # CHARACTER POINTER IN FOR-LOOP.#
      FOR I=0 STEP 1 UNTIL 29 DO       # SCAN THE INPUT WORKING STORAGE#
        BEGIN                          # AREA FOR A BLANK. THE FIRST   #
          IF B<J,6>INWORD[K] EQ O"55"  # OCCURENCE OF A BLANK TERMINATE#
               THEN GOTO CHECKLENGTH;  # S THE KEYWORD NAME. AT THE    #
                                       # COMPLETION OF THE FOR-LOOP "I"#
                                       # WILL CONTAIN THE LENGTH OF THE#
                                       # KEYWORD.                      #
           IF J EQ 54 THEN             # CHECK IF COMPLETE WORD HAS    #
             BEGIN                     # BEEN SCANNED. IF IT HAS THEN  #
               J = 0;                  # SET CHAR PTR (J) TO POINT TO  #
                                       # THE 1ST CHAR OF THE NEXT WORD,#
               K = K + 1;              # INCREMENT THE WORD PTR (K) TO #
             END                       # POINT TO THE NEXT WORD.       #
            ELSE                       #                               #
              J = J + 6;               # INCREMENT J TO POINT TO THE   #
        END                            # NEXT CHARACTER.               #
   CHECKLENGTH:                        #                               #
      B<J,60-J>INWORD[K] = "          ";#BLANK REST OF WORD AS INSUR-  #
                                       # ANCE.                         #
      IF I LS 11 THEN GOTO ONEKEYWORD; # CHECK FOR A "1" WORD KEYWORD. #
      IF I LS 21 THEN GOTO TWOKEYWORD; # CHECK FOR A "2" WORD KEYWORD. #
                                       #                               #
      KEY3WRD[KEY3PTR] = INWORD[0];    # STORE    "FIRST"              #
      KEY3WRD[KEY3PTR + 1] = INWORD[1];#          "SECOND"             #
      KEY3WRD[KEY3PTR + 2] = INWORD[2];#          "THIRD" WORD OF THE  #
                                       # KEYWORD IN A SCRATCH WORKING  #
                                       # STORAGE AREA.                 #
      KEY3PTR = KEY3PTR + 4;           # INCREMENT KEY3PTR TO POINT TO #
                                       # WHERE THE NEXT KEYWORD IS TO  #
                                       # BE PLACED.                    #
      LEXPTR = KEY3PTR - 1;            # POINTER TO WORD POSITION WHERE#
                                       # ID,P1,P2 AND SECT ARE TO BE   #
                                       # PLACED.                       #
      P<LEXICON> = LOC(SYN3SCRATCH);   # ARRAY FOR ACCESSING ID,P,P2   #
                                       # AND SECT.                     #
      GOTO MOVELEXICON;                #                               #
  TWOKEYWORD:                          #                               #
      KEY2WRD[KEY2PTR] = INWORD[0];    # STORE    "FIRST"              #
      KEY2WRD[KEY2PTR + 1] = INWORD[1];#          "SECOND" WORD OF THE #
                                       # KEYWORD IN A SCRATCH WORKING  #
                                       # STORAGE AREA.                 #
      KEY2PTR = KEY2PTR + 3;           # INCREMENT KEY2PTR TO POINT TO #
                                       # WHERE THE NEXT KEYWORD IS TO  #
                                       # BE PLACED.                    #
      LEXPTR = KEY2PTR - 1;            # POINTER TO WORD POSITION WHERE#
                                       # ID,P1,P2 AND SECT ARE TO BE   #
                                       # PLACED.                       #
      P<LEXICON> = LOC(SYN2SCRATCH);   # ARRAY FOR ACCESSING ID,P,P2   #
      GOTO MOVELEXICON;                # AND SECT.                     #
  ONEKEYWORD:                          #                               #
      P<LEXICON> = LOC(SYN1SCRATCH);   #                               #
      LEXWRD[KEY1PTR] = INWORD[0];     # STORE THE KEYWORD IN THE KEY- #
                                       # WORD ARRAY.                   #
      KEY1PTR = KEY1PTR + 2;           # INCREMENT KEY1PTR TO POINT TO #
                                       # WHERE THE NEXT KEYWORD IS TO  #
                                       # BE PLACED.                    #
      LEXPTR = KEY1PTR - 1;            # POINTER TO WORD POSITION WHERE#
                                       # ID=P1,P2 AND SECT ARE TO BE   #
                                       # PLACED.                       #
  MOVELEXICON:                         #                               #
      CTEMP = C<5,5>INWORD[3]; # CONVERT LEXID AND STORE IT.           #
      DISPOCTTOBIN; 
      LEXID[LEXPTR] = ITEMP;
      CTEMP = C<5,5>INWORD[4]; # CONVERT P1 AND STORE IT.              #
      DISPOCTTOBIN; 
      LEX1PARAM[LEXPTR] = ITEMP;
      CTEMP = C<5,5>INWORD[5]; # CONVERT P2 AND STORE IT.              #
      DISPOCTTOBIN; 
      LEX2PARAM[LEXPTR] = ITEMP;
      IF C<0,1>INWORD[3] EQ "*" THEN   # CHECK FOR AN * IN COL 31. IF  #
        LEXSYNSECT[LEXPTR] = -1;       # THERE IS AN * PRESENT, SET    #
       ELSE                            # LEXSYNSECT TO 1. IF THERE IS  #
        LEXSYNSECT[LEXPTR] = 0;        # NO * SET LEXSYNSECT TO 0. AN  #
                                       # * INDICATES THAT THERE IS A   #
                                       # LABELED SECTION NAME IN THE   #
                                       # SYNTAX STATEMENTS THAT IS IDEN#
                                       # TICAL TO THIS KEYWORD.        #
      GOTO READKEYWRD;                 # READ NEXT RECORD OF THE KEY-  #
                                       # WORD LIST.                    #
  PASS1:  
      P<LEXICON> = LOC(SYN1SCRATCH);   # POINTER TO 1 WRD KEYWRD BUFFER#
      MAXKEYWRDS = NUMBER1WRD;         # STORE NUMBER OF 1 WORD KEYWRDS#
      K = 2;                           # VALUE THAT LEXPTR IS INCREMENT#
                                       # ED BY.                        #
      I = 0;                           # BEGINNING BIT POSITION OF     #
                                       # ENTRIES FIELD IN LEXWORDLOC.  #
      J = 6;                           # BEGINNING BIT POSITION OF     #
                                       # INDEX TO KEYWRD LIST FIELD IN #
                                       # LEXWORDLOC.                   #
      TOTALWORDS = 0;                  # INITIALIZE LEXWORDS WORD CNTR.#
      GOTO INITWRDLOC;                 # PROCESS KEYWORD.              #
  PASS2:  
      IF NUMBER2WRD LS 0 THEN          # IF NO 2-WORD KEYWORDS, THEN GO#
        GOTO PASS3;                    # DO 3-WORD KEYWORDS.           #
      P<LEXICON> = LOC(SYN2SCRATCH);   # POINTER TO 2 WRD KEYWRD BUFFER#
      MAXKEYWRDS = NUMBER2WRD;         # STORE NUMBER OF 2 WORD KEYWRDS#
      K = 3;                           # VALUE THAT LEXPTR IS INCREMENT#
                                       # ED BY.                        #
      I = 18;                          # BEGINNING BIT POSITION OF     #
                                       # ENTRIES FIELD IN LEXWORDLOC.  #
      J = 24;                          # BEGINNING BIT POSITION OF     #
                                       # INDEX TO KEYWRD LIST FIELD IN #
                                       # LEXWORDLOC.                   #
      GOTO INITWRDLOC;                 # PROCESS KEYWORD.              #
  PASS3:  
      IF NUMBER3WRD LS 0 THEN          # IF NO 3-WORD KEYWORDS, THEN GO#
        GOTO COMPACTLEX;               # COMPACT THE TABLE.            #
      P<LEXICON> = LOC(SYN3SCRATCH);   # POINTER TO 3 WRD KEYWRD BUFFER#
      MAXKEYWRDS = NUMBER3WRD;         # STORE NUMBER OF 3 WORD KEYWRDS#
      K = 4;                           # VALUE THAT LEXPTR IS INCREMENT#
                                       # ED BY.                        #
      I = 36;                          # BEGINNING BIT POSITION OF     #
                                       # ENTRIES FIELD IN LEXWORDLOC.  #
      J = 42;                          # BEGINNING BIT POSITION OF     #
                                       # INDEX TO KEYWRD LIST FIELD IN #
                                       # LEXWORDLOC.                   #
  INITWRDLOC: 
      ENTRIES = 1;                     # INITIALIZE 1ST CHAR COUNTER.  #
      LEXPTR = 0;                      # INITIALIZE PTR TO KEYWRD LIST.#
  BUILDWRDLOC:  
      WRDLOCPTR = B<0,6>LEXWRD[LEXPTR];# SET PTR TO VALUE OF 1ST CHAR  #
      IF WRDLOCPTR GQ O"33" OR         # CHECK FOR START OF SPECIAL    #
         WRDLOCPTR EQ 0 THEN           # CHARACTERS.                   #
           GOTO SPECIALCHARS; 
 SKIPBADKEY:  
      IF LEXPTR EQ MAXKEYWRDS THEN     # CHECK FOR END OF LEXICON SEC- #
        GOTO SETLEXWRDLOC;             # TION.                         #
      KEYFIRSTCHAR =                   # STORE AND CONVERT THE FIRST   #
        B<0,6>LEXWRD[LEXPTR + K];      # CHAR OF THENEXT KEYWORD.      #
      IF WRDLOCPTR EQ KEYFIRSTCHAR THEN# CHECK IF KEYWORDS EQUAL EACH  #
                                       # OTHER ON FIRST CHAR ONLY.     #
        BEGIN 
          ENTRIES = ENTRIES + 1;       # INCREMENT FIRST CHAR COUNTER. #
          LEXPTR = LEXPTR + K;         # INCREMENT TO NEXT ENTRY.      #
          GOTO BUILDWRDLOC;            # PROCESS NEXT KEYWORD.         #
        END 
      IF KEYFIRSTCHAR LS WRDLOCPTR THEN# CHECK FOR SEQUENCE. IF NEXT   #
        BEGIN                          # KEYWORD IS OUT OF SEQUENCE    #
                                       # ISSUE DIAGNOSTIC, AND THEN    #
                                       # PROCECDE WITH BUILDING THE LEX#
                                       # WORDLOC TABLE.                #
        IF KEYFIRSTCHAR EQ 0 THEN      # IF 64 CHAR SET THEN 0 (:) IS A#
          GOTO SETLEXWRDLOC;           # VALID SPECIAL CHARACTER.      #
          SCALL CHKLINO;
          SYNORL = 70;
          FOR M=2 STEP 1 UNTIL K DO 
            LSWORD[M+2] = LEXWRD[LEXPTR+K+M-2]; 
          FOR M=M STEP 1 UNTIL 4 DO 
            LSWORD[M+2] = " ";
          SYNPRNT(LEXSEQ);
          CHKERRCNT;
          ENTRIES = ENTRIES + 1;       # OUT-OF-ORDER KEYWORDS WILL BE #
          LEXPTR = LEXPTR + K;         # HIDDEN IN THE LEXICON SECTION #
          GOTO SKIPBADKEY;             # IN WHICH THEY WERE FOUND, AND #
        END                            # THEY ARE NOT RETRIEVABLE.     #
 SETLEXWRDLOC:  
      B<J,12>LOCWRD[WRDLOCPTR] =       # STORE PTR TO 1ST KEYWORD OF   #
                        TOTALWORDS;    # THIS CHAR SET INTO LEXWRDLOC. #
      B<I,6>LOCWRD[WRDLOCPTR] = ENTRIES;#STORE THE NUMBER OF ENTRIES   #
                                       # IN LEXWORDLOC.                #
      TOTALWORDS = TOTALWORDS + ENTRIES * K;#PTR TO START OF NEW CHAR- #
      IF LEXPTR GQ MAXKEYWRDS THEN     # IF END OF SECTION, WHICH ONE. #
        BEGIN 
 NEXTPASS:  
          IF K EQ 2 THEN               # GO DO TWO-WORD KEYWORDS.      #
            GOTO PASS2; 
          IF K EQ 3 THEN               # GO DO THREE-WORD KEYWORDS.    #
            GOTO PASS3; 
          GOTO COMPACTLEX;             # GO COMPRESS INTO ONE ARRAY.   #
        END 
      ENTRIES = 1;                     # RESET ENTRY COUNTER.          #
      LEXPTR = LEXPTR + K;             # SET KEYWORD PTR TO NEXT KEYWRD#
      IF KEYFIRSTCHAR GQ O"33" OR      # CHECK FOR START OF SPECIAL    #
        KEYFIRSTCHAR EQ 0 THEN         # CHARACTERS.                   #
        BEGIN 
  SPECIALCHARS: 
          B<J,12>LOCWRD[0] = TOTALWORDS;#STORE PTR TO START OF SPECIAL #
          B<I,6>LOCWRD[0] =            # CHARS.                        #
               (MAXKEYWRDS - LEXPTR)/K + 1;#STORE NR ENTRIES FOR SPEC  #
          TOTALWORDS = TOTALWORDS + MAXKEYWRDS - LEXPTR + K;#CHARS AND #
                                       # INCREMENT TOTALWORDS COUNT.   #
          GOTO NEXTPASS;               # CHECK PASS NUMBER.            #
        END 
      GOTO BUILDWRDLOC;                # FINISH CURRENT LEXICON SECTION#
  COMPACTLEX: 
      J = KEY2PTR - 1;                 # NUMBER OF WORDS IN THE 2-WORD #
                                       # KEYWORD BUFFER.               #
      FOR K=0 STEP 1 UNTIL J DO 
        BEGIN 
          KEY1WRD[KEY1PTR] = KEY2WRD[K];# MOVE THE 2-WORD KEYWORDS IN- #
                                       # THE ONE WORD KEYWORD BUFFER.  #
          KEY1PTR = KEY1PTR + 1;       # INCREMENT PTR TO NEXT WORD.   #
        END 
      J = KEY3PTR - 1;                 # NBR OF WORDS IN THE 3-WORD    #
                                       # KEYWORD BUFFER.               #
      FOR K=0 STEP 1 UNTIL J DO 
        BEGIN 
          KEY1WRD[KEY1PTR] = KEY3WRD[K];# MOVE THE 3-WORD KEYWORDS IN- #
                                       # TO THE 1 WORD KEYWORD BUFFER. #
          KEY1PTR = KEY1PTR +1;        # INCREMENT PTR TO NEXT WORD.   #
        END 
      NEXTAVAIL[51] = LOC(KEY1WRD[KEY1PTR]);#RESET PTR TO LAST USED    #
                                       # WORD + 1 AFTER COMPACTION.    #
      P<LEXICON> = LOC(SYN1SCRATCH);   # SET TO COMPACTED TABLE.       #
      RETURN;                          # RETURN TO SYNCTRL.            #
      END 
      CONTROL EJECT;
#**********************************************************************#
      PROC DISPOCTTOBIN;               # CONVERTS DISPLAY-CODED OCTAL  #
        BEGIN                          # (CTEMP) TO BINARY (ITEMP).    #
          ITEMP = 0;                   # INITIALIZE RESULT TO 0.       #
          FOR M=0 STEP 6 UNTIL 54 DO   # CONVERT UP TO 10 CHARACTERS,  #
            BEGIN                      # ONE AT A TIME.                #
              N = B<M,6>CTEMP;
              IF N EQ O"55" THEN       # BLANK TERMINATES INTEGER BUT  #
                IF ITEMP EQ 0 THEN     # LEADING BLANKS ARE IGNORED.   #
                  TEST M;              #                               #
                ELSE RETURN;           #                               #
              IF N LS O"33" OR         # PUT OUT DIAGNOSTIC IF AN IL-  #
                 N GR O"42" THEN       # LEGAL OCTAL DIGIT IS FOUND.   #
                   BEGIN
                     IF LFLAG EQ 0 THEN #IF LFLAG=0 THEN CARD HAS NOT  #
                       BEGIN           # BEEN PRINTED ON OUTPUT.       #
                         SYNORL = SYNIRL + 10;#LIST CARD WITH ERROR.   #
                         SYNPRNT(LOC(SYNIWSA)-1); 
                       END             #                               #
                     SCALL CHKLINO; 
                     SYNORL = 50; 
                     ITEMP = 0;# ZERO IS RETURNED.                     #
                     SYNPRNT(BADOCTALMSG2); 
                      CHKERRCNT;
                     RETURN;           # ILLEGAL DIGIT TERMINATES CON- #
                   END                 # VERSION.                      #
              ITEMP = ITEMP*2**3 + N - O"33";#ADD 3 NEW BITS TO LOW    #
            END                        # ORDER OF RESULT.              #
        END 
      CONTROL EJECT;
#********************************************************************#
#                            SYNTBLR                                 #
#        A PROC TO -READ- ENTRIES FROM THE SYMBOL/CODE TABLE         #
#********************************************************************#
      PROC SYNTBLR(RWSA, RWA);
        BEGIN 
        ARRAY RWSA; 
          ITEM RWSAWD;
        ITEM RWA; 
        FOR P = 0 STEP 1 UNTIL 5 DO 
          RWSAWD[P] = SYNTBLEWD[RWA + P]; 
        RETURN; 
        END 
      CONTROL EJECT;
#********************************************************************#
#                            SYNTBLW                                 #
#        A PROC TO -WRITE- ENTRIES TO THE SYMBOL/CODE TABLE          #
#********************************************************************#
      PROC SYNTBLW(WWSA, WWA);
        BEGIN 
        ARRAY WWSA; 
          ITEM WWSAWD;
        ITEM WWA; 
        IF  LOC (SYNTBLEWD [WWA + 6 ])  GQ  LASTAVAIL  THEN 
          SYNABT(0);         #  ABORT WITH  SHORT FL  # 
        FOR P = 0 STEP 1 UNTIL 5 DO 
          SYNTBLEWD[WWA + P] = WWSAWD[P]; 
        RETURN; 
        END 
      CONTROL EJECT;
#**********************************************************************#
   PROC CONLEXTABLES; 
    BEGIN 
      ITEMP = KEY1PTR - 1;             # NBR OF WORDS IN KEYWORD LIST. #
      M = ITEMP;                       # SAVE VALUE.                   #
      BINTODISPDEC;                    # CONVERT TO DISPLAY DECIMAL.   #
      B<0,30>KEYHDR[2] = B<0,30>CTEMP; # STORE NUMBER OF WORDS IN THE  #
                                       # LEXWORDS PRESET ARRAY.        #
      SYNCOM(KEYWRDHDR);
      SYNCOM(KEYWRDITEM); 
      M = M - (KEY2PTR + KEY3PTR);
      J = 1;
      L = 0;
 STORE: 
      FOR K=0 STEP 1 UNTIL M DO        # MOVE KEYWORDS INTO THE PRESET #
        BEGIN                          # ARRAY.                        #
          IF L EQ J THEN
            BEGIN 
              L = 0;
              KEYLINE[4] = " "; 
              IF B<45,15>KEY1WRD[K] EQ O"77776" THEN #IF NO LABELLED   #
                BEGIN                  # SECTION OF SYNTBLE CORRESPONDS#
                  B<45,15>KEY1WRD[K] = 0;#TO THIS KEYWORD AND THERE WAS#
                  IF LFLAG EQ 0 THEN   # AN * IN COL 31 OF INPUT CARD, #
                    BEGIN              # PRINT MESSAGE AND ZERO-OUT THE#
                      SCRATCHWD[0] = " ";#LEXSYNSECT FIELD PRIOR TO    #
                      FOR I=1 STEP 1 UNTIL J DO  # CONVERSION.         #
                        SCRATCHWD[I] = KEY1WRD[K-(J+1)+I];
                      SYNORL = I * 10;
                      SYNPRNT(SCRATCH); 
                    END 
                  SCALL CHKLINO;
                  SYNORL = 68;
                  SYNPRNT(NOSYNSECT); 
                  CHKERRCNT;
                END 
            END 
          ELSE
            BEGIN 
              L = L + 1;               # STORE KEYWORDS IN COMMENTS.   #
              IF J EQ 1 THEN           # EQIVALENCE SIGNS AND SEMICO-  #
                IF KEY1WRD[K] EQ "#" THEN #LONS CAN AFFECT COMPILATION #
                  KEYLINE[4] = "EQUIV SIGN";#IF PLACED IN COMMENTS, SO #
                ELSE IF KEY1WRD[K] EQ ";" THEN #THEY MUST BE REPLACED  #
                       KEYLINE[4] = "SEMICOLON ";#WITH NAMES.          #
                     ELSE KEYLINE[4] = KEY1WRD[K];
              ELSE KEYLINE[4] = KEY1WRD[K];#KEYWORD GOES IN COMMENT.   #
            END 
          ITEMP = KEY1WRD[K];          # ENTRY CONDITION FOR CONVERSION#
          BINTODISPOCT;                # CONVERT KEYWRD TO DISPLAY OCT.#
          B<0,60>KEYLINE[1] = OCTAL[0];# STORE CONVERTED VALUE.        #
          B<0,60>KEYLINE[2] = OCTAL[1];#                               #
          SYNCOM(KEYWRDLINE);          # MOVE TO OUTPUT FILES.         #
        END 
      IF KEY1PTR NQ 0 THEN
        BEGIN 
          IF KEY2PTR NQ 0 THEN
            BEGIN 
              M = KEY2PTR - 1;
              J = 2;
              L = 0;
              KEY2PTR = 0;
              P<SYN1SCRATCH> = LOC(KEY1WRD[K]); 
              GOTO STORE; 
            END 
          IF KEY3PTR NQ 0 THEN
            BEGIN 
              M = KEY3PTR - 1;
              J = 3;
              L = 0;
              KEY3PTR = 0;
              P<SYN1SCRATCH> = LOC(KEY1WRD[K]); 
              GOTO STORE; 
            END 
        END 
      SYNCOM(KEYWRDTERM); 
      SYNCOM(LEXICONHDR);              # MOVE HEADER TO OUTPUT FILES.  #
      SYNCOM(LEXICONITEM);             # MOVE ITEM DEC TO OUTPUT FILES.#
      FOR K=0 STEP 1 UNTIL 26 DO
        BEGIN 
          ITEMP = LOCWRD[K];           # STORE WORD OF THE LEXICON TBL.#
          BINTODISPOCT;                # CONVERT WORD TO DISPLAY OCTAL.#
          B<0,60>LEXLINE[1] = OCTAL[0];# STORE CONVERTED VALUE.        #
          B<0,60>LEXLINE[2] = OCTAL[1];#                               #
          SYNCOM(LEXICONLINE);
        END 
      SYNCOM(LEXICONTERM);             # WRITE TERMINATOR FOR THE LEX- #
      RETURN;                          # ICON PRESET ARRAY AND RETURN. #
    END 
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          SUBRBUILD                                   #
#                                                                      #
#PROC WHICH PLACES THE USER-SUPPLIED SUBROUTINE NAMES INTO A HASH-CODED#
#TABLE FOR LATER USE BY SYNSCAN WHEN THE SYNTAX TABLE - SYNTABLE - IS  #
#BEING BUILT. THE CARDS IN THE INPUT FILE INTO SYNIWSA BY THE COMPASS  #
#ROUTINE SYNREAD. IF THE USER DEFAULTS THE SWITCH VECTOR ENTRY VALUES  #
#HE GETS CONSECUTIVE VALUES ASSIGNED IN THE ORDER THE NAMES ARE READ.  #
#IF THE USER REQUESTED A LISTING OF HIS INPUT, THE COMPASS ROUTINE     #
#SYNPRNT IS CALLED TO PRINT OUT THE CARD IMAGE WITH THE SWITCH VALUE   #
#ADDED IF DEFAULTED. THE SUBROUTINE NAMES ARE ENTERED INTO A HASH-CODED#
#TABLE USING AN INDIRECT-CHAINING SCHEME: THE HASH CODE IS AN ADDRESS  #
#IN A TABLE OF POINTERS TO DATA ENTRIES, SYNONYMS BEING CHAINED        #
#TOGETHER IN A PUSHDOWN OR LIFO STACK. THE SYMPL ROUTINE SYNHASH SETS  #
#THE BASED ARRAY TABLENTRY TO THE PROPER POSITION FOR THE NEXT ENTRY,  #
#ALLOCATING SPACE AS NECESSARY BY CALLING SYNALLOCATE.                 #
#                                                                      #
#  ERRORS DIAGNOSED: DUPLICATE ROUTINE NAMES ARE DIAGNOSED AND THE     #
#                    LATEST DEFINITION OVERRIDES.                      #
#                                                                      #
 PROC SUBRBUILD;
   BEGIN
 GETACARD:  
      SYNREAD;                 #READ CARD INTO SYNIWSA.                #
      IF SYNEOF GR 0 THEN              #STOP IF EOF ENCOUNTERED.       #
        SYNABT(2);
      IF WORD1 NQ 0 THEN           # MOVE WORDS 1,2 TO 0,1 AND IGNORE  #
        BEGIN                          # WORD 0.                       #
          INWORD[0] = INWORD[1];
          INWORD[1] = INWORD[2];
          INWORD[2] = " ";
        END 
      IF INWORD[0] EQ " " THEN #ASSUMED TO BE BLANK CARD IF 1ST TEN    #
        GOTO GETACARD;         #CHARS BLANK. BLANK CARDS ARE SKIPPED.  #
      IF INWORD[0] EQ "+" THEN     #+ SIGN MEANS END OF SUBROUTINE     #
        RETURN;                #NAME LIST INPUT.                       #
      NAME[0] = INWORD[0];
      NAME[1] = C<0,2>INWORD[1];
      IF NAME[1] EQ " " THEN   #SYMBOLLENGTH IS 1 WORD IF LESS THAN 11 #
        SYMBOLLENGTH = 1;      #CHARS IN THE ROUTINE NAME.             #
      ELSE SYMBOLLENGTH = 2;
      CTEMP = C<7,3>INWORD[1];
      IF CTEMP EQ " " THEN
        BEGIN                  #IF THE USER DEFAULTS THE SWITCH VECTOR #
          ITEMP = COUNTER;     #INDEX FOR A SUBROUTINE NAME, HE GETS   #
          COUNTER = COUNTER + 1;#VALUES ASSIGNED IN THE ORDER THE NAMES#
        END                    #ARE READ BY SYNGEN.                    #
      ELSE                     #ELSE THE VALUE GIVEN BY THE USER IS    #
        DISPLAYTOBIN;          #CONVERTED TO BINARY.                   #
      SYMBOLVALUE = ITEMP;     #STORE VALUE OF SUBR NAME.              #
      SYNHASH;                 #INSERT THE SUBROUTINE NAME AND SWITCH  #
                               #INDEX INTO THE SYMBOL TABLE.           #
      IF ERRORFLAG EQ 2 THEN   #ERROR MEANS HASH ROUTINE FOUND A DUPLI-#
        BEGIN                  #CATE SUBROUTINE NAME.                  #
          DUPELABEL[1] = NAME[0]; 
          DUPELABEL[2] = NAME[1]; 
          SCALL CHKLINO;
          SYNORL = 77;
          SYNPRNT(DUPELABELMSG);#PRINT OUT DIAGNOSTIC MESSAGE.         #
          CHKERRCNT;
        END 
      GOTO GETACARD;           #LOOP TO GET NEXT INPUT CARD.           #
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          SYNHASH                                     #
#                                                                      #
#PROC WHICH MANAGES THE SYNGEN SYMBOL TABLE, PERFORMING BOTH INSERTIONS#
#AND EXTRACTIONS OF TABLE ENTRIES AS INDICATED BY THE INS$EXT FLAG. THE#
#SYMBOL TABLE IS ORGANIZED AS A HASH-CODED ENTRY TABLE WITH INDIRECT   #
#CHAINING. I.E. THE HASHED CODE PROVIDES AN INDEX INTO A FIXED-LENGTH  #
#TABLE OF POINTERS. THE POINTER SO ACCESSED IS THE HEAD OF A CHAIN OF  #
#SYMBOL TABLE ENTRIES WITH THE SAME HASHED CODE (SYNONYMS). THE CHAIN  #
#IS A SIMPLE QUEUE OR FIFO LIST, WITH THE SPACE FOR EACH CHAIN ENTRY   #
#ALLOCATED WHEN IT IS ENTERED INTO THE CHAIN. CHAIN ENTRIES ARE LINKED #
#BY POINTERS.                                                          #
#  ERRORS DIAGNOSED: 1.THE ERRORFLAG IS SET IF THE SAME SYMBOL IS MUL- #
#                      TIPLY DEFINED AND THE LAST DEFINITION OVERRIDES.#
#                    2.THE ERRORFLAG IS SET IF AN EXTRACTION REQUEST   #
#                      REFERENCES AN UNDEFINED SYMBOL.                 #
#                                                                      #
 PROC SYNHASH;
   BEGIN
      ERRORFLAG = 0;           #TURN OFF ERROR FLAG.                   #
      I = NAME[0];             #FIRST WORD OF SYMBOL.                  #
      ITEMP = SYMBOLLENGTH - 2;#CHECK LENGTH OF SYMBOL IN WORDS.       #
      IF ITEMP LS 0 THEN       #IF 10 CHARS OR LESS THEN GO TO FOLDING #
        GOTO FOLD;             #CODE DIRECTLY.                         #
      IF ITEMP GR 0 THEN       #IF 21-30 CHARS FOLD IN LAST WORD.      #
        I = I + NAME[2];
      I = I + NAME[1];         #FOLD IN 2ND WORD.                      #
 FOLD:  
      ITEMP = ((B<30,30>I*2**15)*2**15) + B<0,30>I;#SHIFT I LEFT(CIRCU-#
                               #LAR) 30 BITS.                          #
      ITEMP = I + ITEMP;       #FOLD ONE LAST TIME.                    #
      RTEMP = B<30,30>ITEMP * .0019569E-48;#PACK,NORMALIZE AND MULTIPLY#
                               #BY A HASHING CONSTANT.                 #
      ITEMP = B<53,7>RTEMP;    #ONLY 9 BITS USED FOR SYNGEN HASHING, 7 #
      J = B<51,2>RTEMP;        #BITS FOR WORD INDEX AND 2 FOR THE 15-  #
                               #BIT QUADRANT OF THE WORD SO INDEXED.   #
      P<SYMBOLTABLE> = B<J*15,15>HASHENTRY[ITEMP];#PTR TO 1ST IN CHAIN.#
      I = SYMBOLLENGTH - 2;    #I = LENGTH OF SYMBOL CALLER IS QUERYING#
      IF INS$EXT EQ S"INSERT" THEN #IS THIS AN INSERTION OR AN EXTRAC- #
        GOTO INSERTION;        #TION OF A SYMBOL AND VALUE.            #
      SYMBOLVALUE = -1;        #TO BE USED ONLY IF THIS EXTRACTION RE- #
                               #QUEST IS 1ST REFERENCE TO UNDEFINED    #
                               #SYMBOL.                                #
      IF P<SYMBOLTABLE> EQ 0 THEN #IF SYMBOL IS UNDEFINED THEN INSERT A#
        BEGIN                  #REFERENCE TO THE SYMBOL.               #
          ERRORFLAG = 1;       #SET FLAG FOR UNDEFINED SYMBOL.         #
          GOTO INSERTENTRY; 
        END 
 EXTRACT:                      #SEARCH DOWN CHAIN FOR SYMBOL MATCH.    #
      IF NAME[0] EQ SNAME[0] AND #POSSIBLE MATCH IF THE 1ST WORDS OF   #
         SYMBOLTYPE EQ STYPE[0] AND #SYMBOLS MATCH AND THE LENGTHS AND #
         SYMBOLLENGTH EQ SLENGTH[0] THEN #TYPES ARE THE SAME.          #
            BEGIN 
              IF I LS 0 THEN   #MATCH FOUND IF 10 CHARS OR LESS IN LENG#
                GOTO EXTRACTMATCH;
              IF NAME[1] NQ SNAME[1] THEN #IF 2ND WORD DOES NOT MATCH  #
                GOTO EXTNOMATCH;
              IF I EQ 0 OR     #MATCH FOUND IF 20 CHARS OR LESS IN LENG#
                 NAME[2] EQ SNAME[2] THEN #OR 3RD WORD MATCHES.        #
                   GOTO EXTRACTMATCH; 
            END 
 EXTNOMATCH:  
      IF NEXTPTR[0] EQ 0 THEN  #THIS ENTRY IS THE END OF A CHAIN, AND  #
        BEGIN                  #THE SYMBOL HAS NO ENTRY IN THE SYMBOL  #
          ERRORFLAG = 1;       #TABLE, SO SET FLAG FOR UNDEFINED SYMBOL#
          GOTO ADDTOCHAIN;     #AND ENTER A REFERENCE TO THE SYMBOL AT #
        END                    #THE END OF THE SYMBOL TABLE CHAIN.     #
      P<SYMBOLTABLE> = NEXTPTR[0];#PTR TO NEXT ENTRY IN CHAIN.         #
      GOTO EXTRACT;            #GO CHECK FOR MATCH.                    #
 EXTRACTMATCH:  
      SYMBOLVALUE = SVALUE[0]; #VALUE IS RETURNED TO CALLER.           #
      IF NOT SDEFINEBIT[0] THEN #IF SYMBOL HAS NOT YET BEEN DEFINED,   #
        BEGIN                  #THEN SET ERRORFLAG TO TELL CALLER AND  #
          ERRORFLAG = 1;       #SET VALUE TO POINTER TO LAST ENTRY IN  #
          SVALUE[0] = SYNTBLEWORD + SYNTBLEPARCL + 7;# SYNTBLE WHICH   #
        END                    #REFERENCES THIS SYMBOL.                #
      RETURN;                  #RETURN TO CALLING ROUTINE.             #
 INSERTION: 
      IF P<SYMBOLTABLE> EQ 0 THEN #IF 0 THEN THIS IS 1ST USE OF THIS   #
        GOTO INSERTENTRY;      #HASH CODE.                             #
 INSERT:  
      IF NAME[0] EQ SNAME[0] AND #POSSIBLE MATCH IF FIRST WORD AND     #
        SYMBOLLENGTH EQ SLENGTH[0] THEN #LENGTHS ARE EQUAL.            #
          BEGIN 
            IF I LS 0 THEN     #MATCH IF 10 CHARS OR LESS IN LENGTH, SO#
              GOTO MULTIPLEDEF;#GO CHECK FOR POSSIBLE MULTI-DEFINITION.#
            IF NAME[1] NQ SNAME[1] THEN #IF 2ND WORD DOES NOT MATCH    #
              GOTO INSNOMATCH; #THEN SYMBOLS DO NOT MATCH.             #
            IF I EQ 0 OR       #MATCH FOUND IF 20 CHARS OR LESS IN LENG#
              NAME[2] EQ SNAME[2] THEN #OR 3RD WORD MATCHES, SO GO     #
                GOTO MULTIPLEDEF;#CHECK FOR POSSIBLE MULTI-DEFINITION. #
          END 
 INSNOMATCH:  
      IF NEXTPTR[0] EQ 0 THEN  #SYMBOL IS NOT IN CHAIN SO GO ADD IT.   #
        GOTO ADDTOCHAIN;
      P<SYMBOLTABLE> = NEXTPTR[0];#PTR TO NEXT ENTRY IN CHAIN.         #
      GOTO INSERT;             #GO CHECK FOR MATCH.                    #
 INSERTENTRY: 
                               #IF THIS IS FIRST USE OF THIS HASHED    #
                               #CODE THEN STORE POINTER TO CHAIN IN THE#
      P<SYMBOLTABLE> = SYNALLOCATE(-SYMBOLLENGTH-1);#FIXED-LENGTH TABLE#
      B<J*15,15>HASHENTRY[ITEMP] = P<SYMBOLTABLE>;#OF POINTERS.        #
      GOTO INSERTATTRIB;
 ADDTOCHAIN:  
      NEXTPTR[0] = SYNALLOCATE(-SYMBOLLENGTH-1);#ELSE PUT THIS ENTRY ON#
      P<SYMBOLTABLE> = NEXTPTR[0];#THE END OF THE CHAIN OF SYNONYMS.   #
 INSERTATTRIB:  
      NEXTPTR[0] = 0;          #MARK THIS ENTRY AS END OF CHAIN.       #
      SLENGTH[0] = SYMBOLLENGTH;#STORE THE ATTRIBUTES OF THE SYMBOL.   #
      STYPE[0] = SYMBOLTYPE;
      SNAME[0] = NAME[0]; 
 REPLACEATTR: 
      SVALUE[0] = SYMBOLVALUE;
      IF I LS 0 THEN GOTO SETDEFBIT;
      SNAME[1] = NAME[1]; 
      IF I GR 0 THEN
        SNAME[2] = NAME[2]; 
 SETDEFBIT: 
      IF INS$EXT NQ S"INSERT" THEN #RETURN TO CALLING ROUTINE IF THIS  #
        BEGIN                  #WAS A FORWARD SYMBOL REFERENCE.        #
          UNDEFSYMBOLS = UNDEFSYMBOLS + 1;#INCREMENT TALLY OF UNDEFINEE#
          SDEFINEBIT[0] = FALSE;#SYMBOLS. MARK AS UNDEFINED.           #
          SVALUE[0] = SYNTBLEWORD + SYNTBLEPARCL + 7; 
          RETURN; 
        END 
      SDEFINEBIT[0] = TRUE;    #FOR INSERTIONS, TURN ON THE DEFINITION #
      RETURN;                  #BIT AND RETURN TO CALLING ROUTINE.     #
 MULTIPLEDEF: 
      IF STYPE[0] NQ SYMBOLTYPE THEN #IF NAMES ARE SAME BUT NOT TYPES  #
        GOTO INSNOMATCH;       #IT IS NOT A MULTIPLY-DEFINED SYMBOL.   #
      IF NOT SDEFINEBIT[0] THEN      #IF NAMES AND TYPES MATCH BUT     #
        BEGIN                  #SYMBOL WAS PREVIOUSLY UNDEFINED, RETURN#
          ITEMP = SVALUE[0];   #PTR TO CHAIN OF REFERENCES IN ITEMP AND#
          SVALUE[0] = SYMBOLVALUE;#REPLACE WITH SYMBOLVALUE. MARK THE  #
          SDEFINEBIT[0] = TRUE;#SYMBOL AS DEFINED.                     #
          UNDEFSYMBOLS = UNDEFSYMBOLS - 1;#REDUCE UNDEFSYMBOL TALLY.   #
          ERRORFLAG = 3;       #FLAG INDICATES SYMBOL PREVIOUSLY UNDEF.#
          RETURN; 
        END 
      ERRORFLAG = 2;           #FOR TRUE MULTIPLE-DEFINITIONS, SET FLAG#
      GOTO REPLACEATTR;        #AND OVERRIDE PREVIOUS DEFINITION.      #
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          SYNBUILD                                    #
#                                                                      #
#ROUTINE WHICH CONSTRUCTS THE SYNTABLE (TABLE WHICH IS USED TO DRIVE   #
#THE SYNTAX ANALYSIS FOR A SYSTEM) AND THE TRACEM TABLE (TABLE WHICH IS#
#USED TO TRACE ANY PATH THROUGH THE SYNTABLE) PLUS THREE CROSS REFER-  #
#ENCE LISTS - LABELS, SUBROUTINES, AND DIAGNOSTICS.                    #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  SYNGEN"S INPUT FILE MUST BE POSITIONED TO THE THIRD SECTION CONTAIN-#
#  ING THE SYNTAX SPECIFICATIONS, THE SUBROUTINE NAMES MUST HAVE BEEN  #
#  ENTERED INTO THE SYMBOL TABLE AND THE LEXICON TABLES MUST HAVE BEEN #
#  BUILT.                                                              #
#                                                                      #
#EXTERNAL REFERENCES:                                                  #
#  SYNSCAN - CODE WHICH IDENTIFIES SYNTAX ENTRIES IN THE INPUT CARD.   #
#  SYNHASH - PROC WHICH ENTERS OR RETRIEVES INFO FROM THE SYMBOL TABLE.#
#  SYNALLOCATE - PROC WHICH ALLOCATES SPACE WITHIN A JOB"S FIELDLENGTH.#
#  SYNPRNT - ROUTINE WHICH PRINTS AN OUTPUT LINE.                      #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#  SYNTABLE, TRACEM, AND THE THREE CROSS REFERENCE LIST ARE BUILT AND  #
#  SYNGEN"S INPUT FILE IS POSITIONED AT EOF.                           #
#                                                                      #
#ERROR CONDITIONS:                                                     #
#  UNDEFINED LABEL REFERENCE BY THE USER"S SYNTAX SPECIFICATIONS.      #
#  UNDEFINED SUBLABEL REFERENCE BY THE USER"S SYNTAX SPECIFICATIONS.   #
 PROC SYNBUILD; 
   BEGIN
      P<SUBLABELPTRS> = SYNALLOCATE(100);#ALLOCATE SPACE FOR SAVING    #
                               #PTRS TO SUBLABELS IN A SYNTBLE SECTION.#
      FOR I=0 STEP 1 UNTIL 99 DO #INITIALIZE SUBLABEL POINTERS TO ZERO.#
        SUBLABELPTR[I] = 0; 
      P<LABELPTRS> = P<SUBLABELPTRS>+100;#LABELPTRS ARRAY SPACE WILL BE#
                               #ALLOCATED AS NEEDED.                   #
      LASTRANSFER = 0;         #INITIALIZE ALL POINTERS AND COUNTERS.  #
      COUNTER = 0;             #INITIALIZE CODE LINE COUNTER.          #
      LABELCOUNTER = 0; 
      SYNTBLEPARCL = 0; 
      CURRENTLABEL[0] = 0;
      FIRSTCHAR = 0;           #INIT SCAN FLAG FOR DELIMITERS AND      #
                               #COMMENTS.                              #
      IF TFLAG NQ 0 THEN       #IF A TRACEM ARRAY IS REQUESTED, THEN   #
        BEGIN                  #WRITE THE ARRAY ITEM DESCRIPTION TO THE#
          TRACEWSAWD[0] = "   ITEM TR";#FILE.                          #
          TRACEWSAWD[1] = "ACEINSTR C"; 
          TRACEWSAWD[2] = "(,,10) = ["; 
          TRACEWSAWD[3] = "          "; 
          TRACEWSAWD[4] = "          "; 
          TRACEWSAWD[5] = "          "; 
          TRACEW; 
          TRACEWSAWD[0] = "          ";#RESET 1ST WORD OF THE WSA TO A #
        END                            #BLANK.                         #
      SCRATCHWD[0] = " ARRAY SYN";
      SCRATCHWD[1] = "TBLE[     ";
      SCRATCHWD[2] = "];        ";
      SCRATCHWD[3] = " "; 
      SCRATCHWD[4] = " "; 
      SCRATCHWD[5] = " "; 
      SYNTBLW(SCRATCH,SYNTBLEWORD); 
      SYNTBLEWORD = SYNTBLEWORD + 6;
      SCRATCHWD[0] = "   ITEM SY";
      SCRATCHWD[1] = "NWORD U =[";
      SCRATCHWD[2] = " "; 
      SYNTBLW(SCRATCH,SYNTBLEWORD); 
      SYNTBLEWORD = SYNTBLEWORD + 6;
      GOTO SYNSCAN;            #CALL SYNSCAN PROCEDURE TO CRACK INPUT  #
                               #AND GIVE CONTROL TO PROPER SYNTACTIC   #
                               #ROUTINE.                               #
#**********************************************************************#
 DRIVERREQ:                    #DRIVER REQUESTS AND KEYWORD CALLS.     #
 ENCODE:  
      ITEMP = SYNSTRUCTION;    #CONVERT INSTRUCTION TO DISPLAY-CODED   #
      BINTODISPOCT;            #OCTAL, LEFT-JUSTIFIED BLANK-FILLED.    #
      SYNSTRUCTION = (B<30,30>OCTAL[1]*2**15)*2**15 + O"5555555555";
 STORECODE: 
      IF TFLAG NQ 0 THEN       #IF TRACEM REQUESTED AND THIS INSTRUC-  #
        IF FIRSTSUBLABL EQ 1 THEN #TION ISN"T 1ST SUBLABEL DEFINED IN  #
           BEGIN               #SECTION, THEN MAKE ENTRY IN THE CURRENT#
             B<6,42>TRACESKEL = B<0,42>DISPLAYINSTR;# TRACEM RECORD.   #
             TRACEWSAWD[1+SYNTBLEPARCL] = TRACESKEL;
           END
        ELSE FIRSTSUBLABL = 1; #SET FLAG SO NEXT INSTRUCTION GETS OUT. #
      C<0,7>INSTRUCTCOM[SYNTBLEPARCL+1]=DISPLAYINSTR;#COMMENT FOR CODE.#
      PRESETI[1+SYNTBLEPARCL] = SYNSTRUCTION;#STORE CODED INSTRUCTION. #
      IF SYNTBLEPARCL GR 2 THEN #IF FULL SYNTBLE WORD BUILT THEN WRITE #
        BEGIN                  #THE RECORD TO FILE AND SET POINTERS TO #
          SYNTBLEPARCL = 0;    #NEXT WORD AND PARCEL.                  #
          ITEMP = COUNTER;     #CONVERT CODE LINE COUNTER TO OCTAL DIS-#
          BINTODISPOCT;        #PLAY CODE AND STORE IN COMMENT LINE.   #
          B<24,30>INSTRUCTCOM[0] = B<30,30>OCTAL[1];
          SYNTBLW(INSTRCOMMENT,SYNTBLEWORD);#WRITE OUT COMMENT LINE.   #
          SYNTBLEWORD = SYNTBLEWORD + 6;
          SYNTBLW(PRESETCODE,SYNTBLEWORD);
          COUNTER = COUNTER + 1;#INCREMENT CODE LINE COUNTER.          #
          SECTIONWORD = SECTIONWORD + 1;
          SYNTBLEWORD = SYNTBLEWORD + 6;
          IF TFLAG NQ 0 THEN   #WRITE OUT RECORD TO TRACEM FILE.       #
            TRACEW; 
          GOTO SYNSCAN;        #GET NEXT INPUT ELEMENT.                #
        END 
      SYNTBLEPARCL = SYNTBLEPARCL + 1;#SET POINTER TO NEXT PARCEL.     #
      GOTO SYNSCAN;            #GET NEXT INPUT ELEMENT.                #
#**********************************************************************#
 LABELS:  
      IF NAME[0] EQ CURRENTLABEL[0] AND  #IF "NEW" LABEL IS SAME AS THE#
         NAME[1] EQ CURRENTLABEL[1] AND  #CURRENT LABEL, IT IS OPTIONAL#
         NAME[2] EQ CURRENTLABEL[2] THEN #BOOKKEEPING DEVICE, SO IT IS #
           GOTO SYNSCAN;       #IGNORED AND NEXT INPUT ELEMENT REQUESTD#
      IF TFLAG NQ 0 THEN       #IF TRACEM BEING BUILT THEN SET FLAG TO #
        BEGIN                  #INDICATE NEW SYNTBLE SECTION BEING     #
          IF SYNTBLEPARCL NQ 0 THEN #STARTED.                          #
            BEGIN 
              FOR I=SYNTBLEPARCL+1 STEP 1 UNTIL 4 DO #FILL OUT TRACEM  #
                TRACEWSAWD[I] = """NO CODE"",";#RECORD WITH THAT WHICH #
              TRACEW;          #SHOULD NEVER SHOW UP ON A TRACE.       #
            END 
          FIRSTSUBLABL = -1;   #FLAG FOR START OF NEW LABELLED SECTION.#
          C<1,1>TRACESKEL = ":";       # ADD : TO A LABEL AND STORE IT #
          B<12,36>TRACESKEL = B<0,36>DISPLAYINSTR;# INTO A TRACEM ENTRY#
          TRACEWSAWD[1] = TRACESKEL;   #TRACEM ENTRY.                  #
        END 
      IF SYNTBLEPARCL EQ 0 THEN #IF NOT ALREADY POSITIONED AT INSTRUC- #
        GOTO WRITELABLCOM;     #TION WORD BOUNDARY, THEN FILL OUT CUR- #
      FOR I=SYNTBLEPARCL+1 STEP 1 UNTIL 4 DO #RENT SYNTBLE WORD AND    #
        BEGIN                  #WRITE OUT COMMENT AND CODE PRESET      #
          PRESET[I] = "00000"; #RECORDS.                               #
          INSTRUCTCOM[I] = " "; 
        END 
      ITEMP = COUNTER;         #CONVERT CODE LINE NUMBER TO DISPLAY-   #
      BINTODISPOCT;            #CODED OCTAL AND STORE IN COMMENT LINE. #
      B<24,30>INSTRUCTCOM[0] = B<30,30>OCTAL[1];
      SYNTBLW(INSTRCOMMENT,SYNTBLEWORD);
      SYNTBLEWORD = SYNTBLEWORD + 6;
      SYNTBLW(PRESETCODE,SYNTBLEWORD);
      SYNTBLEWORD = SYNTBLEWORD + 6;#INCREMENT POINTERS.               #
      SYNTBLEPARCL = 0; 
      COUNTER = COUNTER + 1;
 WRITELABLCOM:                 #BUILD COMMENT CARD FOR NEW LABEL.      #
      B<24,36>LABELCOMWORD[0] = B<0,36>NAME[0]; 
      B<24,36>LABELCOMWORD[1] = B<0,36>NAME[1]; 
      B<24,36>LABELCOMWORD[2] = B<0,36>NAME[2]; 
      B<0,24>LABELCOMWORD[1] = B<36,24>NAME[0]; 
      B<0,24>LABELCOMWORD[2] = B<36,24>NAME[1]; 
      B<0,24>LABELCOMWORD[3] = B<36,24>NAME[2]; 
      SYNTBLW(LABELCOMMENT,SYNTBLEWORD);#WRITE OUT LABEL COMMENT LINE. #
      SYNTBLEWORD = SYNTBLEWORD + 6;
      P<LABELENTRY> = SYNALLOCATE(6);#ALLOCATE ANOTHER ENTRY IN THE    #
                               #LABELPTRS TABLE.                       #
      LABELCOUNTER = LABELCOUNTER + 1;#INCREMENT LABEL TALLY.          #
      SYMBOLVALUE = LABELCOUNTER;#ENTRY POSITION IN LABELPTRS TABLE IS #
                               #THE DEFINED VALUE OF THE SYMBOL.       #
      SECTIONWORD = 0;         #1ST WORD OF NEW LABELLED SECTION.      #
      LABELNAME[1] = NAME[0];  #STORE LABEL IN COMMENT PORTION OF THE  #
      LABELNAME[2] = NAME[1];  #LABELPTRS ARRAY ENTRY.                 #
      LABELNAME[3] = NAME[2]; 
      ITEMP = COUNTER;         #CONVERT RELATIVE WORD POSITION IN THE  #
      BINTODISPDEC;            #SYNTBLE TO DISPLAY CODE AND STORE INTO #
      LABELPRESET[0] = CTEMP;  #THE PRESET PORTION OF THE LABELPTRS    #
                               #ARRAY ENTRY.                           #
      LABELNAME[0] = "       #  ";#STORE COMMENT SYMBOLS INTO THE      #
      LABELNAME[4] = "  #,      ";#LABELPTRS ARRAY ENTRY.              #
      SYMBOLTYPE = "L"; 
      INS$EXT = S"INSERT";
      SYNHASH;                 #ENTER SYMBOL DEFINITION IN SYMBOL TABLE#
      K = ITEMP;               #SAVE PTR TO CHAIN OF REFERENCES.       #
      ITEMP = O"24000" + LABELCOUNTER;#BUILD INSTRUCTION CALLING NEWLY-#
      BINTODISPOCT;            #DEFINED LABEL.                         #
      SYNSTRUCTION = (B<30,30>OCTAL[1]*2**15)*2**15 + O"5555555555";
      IF ERRORFLAG EQ 3 THEN   #IF LABEL PREVIOUSLY UNDEFINED, REPLACE #
        WALKCHAIN;             #CHAIN ENTRIES WITH  LABEL CALL.        #
      ELSE IF ERRORFLAG EQ 2 THEN #IF LABEL IS A DUPLICATE, STORE LABEL#
        BEGIN                  #IN MESSAGE AND CALL SYNPRNT TO PRINT IT#
          DUPELABEL[1] = NAME[0];#ON THE SYSTEM OUTPUT FILE.           #
          DUPELABEL[2] = NAME[1]; 
          DUPELABEL[3] = NAME[2]; 
          DUPELABEL[4] = "    DOUBLY";
          SCALL CHKLINO;
          SYNORL = 77;
          SYNPRNT(DUPELABELMSG);
          CHKERRCNT;
        END 
      FOR I=0 STEP 1 UNTIL 99 DO #REINITIALIZE SUBLABELPTRS TO ZERO,   #
        BEGIN                  #CHECKING FOR UNDEFINED SUBLABEL REFER- #
          IF SUBLABELPTR[I] NQ 0 AND #ENCES. PUT OUT DIAGNOSTIC IF UN- #
             SUBLABELPTR[I] GR 0 THEN #DEFINED SUBLABEL FOUND.         #
               BEGIN
                 UNDEFMESS[1] = CURRENTLABEL[0];
                 UNDEFMESS[2] = CURRENTLABEL[1];
                 UNDEFMESS[3] = CURRENTLABEL[2];
                 ITEMP = I; 
                 BINTODISPDEC;
                 B<0,6>UNDEFMESS[4] = ":";
                 B<6,12>UNDEFMESS[4] = B<18,12>CTEMP; 
                 UNDEFMESS[5] = "NED SUBLAB"; 
                 UNDEFMESS[6] = "EL.       "; 
                 SCALL CHKLINO; 
                 SYNORL = 65; 
                 SYNPRNT(UNDEFMESSAGE); 
                 CHKERRCNT; 
                 UNDEFMESS[4] = "    UNDEFI";#RESTORE BLANKS.          #
                 K = SUBLABELPTR[I];#REPLACE CHAIN OF REFERENCE PTRS   #
                 SYNSTRUCTION = "03777     "; 
                 WALKCHAIN; 
               END
          SUBLABELPTR[I] = 0; 
        END 
      IF LFLAG NQ 0 THEN       #IF THE LFLAG IS SET THEN CROSS REFER-  #
        BEGIN                  #ENCE INFORMATION MUST BE KEPT.         #
          CURNTLABLPTR = P<SYMBOLTABLE>;#KEEP PTR TO SYMBOL TABLE ENTRY#
        END                    #FOR THE CURRENT LABEL.                 #
      CURRENTLABEL[0] = NAME[0];#SAVE LABEL OF SYNTBLE SECTION THAT IS #
      CURRENTLABEL[1] = NAME[1];#CURRENTLY BEING CONSTRUCTED.          #
      CURRENTLABEL[2] = NAME[2];
      IF LASTRANSFER NQ 0 THEN #STORE A CALL TO THE NEW LABEL AT THE   #
        BEGIN                  #LAST / OR :SUBLABEL.                   #
          SYNTBLR(SCRATCH,LASTRANSFER);#FETCH THE WORD FROM SYNTBLE.   #
          SCRATCHWD[0] = "00000     "; #STORE A NO-OP AT LASTRANSFER.  #
          SYNTBLW(SCRATCH,LASTRANSFER);#STORE UPDATED WORD BACK.       #
          LASTRANSFER = 0;     #INITIALIZE TO ZERO FOR A NEW LABELLED  #
        END                    #SECTION.                               #
      GOTO SYNSCAN;            #GET NEXT SOURCE ELEMENT.               #
#**********************************************************************#
 SUBLABELS: 
      IF TFLAG NQ 0 THEN       #IF TRACEM REQUESTED THEN SET FLAG TO   #
        BEGIN                  #INDICATE WHETHER THIS IS 1ST SUBLABEL  #
          IF FIRSTSUBLABL LS 0 THEN #IN THE CURRENT LABELLED SECTION.  #
            FIRSTSUBLABL = 0; 
        END 
      IF B<0,1>SUBLABELPTR[SUBLABEL] EQ 1 THEN #IF THE SIGN-BIT IN THE #
        BEGIN                  #ENTRY IS ALREADY SET THEN THIS SUBLABEL#
          DUPELABEL[1] = CURRENTLABEL[0];#IS DOUBLY-DEFINED.           #
          DUPELABEL[2] = CURRENTLABEL[1]; 
          DUPELABEL[3] = CURRENTLABEL[2]; 
          ITEMP = SUBLABEL; 
          BINTODISPDEC; 
          C<0,1>DUPELABEL[4] = ":"; 
          B<6,12>DUPELABEL[4] = B<18,12>CTEMP;
          SCALL CHKLINO;
          SYNORL = 77;
          SYNPRNT(DUPELABELMSG);
          CHKERRCNT;
          DUPELABEL[4] = "    DOUBLY";
        END 
      ELSE
        IF SUBLABELPTR[SUBLABEL] GR 0 THEN #IF THE VALUE IS POSITIVE,  #
          BEGIN                #IT REPRESENTS A PTR TO THE HEAD OF A   #
            K = SUBLABELPTR[SUBLABEL];#CHAIN OF REFERENCES TO BE SATIS-#
            ITEMP = O"40000" + SYNTBLEPARCL*2**11 + SECTIONWORD;#FIED. #
            BINTODISPOCT; 
            SYNSTRUCTION = (B<30,30>OCTAL[1]*2**15)*2**15 + 
                                                          O"5555555555";
            WALKCHAIN;
          END 
      SUBLABELPTR[SUBLABEL] = -(SYNTBLEPARCL*2**11 + SECTIONWORD);
      CURNTSUBLABL = C<1,2>DISPLAYINSTR;
#**********************************************************************#
 SLASH: 
      IF LASTRANSFER NQ 0 THEN
        BEGIN 
          ITEMP = O"60000" + SECTIONWORD + SYNTBLEPARCL*2**11;
          BINTODISPOCT; 
          ITEMP = SYNTBLEWORD + SYNTBLEPARCL + 7; 
          I = (B<30,30>OCTAL[1]*2**15)*2**15 + O"5555555555"; 
          IF ITEMP-LASTRANSFER LS 4 THEN #IF THE LAST TRANSFER POINT IS#
            BEGIN              #IN THE CURRENT RECORD OF THE SYNTBLE   #
              PRESETI[LASTRANSFER-SYNTBLEWORD-6] = I;#FILE, THEN DON"T #
              GOTO UPDATETRANSF;#GET THE RECORD, SIMPLY STORE IN THE   #
            END                #WSA CURRENTLY BEING FILLED.            #
          SYNTBLR(SCRATCH,LASTRANSFER);#ELSE GET THE WORD FROM THE FILE#
          B<0,60>SCRATCHWD[0] = I;
          SYNTBLW(SCRATCH,LASTRANSFER); 
        END 
 UPDATETRANSF:  
      LASTRANSFER = SYNTBLEWORD + SYNTBLEPARCL + 7;#UPDATE LAST TRANS- #
                               #FER POINTER.                           #
      SYNSTRUCTION = 0;        #STORE A ZERO IN THE CURRENT PARCEL OF  #
      GOTO STORECODE;          #SYNTBLE, TEMPORARILY.                  #
#**********************************************************************#
 LABELCALL: 
      INS$EXT = S"EXTRACT";    #SET UP CALL TO SYNHASH REQUESTING LABEL#
      SYMBOLTYPE = "L";        #POSTION IN LABELPTRS TABLE.            #
      SYNHASH;
      IF LFLAG NQ 0 THEN       #LFLAG MEANS CROSS REFERENCE INFO IS    #
        BEGIN                  #REQUIRED. CROSS REFERENCE RECORD HAS   #
          LXREFWSA = P<SYMBOLTABLE>;#PTR TO SYMBOLTABLE ENTRY FOR LABEL#
          B<12,12>LXREFWSA = "  ";#NO SUBLABEL FOR LABEL DEFINITION.   #
 COMPLETEXREF:  
          B<0,12>LXREFWSA = CURNTSUBLABL; #REFENCED,POINTER TO ENTRY OF#
          B<24,18>LXREFWSA = CURNTLABLPTR;#CURRENT LABEL, AND DISPLAY- #
          LXREFW;              #CODED SUBLABEL THAT IS CURRENT.        #
        END 
 STORECALL: 
      IF ERRORFLAG EQ 0 THEN   #FLAG MEANING CALLED LABEL IS DEFINED SO#
        BEGIN                  #INSTRUCTION CAN BE BUILT.              #
          SYNSTRUCTION = SYNSTRUCTION + SYMBOLVALUE;
          GOTO ENCODE;
        END 
      SYNSTRUCTION = SYMBOLVALUE;#ELSE PUT OUT A POINTER TO LAST PRE-  #
      GOTO STORECODE;          #VIOUS REFERENCEE TO LABEL.             #
#**********************************************************************#
 SUBLABELCALL:  
      SYMBOLVALUE = SUBLABELPTR[SUBLABEL];#EITHER VALUE OR POINTER.    #
      IF B<0,1>SYMBOLVALUE EQ 1 THEN #LS 0 MEANS SUBLABEL HAS BEEN     #
        BEGIN                  # DEFINED ALREADY.                      #
          ERRORFLAG = 0;
          SYMBOLVALUE = -SYMBOLVALUE; 
        END 
      ELSE                     #GQ 0 MEANS SUBLABEL IS UNDEFINED.      #
        BEGIN 
          ERRORFLAG = 1;
          IF SYMBOLVALUE EQ 0 THEN #EQ 0 MEANS SUBLABEL NOT PREVIOUSLY #
            SYMBOLVALUE = -1;  #REFERENCED, SO -1 FLAGS END OF CHAIN OF#
          SUBLABELPTR[SUBLABEL] = SYNTBLEWORD + SYNTBLEPARCL + 7; 
        END                    #REFERENCES. SAVE WORD ADDRESS OF LAST  #
                               #REFERENCE IN SUBLABELPTRS TABLE ENTRY. #
      IF LFLAG NQ 0 THEN       #CROSS REFERENCE INFO IS REQUIRED, CON- #
        BEGIN                  #TAINING PTR TO CURRENT LABEL ENTRY IN  #
          LXREFWSA = CURNTLABLPTR;#SYMBOL TABLE, SUBLABEL CALLED, ETC. #
          B<12,12>LXREFWSA = B<0,12>DISPLAYINSTR; 
          GOTO COMPLETEXREF;
        END 
      GOTO STORECALL; 
#**********************************************************************#
 SUBROUTINE:  
      INS$EXT = S"EXTRACT";    #SET UP CALL TO SYNHASH REQUESTING SUB- #
      SYMBOLTYPE = "S";        #ROUTINE"S SWITCH VECTOR POSITION.      #
      SYNHASH;
      IF LFLAG NQ 0 THEN       #CROSS REFERENCE INFO REQUIRED INCLUDES #
        BEGIN                  #PTRS TO SYMBOL TABLE ENTRIES FOR SUB-  #
          SXREFWSA = P<SYMBOLTABLE>;#ROUTINE AND CURRENT LABEL AND DIS-#
          B<0,12>SXREFWSA = CURNTSUBLABL;#PLAY-CODED SUBLABEL.         #
          B<24,18>SXREFWSA = CURNTLABLPTR;
          SXREFW;              #WRITE OUT XREF INFO.                   #
        END 
      IF ERRORFLAG NQ 0 THEN   #SUBROUTINE WAS NOT DEFINED BY USER TO  #
        BEGIN                  #SUBRBUILD.                             #
          UNDEFMESS[1] = NAME[0]; 
          UNDEFMESS[2] = NAME[1]; 
          UNDEFMESS[3] = NAME[2]; 
          C<4,6>UNDEFMESS[5] = "SUBROU";
          UNDEFMESS[6] = "TINE."; 
          SCALL CHKLINO;
          SYNORL = 65;
          SYNPRNT(UNDEFMESSAGE);
          CHKERRCNT;
  
          SYNSTRUCTION = SYNSTRUCTION + O"3777";#TO GENERATE A MODE 1  #
        END                    #ERROR BY STD IF EXECUTED.              #
      ELSE SYNSTRUCTION = SYNSTRUCTION + SYMBOLVALUE; 
      GOTO ENCODE;
#**********************************************************************#
 DIAGNOSTIC:  
      IF LFLAG NQ 0 THEN       #CROSS REFERENCE INFO INCLUDES DISPLAY- #
        BEGIN                  #CODED DIAGNOSTIC AND SUBLABEL AND PTR  #
          B<0,10>DXREFWSA = B<50,10>SYNSTRUCTION; # TO THE CURRENT     #
          B<12,18>DXREFWSA = B<6,18>DISPLAYINSTR; # SYNTBLE LABEL"S    #
          B<42,18>DXREFWSA = CURNTLABLPTR;#ENTRY IN SYMBOL TABLE.      #
          B<30,12>DXREFWSA = B<0,12>CURNTSUBLABL; 
          DXREFW;              #WRITE OUT XREF INFO                    #
        END 
      GOTO ENCODE;
#**********************************************************************#
 INPUTEOF:                     #ALL USER SPECS HAVE BEEN READ FROM FILE#
      ENDINP;        # FIX UP LISTING AND REWIND XREF FILES  #
      IF UNDEFSYMBOLS NQ 0 OR  #FOR EACH UNDEFINED LABEL AND SEMANTIC  #
         LFLAG NQ 0 THEN       #SUBROUTINE NAME IN THE SOURCE, PRINT   #
        BEGIN                  #OUT DIAGNOSTICS AND REPLACE SYNTBLE    #
          SYNSTRUCTION = "03777     ";#CODE REFERENCING THEM WITH AN   #
          FOR ITEMP=0 STEP 1 UNTIL 3 DO #INSTRUCTION DESIGNED TO GENER-#
            BEGIN              #ATE A MODE 1 ERROR IF STD ATTEMPTS TO  #
              J = ITEMP * 15;  #EXECUTE IT.                            #
              FOR I=0 STEP 1 UNTIL 127 DO 
               BEGIN
                  P<SYMBOLTABLE> = B<J,15>HASHENTRY[I]; 
 CHKCHAINEND:     IF P<SYMBOLTABLE> EQ 0 THEN 
                    TEST I; 
                  N = SLENGTH[0] - 1; 
                  IF NOT  SDEFINEBIT[0] THEN #UNDEFINED SYMBOL ENTRY.  #
                    BEGIN 
                      IF STYPE[0] EQ O"23" THEN #IF UNDEFINED SUBRTN,  #
                        GOTO DECUNDEFCNT;#IT HAS ALREADY BEEN TAKEN    #
                               # CARE OF.                              #
                      UNDEFMESS[1] = SNAME[0];
                      IF N GR 0 THEN
                        BEGIN 
                          UNDEFMESS[2] = SNAME[1];
                          IF N GR 1 THEN
                            UNDEFMESS[3] = SNAME[2];
                          ELSE UNDEFMESS[3] = " ";
                        END 
                      ELSE UNDEFMESS[2] = " ";
                      UNDEFMESS[5] = "NED LABEL.";
                      SCALL CHKLINO;
                      SYNORL = 60;
                      SYNPRNT(UNDEFMESSAGE);#PRINT OUT DIAGNOSTIC.     #
                      CHKERRCNT;
                      K = SVALUE[0];
                      WALKCHAIN;#REPLACE CALLS TO UNDEFINED SYMBOL.    #
 DECUNDEFCNT:         UNDEFSYMBOLS = UNDEFSYMBOLS - 1;
                      IF UNDEFSYMBOLS EQ 0 AND LFLAG EQ 0 THEN
                        GOTO PUTLABELPTRS;
                    END 
                  IF LFLAG NQ 0 THEN
                    FOR M=54 STEP -6 WHILE
                      B<M,6>SNAME[N] EQ O"55" DO
                        B<M,6>SNAME[N] = 0; 
                  P<SYMBOLTABLE> = NEXTPTR[0];#NEXT ENTRY IN CHAIN OF  #
                  GOTO CHKCHAINEND;           #SYNONYMS.               #
                END 
            END 
        END 
 PUTLABELPTRS:  
      FOR I=0 STEP 1 UNTIL 99 DO #CHECK ANY UNDEFINED SUBLABELS IN THE #
        BEGIN                  #LAST LABELLED SECTION OF THE TABLE.    #
          IF SUBLABELPTR[I] GR 0 THEN 
            BEGIN 
              UNDEFMESS[1] = CURRENTLABEL[0]; 
              UNDEFMESS[2] = CURRENTLABEL[1]; 
              UNDEFMESS[3] = CURRENTLABEL[2]; 
              ITEMP = I;
              BINTODISPDEC; 
              C<0,1>UNDEFMESS[4] = ":"; 
              B<6,12>UNDEFMESS[4] = B<18,12>CTEMP;
              UNDEFMESS[5] = "NED SUBLAB";
              UNDEFMESS[6] = "EL.       ";
              SCALL CHKLINO;
              SYNORL = 65;
              SYNPRNT(UNDEFMESSAGE);
              CHKERRCNT;
              UNDEFMESS[4] = "    UNDEFI";#RESTORE BLANKS.             #
              K = SUBLABELPTR[I]; 
              SYNSTRUCTION = "03777     ";
              WALKCHAIN;
            END 
        END 
      SYNCOM(PROCNAME); 
      SYNCOM("    BEGIN 
  "); 
      IF NOT PTC THEN 
      SYNCOM("      XDEF BEGIN
  "); 
      ITEMP = LABELCOUNTER;    #WRITE OUT LABELPTRS ARRAY AS PRESET,   #
      BINTODISPDEC;            #WITH ARRAY DECLARATION INFO IN FIRST 2 #
      B<0,30>LABELPTRHDR[2] = B<0,30>CTEMP;    #RECORDS.               #
      SYNCOM(LABELPTRHEDR); 
      SYNCOM(LABELPTRITEM); 
      FOR I=1 STEP 1 UNTIL LABELCOUNTER DO #WRITE OUT LBLPTRS ARRAY BY #
        BEGIN                  #LOOPING.                               #
          SYNCOM(LABELPTRS);
          P<LABELPTRS> = P<LABELPTRS> + 6;
        END 
      SYNCOM(LABELPTRTAIL);    #WRITE OUT ARRAY TERMINATION CHARS.     #
      IF LASTRANSFER NQ 0 THEN #STORE AN INSTRUCTION IN THE LAST / OF  #
        BEGIN                  #OF THE TABLE WHICH WILL BE A NO-OP.    #
          IF SYNTBLEWORD+SYNTBLEPARCL+7-LASTRANSFER LS 4 THEN 
            B<0,60>PRESETI[LASTRANSFER-SYNTBLEWORD-6] = "00000     "; 
          ELSE
            BEGIN 
              SYNTBLR(SCRATCH,LASTRANSFER); 
              SCRATCHWD[0] = "00000     ";
              SYNTBLW(SCRATCH,LASTRANSFER); 
            END 
        END 
      ITEMP = COUNTER;
      IF SYNTBLEPARCL NQ 0 THEN #WRITE OUT REMAINING PART-WORD OF CODE,#
        BEGIN                  #IF ANY.                                #
          FOR I=SYNTBLEPARCL+1 STEP 1 UNTIL 4 DO
            BEGIN 
              PRESET[I] = "00000";
              INSTRUCTCOM[I] = " "; 
            END 
          BINTODISPOCT;        #WORD COUNT IN OCTAL GOES INTO COMMENT. #
          B<24,30>INSTRUCTCOM[0] = B<30,30>OCTAL[1];
          SYNTBLW(INSTRCOMMENT,SYNTBLEWORD);
          SYNTBLEWORD = SYNTBLEWORD + 6;
          SYNTBLW(PRESETCODE,SYNTBLEWORD);
          SYNTBLEWORD = SYNTBLEWORD + 6;
        END 
      SYNTBLW(LABELPTRTAIL,SYNTBLEWORD);#WRITE OUT SYNTBLE ARRAY TERM. #
      SYNTBLEWORD = SYNTBLEWORD + 6;
      BINTODISPDEC;            #STORE ARRAY SIZE IN ARRAY PRESET       #
      SYNTBLR(SCRATCH,1);      #DECLARATION.                           #
      B<30,30>SCRATCHWD[1] = B<0,30>CTEMP;
      SYNTBLW(SCRATCH,1);      #WRITE OUT WORD CONTAINING ARRAY SIZE.  #
      IF TFLAG NQ 0 THEN       #IF TRACEM REQUESTED, WRITE OUT ARRAY   #
        BEGIN                  #TERMINATOR AND STORE ARRAY SIZE INTO   #
          IF SYNTBLEPARCL NQ 0 THEN #ARRAY DECLARATION AND SAVE IN THE #
            BEGIN              #WSA FOR THE INPUT FILE.                #
              FOR I=SYNTBLEPARCL+1 STEP 1 UNTIL 4 DO
                TRACEWSAWD[I] = """NO CODE"","; 
              TRACEW; 
            END 
          FOR I=0 STEP 1 UNTIL 5 DO 
            TRACEWSAWD[I] = TRACEMTAILWD[I];
          TRACEW; 
          ITEMP = COUNTER*4 + 3;
          BINTODISPDEC; 
          B<30,30>TRACEMHDRWD[1] = B<0,30>CTEMP;
          FOR I=0 STEP 1 UNTIL 6 DO 
            INWORD[I] = TRACEMHDRWD[I]; 
        END 
      RETURN;                  #RETURN CONTROL TO SYNCTRL.             #
CONTROL EJECT;
      SWITCH SYNTAXSWCH                #                               #
        SCOLON,           #:#          #                               #
        LET,              #A#          #                               #
        LET,              #B#          #                               #
        LET,              #C#          #                               #
        SD,               #D#          #                               #
        SE,               #E#          #                               #
        LET,              #F#          #                               #
        LET,              #G#          #                               #
        LET,              #H#          #                               #
        LET,              #I#          #                               #
        LET,              #J#          #                               #
        LET,              #K#          #                               #
        LET,              #L#          #                               #
        LET,              #M#          #                               #
        SN,               #N#          #                               #
        SO,               #O#          #                               #
        LET,              #P#          #                               #
        LET,              #Q#          #                               #
        LET,              #R#          #                               #
        SS,               #S#          #                               #
        LET,              #T#          #                               #
        LET,              #U#          #                               #
        LET,              #V#          #                               #
        LET,              #W#          #                               #
        LET,              #X#          #                               #
        SY,               #Y#          #                               #
        LET,              #Z#          #                               #
        DGT,              #0#          #                               #
        DGT,              #1#          #                               #
        DGT,              #2#          #                               #
        DGT,              #3#          #                               #
        DGT,              #4#          #                               #
        DGT,              #5#          #                               #
        DGT,              #6#          #                               #
        DGT,              #7#          #                               #
        DGT,              #8#          #                               #
        DGT,              #9#          #                               #
        SPLUS,            #+#          #                               #
        SMINUS,           #-#          #                               #
        SASK,             #*#          #                               #
        SSLASH,           #/#          #                               #
        SSPC,             #(#          #                               #
        SSPC,             #)#          #                               #
        SDSIGN,           #$#          #                               #
        SSPC,             #=#          #                               #
        SDELIM,           # #          #                               #
        SCOMMA,           #,#          #                               #003940
        SSPC,             #.#          #                               #
        SCOMMENT,       #EQUIV#        #                               #
        SSPC,             #[#          #                               #
        SSPC,             #]#          #                               #
        SCOLON,           #:#          #                               #
        SSPC,             #"#          #                               #
        SSPC,             #_#          #                               #
        SSPC,             #!#          #                               #
        SSPC,             #&#          #                               #
        SSPC,             #'#          #                               #
        SSPC,             #?#          #                               #
        SSPC,             #<#          #                               #
        SSPC,             #>#          #                               #
        SSPC,             #@#          #                               #
        SSPC,             #\#          #                               #
        SSPC,             #^#          #                               #
        SSPC;             #SEMI-COLON# #                               #
      SWITCH STTRANSWTCH SYN1ERR,COLON,SYNLBL,SYNSLBL,LBLCALL,LBLSLASH, 
                         SUBLBLCALL,SUBLBLSLASH,SYNSUBR,SUBR,SUBRSLASH, 
                         SYNKEY,SYNKEYWRD,SYNKEYWORD,KEYSLASH,SYNDRIVER,
                         SYND,SYNDIAG,DIAGSLASH,SYNY,SYNE,SYNS,SYNYES,
                         YESSLASH,SYNN,SYNO,SYNNO,NOSLASH,SYNLETTER,
                         SYNLETR,SYNCHAR,SYNDIGIT,SUBLLBLCALL,SUBRL,
                         SYNLKEYWRD,SYNLDIAG,LBLLCALL,SYNLYES,SYNLNO, 
                         SYNLREQUEST,SYNREQ,DRIVERSLSH,HYPHENCHECK, 
                         HYPHEN;
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                  LEXICONSCAN                                         #
#                                                                      #
#                                                                      #
  FUNC LEXICONSCAN B; 
    BEGIN 
      LEXPTR = B<0,6>NAME[0];          # 1ST CHAR IN WORD IS INDEX.    #
      ITEMP = N * 18; 
      IF LEXPTR GR O"32" THEN          # CHECK FOR SPECIAL CHAR AS 1ST #
        BEGIN 
          WRDPTR = B<ITEMP+6,12>LOCWRD[0];#PTR TO 1ST ENTRY IN SPEC CHR#
          ENTRIES = B<ITEMP,6>LOCWRD[0];#NR ENTRIES IN SPEC CHAR SET.  #
          GOTO SCNLEXWRD; 
        END 
      WRDPTR = B<ITEMP+6,12>LOCWRD[LEXPTR];#PTR TO 1ST ENTRY IN CHAR ST#
      ENTRIES = B<ITEMP,6>LOCWRD[LEXPTR];#NR ENTRIES IN THIS CHAR SET. #
  SCNLEXWRD:  
      FOR I=1 STEP 1 UNTIL ENTRIES DO  # SEARCH CHAR SET FOR MATCH WITH#
        BEGIN                          # THE SOURCE WORD IN NAME.      #
              IF LEXWRD[WRDPTR] EQ NAME[0] THEN 
                BEGIN 
                  IF N LS 1 THEN
                        GOTO SCANEXIT;
                  IF LEXWRD[WRDPTR + 1] EQ NAME[1] THEN 
                    BEGIN 
                      IF N LS 2 THEN
                        GOTO SCANEXIT;
                      IF LEXWRD[WRDPTR + 2] EQ NAME[2] THEN 
                        BEGIN 
  SCANEXIT: 
                          LEXICONSCAN = TRUE; 
                          RETURN; 
                        END 
                    END 
                END 
          WRDPTR = WRDPTR + 2 + N;     # INCREMENT PTR TO NEXT ENTRY.  #
        END 
      LEXICONSCAN = FALSE;
      RETURN; 
    END 
#**********************************************************************#
 SYNSCAN: #............................................................#
      IF CHRPTR LS LASTCHAR THEN       # CHECK FOR NEED TO READ A NEW  #
        GOTO STARTSTATE;               # SOURCE RECORD. IF NOT GOTO THE#
                                       # SYNTAX CRACKER.               #
      CHRPTR = 0;                      #                               #
 READSYNTAX:                           #                               #
      SYNREAD;                         # READ A NEW SOURCE RECORD.     #
      IF SYNEOF GR 0 THEN              # IF EOF REACHED GOTO WRAP-UP.  #
        GOTO INPUTEOF;                 #                               #
      IF FIRSTCHAR GR 0 THEN           # IF COMMENT FROM PREVIOUS      #
        BEGIN                          # RECORD NOT ENDED, THEN SEARCH #
          BP = -6;                     # FOR ENDING DELIMITER.         #
          I = -1;                      #                               #
          WRDPTR = 0;                  #                               #
          GOTO CNTCMNT;                #                               #
        END                            #                               #
      FOR WRDPTR=0 STEP 1 UNTIL 6 DO   # SKIP ANY CARDS WITH 72 LEADING#
        IF INWORD[WRDPTR] NQ " " THEN  # BLANKS.                       #
          GOTO BREAKUP; 
      IF C<0,2>INWORD[7] NQ " " THEN
        GOTO BREAKUP; 
      GOTO READSYNTAX;                 # GET NEXT SOURCE RECORD.       #
 BREAKUP: 
      IF INWORD[0] EQ "END       " THEN GOTO INPUTEOF;
      IF INWORD[0] EQ "+       "  THEN
        BEGIN 
        PTC = TRUE; 
        GOTO INPUTEOF;
        END 
      FOR BP=0 STEP 6 DO               # LOCATE 1ST NON-BLANK CHARACTER#
        IF B<BP,6>INWORD[WRDPTR] NQ O"55" THEN #IN THE INPUT RECORD.   #
          GOTO GETFIRSTCHAR;
 GETFIRSTCHAR:  
      FOR I=BP/6+WRDPTR*10 STEP 1 UNTIL 71 DO #1ST 72 CHARS OF RECORD  #
        BEGIN                          # ARE SCANNED.                  #
          ITEMP = B<BP,6>INWORD[WRDPTR];#                              #
          GOTO SYNTAXSWCH[ITEMP];      # DISPLAY VALUE IS INDEX.       #
 STORECHAR:                            #                               #
          FIRSTCHAR = 0;               #                               #
          CHAR[CHRPTR] = ITEMP;        # STORE CHAR IN SYNCHARS.       #
          CHRPTR = CHRPTR + 1;         #                               #
 NEXTCHAR:                             #                               #
          IF BP GR 53 THEN             # INCREMENT PTRS TO NEXT SOURCE #
            BEGIN                      # CHARACTER.                    #
              BP = 0;                  #                               #
              WRDPTR = WRDPTR + 1;     #                               #
            END                        #                               #
          ELSE BP = BP + 6;            #                               #
        END                            #                               #
 LASTOFRECORD:                         #                               #
      LASTCHAR = CHRPTR;               # PTR TO LAST SOURCE CHAR IN    #
                                       # SYNCHARS.                     #
      IF CHRPTR EQ 0 THEN              # IF NO SIGNIFICANT CHARS ON    #
        GOTO READSYNTAX;               # CARD, GO GET NEXT RECORD.     #
      CHRPTR = 0;                      #                               #
      STATLIST[LASTCHAR] = S"COMA";    # LAST CHAR ALWAYS A DELIMITER. #
      GOTO STARTSTATE;                 # GOTO SYNTAX CRACKER.          #
  SCOMMA:                              #                               #003960
      IF CHRPTR GQ 2                   # A COMMA CAN BE EITHER A       # DL3A018
        AND (CHAR[CHRPTR-2] EQ " " OR  # KEYWORD OR A DELIMITER.       # DL3A018
             CHAR[CHRPTR-2] EQ "/" OR 
             CHAR[CHRPTR-2] EQ ":" OR 
             CHAR[CHRPTR-2] EQ ","   ) # TEST PRIOR 2 CHARS FOR KEYWORD# DL3A018
        AND (CHAR[CHRPTR-1] EQ "$" OR  # CONSTRUCTS, I.E. A DELIMITER  # DL3A018
             CHAR[CHRPTR-1] EQ "-"   ) # FOLLOWED BY $ OR -. IF FOUND, # DL3A018
      THEN GOTO SSPC;                  # TREAT AS KEYWORD SPECIAL CHAR.# DL3A018
                                       # (SIMILAR TEST IS AT SCOMMENT) # DL3A018
      IF CHRPTR EQ 1
        AND (CHAR[CHRPTR-1] EQ "$" OR #JUST REST FOR $ OR -, AS ABOVE#
             CHAR[CHRPTR-1] EQ "-"  ) 
      THEN GOTO SSPC; 
      GOTO SDELIM;                     # ELSE, COMMA IS A SYNGEN DELIM.#004000
  SSPC:                                #                               #
      STATLIST[CHRPTR] = S"SPC";       # STORE STATUS VALUE.           #
      GOTO STORECHAR;                  #                               #
  DGT:                                 #                               #
      STATLIST[CHRPTR] = S"DIGIT";     #                               #
      GOTO STORECHAR;                  #                               #
  SCOLON:                              #                               #
      IF CHRPTR GQ 2                   # A COLON CAN BE EITHER A       #
        AND (CHAR[CHRPTR-2] EQ " " OR  # KEYWORD OR A DELIMITER.       #
             CHAR[CHRPTR-2] EQ "/" OR  #                               #
             CHAR[CHRPTR-2] EQ ":" OR  #                               #
             CHAR[CHRPTR-2] EQ ","   ) # TEST PRIOR 2 CHARS FOR KEYWORD#
        AND (CHAR[CHRPTR-1] EQ "$" OR  # CONSTRUCTS, I.E. A DELIMITER  #
             CHAR[CHRPTR-1] EQ "-"   ) # FOLLOWED BY $ OR -. IF FOUND, #
      THEN GOTO SSPC;                  # TREAT AS KEYWORD SPECIAL CHAR.#
                                       # (SIMILAR TEST IS AT SCOMMENT) #
      IF CHRPTR EQ 1                   # IF ONLY 1 PRIOR CHAR,         #
        AND (CHAR[CHRPTR-1] EQ "$" OR  # JUST TEST FOR $ OR -, AS ABOVE#
             CHAR[CHRPTR-1] EQ "-"   ) #                               #
      THEN GOTO SSPC;                  #                               #
      IF STATLIST[CHRPTR-1] EQ S"COMA" THEN #COLON IS A DELIMITER, SO  #
        CHRPTR = CHRPTR - 1;           # PRECEDING BLANK OR COMMA IS   #
                                       # OVERLAID.                     #
      STATLIST[CHRPTR] = S"COLN";      #                               #
      GOTO STORECHAR;                  #                               #
  SASK:                                #                               #
      STATLIST[CHRPTR] = S"ASK";       #                               #
      GOTO STORECHAR;                  #                               #
  SSLASH:                              #                               #
      STATLIST[CHRPTR] = S"SLSH";      #                               #
      IF CHRPTR GR 0 AND               # / CAN BE A KEYWORD TOO.       #
         STATLIST[CHRPTR-1] GR S"ASK" AND 
         STATLIST[CHRPTR-1] LS S"PLUS" THEN 
         BEGIN
           IF CHRPTR GR 1 AND 
              STATLIST[CHRPTR-2] GQ S"ASK" THEN 
                GOTO STORECHAR; 
           STATLIST[CHRPTR] = S"LETTER";
         END
      GOTO STORECHAR;                  #                               #
  SDSIGN:                              #                               #
      STATLIST[CHRPTR] = S"DSGN";      #                               #
      GOTO STORECHAR;                  #                               #
  SMINUS:                              #                               #
      STATLIST[CHRPTR] =S"MINUS";      #                               #
      GOTO STORECHAR;                  #                               #
  SPLUS:                               #                               #
      STATLIST[CHRPTR] = S"PLUS";      #                               #
      GOTO STORECHAR;                  #                               #
  SD:                                  #                               #
      STATLIST[CHRPTR] = S"D";         #                               #
      GOTO STORECHAR;                  #                               #
  SY:                                  #                               #
      STATLIST[CHRPTR] = S"Y";         #                               #
      GOTO STORECHAR;                  #                               #
  SE:                                  #                               #
      STATLIST[CHRPTR] = S"E";         #                               #
      GOTO STORECHAR;                  #                               #
  SS:                                  #                               #
      STATLIST[CHRPTR] = S"S";         #                               #
      GOTO STORECHAR;                  #                               #
  SN:                                  #                               #
      STATLIST[CHRPTR] = S"N";         #                               #
      GOTO STORECHAR;                  #                               #
  SO:                                  #                               #
      STATLIST[CHRPTR] = S"O";         #                               #
      GOTO STORECHAR;                  #                               #
  LET:                                 #                               #
      STATLIST[CHRPTR] = S"LETTER";    #                               #
      GOTO STORECHAR;                  #                               #
  SDELIM:                              #                               #
      IF FIRSTCHAR LS 0 THEN           # IF DELIMITER PRECEDED THEN    #
        GOTO NEXTCHAR;                 # SKIP THIS ONE.                #
      IF CHRPTR EQ 0 THEN              # IF COMMENT STARTED THIS CARD, #
        GOTO NEXTCHAR;                 # SKIP BLANKS AFTER COMMENT.    #
      IF STATLIST[CHRPTR-1] LS S"ASK" THEN #/ AND : ARE DELIMITERS TOO,#
        GOTO SLASHDELIM;               # IGNORE FOLLOWING BLANKS AND   #
                                       # COMMAS.                       #
      CHAR[CHRPTR] = ",";              # STORE A COMMA. ALL DELIMITERS #
                                       # ARE CONVERTED TO COMMAS.      #
      STATLIST[CHRPTR] = S"COMA";      # STORE STATUS VALUE OF CORRESP #
                                       # ONDING ENTRY IN SYNCHARS.     #
      CHRPTR = CHRPTR + 1;             # SET INDEX TO NEXT ARRAY ENTRY.#
 SLASHDELIM:  
      FIRSTCHAR = -1;                  # INDICATES PRECEDING CHAR WAS A#
      GOTO NEXTCHAR;                   # DELIMITER.                    #
  SCOMMENT:                            #                               #
      IF CHAR[CHRPTR-1] EQ "$" OR      # CHECK IF THE PREVIOUS CHAR    #
         CHAR[CHRPTR-1] EQ "-" THEN    # INDICATES A KEYWORD. IF KEYWRD#
          GOTO EQUIV;                  # STORE CHARACTER. OTHERWISE A  #
  CNTCMNT:                             # COMMENT IS INDICATED. SCAN IN-#
      FOR I=I+1 STEP 1 UNTIL 71 DO     # PUT UNTIL TERMINATING COMMENT #
        BEGIN                          # DELIMITER FOUND.              #
          IF BP GR 53 THEN             # INCREMENT PTRS TO NEXT SOURCE #
            BEGIN                      # CHARACTER.                    #
              BP = 0;                  #                               #
              WRDPTR = WRDPTR + 1;     #                               #
            END                        #                               #
          ELSE BP = BP + 6;            #                               #
          ITEMP = B<BP,6>INWORD[WRDPTR];#                              #
          IF ITEMP EQ O"60" THEN       # IF SOURCE CHAR IS ENDING DE-  #
            BEGIN                      # LIMITER THEN TURN OFF COMMENT #
              FIRSTCHAR = 0;           # FLAG AND CONTINUE SCAN.       #
              GOTO NEXTCHAR;           #                               #
            END                        #                               #
        END                            #                               #
      FIRSTCHAR = 1;                   # FLAG INDICATING THAT COMMENT  #
                                       # SPANS RECORD BOUNDARY.        #
      GOTO LASTOFRECORD;               #                               #
  EQUIV:                               #                               #
      STATLIST[CHRPTR] = S"LETTER";    #                               #
      GOTO STORECHAR;                  #                               #
  STARTSTATE:                          #                               #
      IF STATE EQ 13 THEN              # CHECK ENDING SLASH LAST TIME. #
        BEGIN                          #                               #
 SLASHOP: 
          SYNSTRUCTION = O"60000";     # SET THE OPERATOR FIELD.       #
          DISPLAYINSTR = "/";          # STORE A SLASH.                #
          IF STATLIST[CHRPTR] LS S"ASK" THEN
            BEGIN 
              IF STATLIST[CHRPTR] EQ S"COLN" THEN 
                STATE = 1;
              ELSE STATE = 2; 
              CHRPTR = CHRPTR + 1;
              GOTO SLASH; 
            END 
        STATE = 2;
          GOTO SLASH;                  # GOTO SLASH PROCESSING SECTION #
                                       # OF SYNGEN.                    #
        END                            #                               #
      NAME[0] = " ";                   # BLANK FILL NAME.              #
      NAME[1] = " ";                   # BLANK FILL NAME.              #
      NAME[2] = " ";                   # BLANK FILL NAME.              #
      NAME[3] = " ";                   # BLANK FILL NAME.              #
      CHARIND = 0;                     # ZERO OUT CHAR/NUM INDICATOR.  #
      M = -6;                          # INITIALIZE BIT POINTER.       #
      N = 0;                           # SET WORD PTR TO 0.            #
      GOTO STTRANSWTCH[SWITCHVALUE[STATLIST[CHRPTR],STATE]];
  SYNLBL:                              #                               #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      IF CHARIND GR 0 AND CHARIND      # CHECK IF THE LABEL HAS AN     #
        NQ 2 THEN                      # ALPHA CHARACTER.              #
        BEGIN                          #                               #
          IF LEXICONSCAN THEN       # CHECK IF LABEL HAS THE SAME NAME #
                                    # AS A KEYWORD.                    #
            BEGIN 
              WRDPTR = WRDPTR + N + 1; # SET PTR TO LEXSYNSECT.        #
              IF LEXSYNSECT[WRDPTR] EQ -1 THEN
                LEXSYNSECT[WRDPTR] = LABELCOUNTER + 1;
            END 
          SYMBOLLENGTH = N + 1;        # STORE THE LENGTH OF LABEL IN  #
          DISPLAYINSTR = NAME[0];      # STORE FIRST 7 CHARS OF LABEL  #
          GOTO LABELS;                 # WORDS. PASS CONTROL.          #
        END                            #                               #
      GOTO SYN1ERR;                    # UNRECONIZABLE STATEMENT.      #
  SYNSLBL:                             #                               #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      STATE = 2;
      IF CHARIND EQ 2 THEN             # CHECK IF SUBLABEL IS ALL DIGIT#
        IF M LS 7 AND N EQ 0 THEN      # CHECK IF SUBLABEL IS LESS THAN#
          BEGIN                        # 3 CHARACTERS.                 #
            CTEMP = NAME[0];           # ENTRY CONDITION FOR DISPLAY-  #
                                       # TOBIN                         #
            DISPLAYTOBIN;              # CONVERT THE VALUE IN CTEMP TO #
                                       # BINARY INTEGER.               #
            SYNSTRUCTION = O"60000";   # SET OPERATOR CODE TO 6.       #
            SUBLABEL = ITEMP;          # STORE THE BINARY INTEGER VALUE#
            B<0,6>DISPLAYINSTR = ":";  # STORE : AND THE SUBLABEL NAME.#
            C<1,6>DISPLAYINSTR = NAME[0]; 
            GOTO SUBLABELS;            # PASS CONTROL BACK TO SYNBUILD.#
          END                          #                               #
      GOTO SYN1ERR;                    # UNRECONIZABLE STATEMENT.      #
  LBLSLASH:                            #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO LBL1CALL;                   #                               #
  LBLLCALL: 
      STATE = 1;                       # COLON WAS ENDING DELIMITER.   #
      GOTO LBL1CALL;
  LBLCALL:                             #                               #
      STATE = 2;                       #                               #
  LBL1CALL:                            #                               #
      SYMBOLLENGTH = N + 1;            # STORE LENGTH OF LABEL IN WORDS#
      SYNSTRUCTION = O"24000";         # SET THE OPERATOR FIELD TO 5.  #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      DISPLAYINSTR = NAME[0];          # STORE THE NAME OF THE LABEL.  #
      GOTO LABELCALL;                  #                               #
  NOSLASH:                             #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SYN1NO;                     #                               #
  SYNLNO: 
      STATE = 1;                       # COLON WAS ENDING DELIMITER.   #
      GOTO SYN1NO;
  SYNNO:                               #                               #
      STATE = 2;                       #                               #
  SYN1NO:                              #                               #
      SYNSTRUCTION = 2;                # SET OPERAND FIELD TO 2.       #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      DISPLAYINSTR = NAME[0];          # STORE NO.                     #
      GOTO DRIVERREQ;                  # PASS CONTROL.                 #
  YESSLASH:                            #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SYN1YES;                    #                               #
  SYNLYES:  
      STATE = 1;                       # COLON WAS WNDING DELIMITER.   #
      GOTO SYN1YES; 
  SYNYES:                              #                               #
      STATE = 2;                       #                               #
  SYN1YES:                             #                               #
      SYNSTRUCTION = 1;                # SET OPERAND FIELD TO 1.       #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      DISPLAYINSTR = NAME[0];          # STORE YES.                    #
      GOTO DRIVERREQ;                  # PASS CONTROL.                 #
  SUBLLBLCALL:  
      STATE = 1;                       # COLON WAS ENDING DELIMITER.   #
      GOTO SUBLBLCALL;
 SUBLBLSLASH:                          #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      IF M LS 0 THEN
        GOTO SLASHOP; 
 SUBLBLCALL:                           #                               #
      IF M LS 0 THEN                   # IGNORE CONTIGUOUS DELIMITERS. #
        GOTO SYN1CHAR;                 #                               #
      IF M GR 6 OR N GR 0 THEN         # IF SUBLABEL EXCEEDS 2 CHARS - #
        GOTO SYN1ERR;                  # UNRECONIZABLE STATEMENT.      #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      CTEMP = NAME[0];                 # ENTRY CONDITION FOR DISPLAYTO-#
                                       # BIN.                          #
      DISPLAYTOBIN;                    # CONVERT THE VALUE IN CTEMP TO #
                                       # BINARY INTEGER.               #
      SUBLABEL = ITEMP;                # STORE THE BINARY VALUE OF THE #
                                       # SUBLBL NAME.                  #
      SYNSTRUCTION = O"40000";         # SET THE HIGH ORDER BIT OF THE #
                                       # THE OPERATOR FIELD.           #
      DISPLAYINSTR = NAME[0];          # STORE SUBLABEL NAME.          #
      GOTO SUBLABELCALL;               # PASS CONTROL.                 #
  DIAGSLASH:                           #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SYN1DIAG;                   #                               #
  SYNLDIAG: 
      STATE = 1;                       # COLON WAS ENDING DELIMITER.   #
      GOTO SYN1DIAG;
  SYNDIAG:                             #                               #
      STATE = 2;                       # RESET STATE.                  #
  SYN1DIAG:                            #                               #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      IF M GR 18 OR N GR 0 THEN        # IF THE DIAG NUMBER EXCEEDS    #
        GOTO SYN1ERR;                  # THAN 3 NUMBERS, ISSUE ERROR.  #
      CTEMP = " ";
      B<0,M>CTEMP = B<6,M>NAME[0];     # ENTRY CONDITION FOR           #
                                       # DISPLAYTOBIN.                 #
      DISPLAYTOBIN;                    # CONVERT THE VALUE IN CTEMP TO #
                                       # BINARY INTEGER.               #
      SYNSTRUCTION = ITEMP LOR O"4000";# STORE A 2 IN THE OPERATOR     #
                                       # FIELD AND THE BINARY VALUE OF #
                                       # THE DIAGNOSTIC NUMBER IN THE  #
                                       # OPERAND FIELD.                #
      DISPLAYINSTR = NAME[0];          # STORE DIAGNOSTIC.             #
      GOTO DIAGNOSTIC;                 # PASS CONTROL.                 #
  SUBRSLASH:                           #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SUBR1;                      #                               #
  SUBRL:  
      STATE = 1;                       # COLON WAS ENDING DELIMITER.   #
      GOTO SUBR1; 
  SUBR:                                #                               #
      STATE = 2;                       # RESET STATE.                  #
  SUBR1:                               #                               #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      IF N*60+M GR 66 OR               # CHECK FOR SUBROUTINE NAME > 12#
         M LS 0 THEN                   # CHARS OR < 1 CHAR IN LENGTH.  #
          GOTO SYN1ERR;                #                               #
      SYMBOLLENGTH = N + 1;            # STORE LENGTH OF SUBROUTINE IN #
                                       # WORDS.                        #
      SYNSTRUCTION = O"10000";         # SET OPERATOR TO 2.            #
      B<0,6>DISPLAYINSTR = O"47";      # STORE AN ASK.                 #
      C<1,6>DISPLAYINSTR = NAME[0];    # 1ST 6 CHARS OF SUBROUTINE NAME#
      GOTO SUBROUTINE;                 # PASS CONTROL.                 #
  COLON:                               #                               #
      STATE = 1;                       # RESET STATE.                  #
      GOTO SYN1CHAR;                   # CHECK NEXT CHARACTER.         #
  SYNY:                                #                               #
      STATE = 12;                      #                               #
      GOTO SYNCHAR;                    #                               #
  SYNE:                                #                               #
      STATE = 8;                       #                               #
      GOTO SYNCHAR;                    #                               #
  SYNS:                                #                               #
      STATE = 9;                       #                               #
      GOTO SYNCHAR;                    #                               #
  SYNN:                                #                               #
      STATE = 10;                      #                               #
      GOTO SYNCHAR;                    #                               #
  SYNO:                                #                               #
      STATE = 11;                      #                               #
      GOTO SYNCHAR;                    #                               #
  SYNKEY:                              #                               #
      SYNSTRUCTION  = O"14000";        # SET THE OPERATOR FIELD TO 3.  #
      GOTO KEYCOMMON; 
  SYNKEYWRD:                           #                               #
      SYNSTRUCTION  = O"20000";        # SET THE OPERATOR FIELD TO 4.  #
 KEYCOMMON:                            # CODE COMMON TO BOTH $ AND -   #
      STATE = 4;                       # KEYWORDS.                     #
      B<0,6>DISPLAYINSTR = B<0,6>CHAR[CHRPTR];# SAVE $ OR - .          #
      GOTO SYN1CHAR;                   #                               #
 HYPHENCHECK: 
      IF M LS 0 THEN                   # LABELS MAY NOT HAVE A HYPHEN  #
        GOTO SYN1ERR;                  # AS THE FIRST CHARACTER NOR AS #
      IF STATLIST[CHRPTR+1] EQ S"COLN" THEN #THE LAST CHARACTER.       #
        GOTO SYN1ERR; 
 SYNLETTER:                            #                               #
      CHARIND = CHARIND LOR 1;         # LOGICAL OR TO INDICATE ALPHA. #
  SYNCHAR:                             #                               #
      IF M EQ 54 THEN                  # SET WORD AND BIT POINTERS (N  #
        BEGIN                          # AND M) TO THE NEXT CHARACTER  #
          M = 0;                       # IN THE STRING BEING STORED IN #
          N = N + 1;                   # "NAME".                       #
        END                            #                               #
      ELSE M = M + 6;                  #                               #
      IF N GR 2 THEN                   # CHECK FOR A NAME EXCEEDING 30 #
        GOTO SYN1ERR;                  # CHARACTERS.                   #
      B<M,6>NAME[N] = B<0,6>CHAR[CHRPTR];# STORE CHARACTER IN NAME.    #
  SYN1CHAR:                            #                               #
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      GOTO STTRANSWTCH[SWITCHVALUE[STATLIST[CHRPTR],STATE]];
 HYPHEN:  
      IF STATLIST[CHRPTR+1] LQ S"SLSH" THEN #LABELS MAY CONTAIN HYPHENS#
        GOTO SYN1ERR;                  # THO NOT AS 1ST OR LAST CHARS. #
  SYNLETR:                             #                               #
      STATE = 7;                       #                               #
      GOTO SYNCHAR;                    #                               #
  SYNDIGIT:                            #                               #
      CHARIND = CHARIND LOR 2;         # LOGICAL OR TO INDICATE NUMERIC#
      GOTO SYNCHAR;                    #                               #
                                       #                               #
  SYND:                                #                               #
      STATE = 6;                       #                               #
      GOTO SYNCHAR;                    #                               #
  SYNSUBR:                             #                               #
      STATE = 3;                       #                               #
      IF STATLIST[CHRPTR+1] EQ S"DIGIT" THEN # 1ST CHAR IN A ROUTINE   #
        GOTO SYN1ERR;                  # NAME MUST BE ALPHABETIC.      #
      GOTO SYN1CHAR;                   #                               #
  SYN1ERR:  
      P<SERR> = LOC(USTATE);
      GOTO ERROREXIT; 
  SYN4ERR:  
      P<SERR> = LOC(UKEY);
      GOTO ERROREXIT; 
  SYN5ERR:  
      P<SERR> = LOC(UACT);
  ERROREXIT:  
      FOR CHRPTR=CHRPTR STEP 1 UNTIL LASTCHAR DO
        BEGIN 
          I = STATLIST[CHRPTR]; 
          IF I LS 1 THEN
            BEGIN 
              STATE = 1;
              GOTO PRINTDMSG; 
            END 
          IF I LS 2 THEN
            BEGIN 
              STATE = 2;
              GOTO PRINTDMSG; 
            END 
          IF I LS 3 THEN
            BEGIN 
              STATE = 13; 
              GOTO PRINTDMSG; 
            END 
          IF M EQ 54 THEN 
            BEGIN 
              N = N + 1;
              M = 0;
            END 
          ELSE M = M + 6; 
          B<M,6>NAME[N] = B<0,6>CHAR[CHRPTR]; 
        END 
      STATE = 2;
 PRINTDMSG: 
      CHRPTR = CHRPTR + 1;
      SYNERROR[4] = NAME[0];
      SYNERROR[5] = NAME[1];
      SYNERROR[6] = NAME[2];
      SYNERROR[7] = NAME[3];
      IF LFLAG EQ 0 THEN
        BEGIN 
          SCALL CHKLINO;
          SYNORL = SYNIRL;
          SYNPRNT(SYNIWSA); 
        END 
      SCALL CHKLINO;
      SYNORL = 80;
      SYNPRNT(SERR);
      CHKERRCNT;
      GOTO SYNSCAN;                    # TRY TO FIND A LEGAL SOURCE WD.#
  SYNLKEYWRD: 
      STATE = 1;
      GOTO SYN1KEYWRD;
  KEYSLASH:                            #                               #
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SYN1KEYWRD;
 SYNKEYWORD:                           #                               #
      STATE = 2;
  SYN1KEYWRD: 
      IF NOT LEXICONSCAN THEN          # IF NAME IS NOT A KEY WORD THEN#
        GOTO SYN4ERR; 
      CHRPTR = CHRPTR + 1;             # INCREMENT PTR TO NEXT CHAR.   #
      SYNSTRUCTION = SYNSTRUCTION + B<4,11>LEXWRD[WRDPTR+N+1];
      N = NAME[0];
      IF NAME[0] EQ ";" THEN           # SPELL OUT SPECIAL CHARS THAT  #
        N = "SEMICOLON ";              # WILL CLOBBER SYMPL COMPILATION#
      ELSE IF NAME[0] EQ """" THEN
             N = "NOTEQUAL  ";
           ELSE IF NAME[0] EQ "#" THEN
                  N = "EQUIVALENC"; 
      B<6,36>DISPLAYINSTR = B<0,36>N; 
      GOTO DRIVERREQ;                  # GOTO DRIVERREQ IN SYNBUILD.   #
  SYNDRIVER:  
      STATE = 5;                       # SET STATE FOR DRIVER REQUEST. #
      GOTO SYN1CHAR;
  SYNREQ: 
      STATE = 2;
  SYN1REQUEST:  
      FOR I=0 STEP 2 UNTIL 40 DO       # SCAN PRESET ARRAY CONTAINING  #004020
        BEGIN                          # DRIVER REQUESTS FOR A MATCH.  #
          IF NAME[0] EQ SYNR[I] THEN   # EACH WRD FOLLOWING THE DRIVER #
            BEGIN                      # REQUEST CONTAINS THE CORRESPON#
              SYNSTRUCTION = REQSTRUCTION[I]; # DING OPERATOR AND      #
              CHRPTR = CHRPTR + 1;     # OPERAND WHEN A MATCH IS FOUND #
              B<0,6>DISPLAYINSTR = O"45";#STORE + AND DRIVER REQUEST IN#
              B<6,36>DISPLAYINSTR = B<0,36>NAME[0];# DISPLAYINSTR.     #
              GOTO DRIVERREQ;          # STORE THE OPERATOR AND OPERAND#
            END 
        END 
      GOTO SYN5ERR;                    # DRIVER REQ WAS NOT FOUND.     #
  DRIVERSLSH: 
      STATE = 13;                      # STATE FOR SLASH TERMINATOR.   #
      GOTO SYN1REQUEST; 
  SYNLREQUEST:  
      STATE = 1;
      GOTO SYN1REQUEST; 
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          SYNXREF                                     #
#                                                                      #
#ROUTINE WHICH SORTS THE CROSS REFERENCE LISTS, FORMATS THEM AND WRITES#
#THEM ON THE SYSTEM OUTPUT FILE.                                       #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  THE THREE CROSS REFERENCE FILES - LXREF, DXREF, AND SXREF - MUST BE #
#  POSITIONED TO BOI.                                                  #
#EXTERNAL REFERENCES:                                                  #
#  LXREFR, DXREFR, AND SXREFR ARE COMPASS ROUTINES WHICH READ RECORDS  #
#  FROM THE LXREF, DXREF, AND SXREF FILES.                             #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#  THE THREE SORTED CROSS REFERENCE LISTS WILL BE WRITTEN ON THE SYSTEM#
#  OUTPUT FILE.                                                        #
#                                                                      #
#ERROR CONDITIONS:                                                     #
#  NONE                                                                #
#                                                                      #
 PROC SYNXREF;
   BEGIN
      P<SORT> = NEXTAVAIL[51]; #BASE OF SORTING SPACE IS FIRST AVAIL-  #
                               #ABLE WORD IN THE FIELD LENGTH.         #
      SORTFL = LASTAVAIL - P<SORT>;  #FL AVAILABLE FOR SORTING         #
      SYNEOF = 0;              #TURN OFF EOF FLAG.                     #
      FOR N=0 STEP 1 UNTIL SORTFL DO #READ ENTIRE FILE INTO CORE. IT   #
        BEGIN                  #MUST ALL FIT INTO CORE ELSE PUNT.      #
          DXREFR(LOC(SORTWORD[N])); 
          IF SYNEOF NQ 0 THEN  #SYNEOF SET TO 1 WHEN EOF READ.         #
          GOTO SORTDXREF; 
        END 
      IF SYNEOF EQ 0 THEN      #ABORT IF DIAGNOSTICS FILE CANNOT ALL BE#
        SYNABT(0);             #READ INTO CORE.                        #
 SORTDXREF: 
                               # SORT USING SHELL SORT ALGORITHM.      #
          N = N - 1;
          M = N;
 NEXTINTERVAL:  
          M = M/2;
          IF M EQ 0 THEN
        GOTO PRTDXREF;
          K = N - M;
      FOR J=0 STEP 1 UNTIL K DO 
        BEGIN 
          I = J;
 BACKTRACK: 
          L = I + M;
          IF B<0,10>SORTWORD[I] LQ B<0,10>SORTWORD[L] THEN
            TEST J; 
          LABELCOUNTER = SORTWORD[I];#SWAP LIST ELEMENTS, PUTTING THE  #
          SORTWORD[I] = SORTWORD[L];#SMALLER FIRST IN THE LIST.        #
          SORTWORD[L] = LABELCOUNTER; 
          IF I GQ M THEN       #SWAP REQUIRES BACKTRACKING.            #
            BEGIN 
              I = I - M;
              GOTO BACKTRACK; 
            END 
        END 
      GOTO NEXTINTERVAL;       #IF THRU WITH THIS SEGMENT, SORT NEW    #
                               # SEGMENT.                              #
 PRTDXREF:  
      HDRTITLE[0] = "DIAGNOSTIC CROSS REFERENCE ";
      SCALL PRNTHDR;
      SYNORL = 38;             #ERENCE LISTING.                        #
      SYNPRNT(DXREFHEADER2);
      SYNORL = 8; 
      SYNPRNT(SKIPLINE);
      LINENO = 2;              #COMPENSATE FOR EXTRA HEADER            #
      FOR I=0 STEP 1 UNTIL 3 DO #BLANK OUT SCRATCH STORAGE FOR USE AS  #
        SCRATCHWD[I] = " ";    #A PRINT LINE STORAGE AREA.             #
      IF N LS 0 THEN           #IF NO DIAGNOSTICS THEN PRINT THE WORD  #
        BEGIN                  # NONE.                                 #
          SYNORL = 26;
          SCRATCHWD[0] = " NONE"; 
          SCRATCHWD[2] = "NONE";
          SYNPRNT(SCRATCH); 
          GOTO READLXREF; 
        END 
      FOR I=0 STEP 1 UNTIL N DO #A LINE IS PRINTED FOR EACH DIAGNOSTIC #
        BEGIN                  #REFERENCE.                             #
          SCRATCHWD[4] = " ";  #BLANK OUT SCRATCH WORDS WHICH MIGHT NOT#
          SCRATCHWD[5] = " ";  #BE USED.                               #
          B<6,24>SCRATCHWD[0] = O"04000000" + B<12,18>SORTWORD[I];
                               # ADD A "D" IN FRONT OF DIAG NUMBER.    #
          P<SYMBOLTABLE> = B<42,18>SORTWORD[I];#SYMBOL TABLE ENTRY HAS #
          J = SLENGTH[0];      #NAME AND LENGTH OF NAME OF LABELLED    #
          SCRATCHWD[2] = SNAME[0];#SECTION WITH DIAGNOSTIC REFERENCE.  #
          IF J GR 1 THEN       #MOVE ALL OF LABEL TO SCRATCH WSA.      #
            BEGIN 
              SCRATCHWD[3] = SNAME[1];
              IF J GR 2 THEN
                SCRATCHWD[4] = SNAME[2];
            END 
          FOR L=54 STEP -6 WHILE B<L,6>SCRATCHWD[J+1] EQ 0 DO 
            B<L,6>SCRATCHWD[J+1] = " "; 
          B<0,6>SCRATCHWD[J + 2] = ":";#STORE : AND SUBLABEL IN WSA.   #
          B<6,12>SCRATCHWD[J + 2] = B<30,12>SORTWORD[I];
          SCALL CHKLINO;
          SYNORL = 58;
          SYNPRNT(SCRATCH);    #PRINT LINE OF CROSS REFERENCE LIST.    #
        END 
 READLXREF: 
      SYNEOF = 0;              #TURN OFF EOF FLAG.                     #
      FOR N=0 STEP 1 UNTIL SORTFL DO #READ ENTIRE LXREF INTO CORE.     #
        BEGIN 
          LXREFR(LOC(SORTWORD[N])); 
          IF SYNEOF NQ 0 THEN 
            GOTO SORTLXREF; 
        END 
      IF SYNEOF EQ 0 THEN      #ABORT IF FILE WOULDN"T FIT IN CORE.    #
        SYNABT(0);
 SORTLXREF: 
      N = N - 1;
      SORTER;                  #CALL SORTING ROUTINE.                  #
      HDRTITLE[0] = "LABEL CROSS REFERENCE "; 
      SCALL PRNTHDR;
      SYNORL = 58;
      SYNPRNT(LXREFHEADER2);   #ERENCE LISTING.                        #
      SYNORL = 8; 
      SYNPRNT(SKIPLINE);
      LINENO = 2;              #COMPENSATE FOR EXTRA HEADER            #
      SYNORL1 = 73; 
      PRINTER;                 #CALL PRINTING PROCEDURE.               #
      SYNEOF = 0;              #TURN OFF EOF FLAG.                     #
      FOR N=0 STEP 1 UNTIL SORTFL DO #READ ENTIRE SXREF INTO CORE.     #
        BEGIN 
          SXREFR(LOC(SORTWORD[N])); 
          IF SYNEOF NQ 0 THEN 
            GOTO SORTSXREF; 
        END 
      IF SYNEOF EQ 0 THEN 
        SYNABT(0);
 SORTSXREF: 
      N = N - 1;
      SORTER; 
      HDRTITLE[0] = "SUBROUTINE CROSS REFERENCE ";
      SCALL PRNTHDR;
      SYNORL = 58;
      SYNPRNT(SXREFHEADER2);   #REFERENCE LISTING.                     #
      SYNORL = 38;
      SYNPRNT(SXREFHEADER3);
      LINENO = 2;              #COMPENSATE FOR EXTRA HEADER            #
      SYNORL1 = 78; 
      PRINTER;                 #CALL PRINT FORMATTING ROUTINE.         #
      RETURN; 
      END 
      CONTROL EJECT;
#**********************************************************************#
      PROC SORTER;
        BEGIN 
          M = N;
 NEXTINTERVAL:  
          M = M/2;
          IF M EQ 0 THEN
            RETURN; 
          K = N - M;
          FOR J=0 STEP 1 UNTIL K DO 
            BEGIN 
              I = J;
 BACKTRACK:   L = I + M;
              P<SYMBOLTABLE> = B<42,18>SORTWORD[I]; 
              P<SYMBOLTABLE2> = B<42,18>SORTWORD[L];
              IF SNAME[0] GR SNAME2[0] THEN 
                GOTO SWAPUM;
              IF SNAME[0] EQ SNAME2[0] THEN 
                BEGIN 
                  IF SLENGTH[0] GR SLENGTH2[0] THEN 
                    GOTO SWAPUM;
                  IF SLENGTH[0] EQ SLENGTH2[0] AND
                     SLENGTH[0] GR 1 THEN 
                       BEGIN
                         IF SNAME[1] GR SNAME2[1] THEN
                           GOTO SWAPUM; 
                         IF SNAME[1] EQ SNAME2[1] AND 
                            SLENGTH[0] GR 2 AND 
                            SNAME[2] GR SNAME2[2] THEN
                              BEGIN   #SWAP IF OUT OF ORDER.           #
 SWAPUM:                        LABELCOUNTER = SORTWORD[I]; 
                                SORTWORD[I] = SORTWORD[L];
                                SORTWORD[L] = LABELCOUNTER; 
                                IF I GQ M THEN
                                  BEGIN 
                                    I = I - M;
                                    GOTO BACKTRACK; 
                                  END 
                              END 
                       END
                END 
            END 
          GOTO NEXTINTERVAL;
        END 
      CONTROL EJECT;
#**********************************************************************#
      PROC PRINTER; 
        BEGIN 
          IF N LS 0 THEN       #IF NO REFERENCES IN A CATEGORY, THEN   #
            BEGIN              # THE WORD NONE IS PRINTED.             #
              SCRATCHWD[0] = " NONE"; 
              SCRATCHWD[1] = " "; 
              SCRATCHWD[2] = " "; 
              SCRATCHWD[3] = " "; 
              SCRATCHWD[4] = "NONE";
              SYNORL = 48;
              SYNPRNT(SCRATCH); 
              RETURN; 
            END 
          FOR I=0 STEP 1 UNTIL N DO #PRINT A LINE FOR EACH CROSS REF.  #
            BEGIN 
              FOR J=0 STEP 2 UNTIL 6 DO #BLANK OUT WSA TO ERASE LAST   #
                BEGIN          #RECORD THAT WAS WRITTEN.               #
                  SCRATCHWD[J] = " "; 
                  SCRATCHWD[J+1] = " "; 
                END 
              P<SYMBOLTABLE> = B<42,18>SORTWORD[I];#REFERENCED SYMBOL. #
              P<SYMBOLTABLE2> = B<24,18>SORTWORD[I];#SYMBOL DOING REF. #
              B<6,54>SCRATCHWD[0] = B<0,54>SNAME[0];#MOVE NAME OF SYMBL#
              B<0,6>SCRATCHWD[1] = B<54,6>SNAME[0];#BEING REFERENCED.  #
              K = SLENGTH[0]; 
              IF K GR 1 THEN
                BEGIN 
                  B<6,54>SCRATCHWD[1] = B<0,54>SNAME[1];
                  B<0,6>SCRATCHWD[2] = B<54,6>SNAME[1]; 
                  IF K GR 2 THEN
                    BEGIN 
                      B<6,54>SCRATCHWD[2] = B<0,54>SNAME[2];
                      B<0,6>SCRATCHWD[3] = B<54,6>SNAME[2]; 
                    END 
                END 
              FOR J=0 STEP -6 WHILE B<J,6>SCRATCHWD[K] EQ 0 DO
                BEGIN          #REPLACE TRAILING ZEROS WITH BLANKS.    #
                  B<J,6>SCRATCHWD[K] = " "; 
                  IF J EQ 0 THEN
                    BEGIN 
                      J = 60; 
                      K = K- 1; 
                    END 
                END 
              IF STYPE[0] EQ "L" THEN #IF LABEL CROSS REFERENCE BEING  #
                BEGIN          #PRINTED, THEN PRINT SUBLABEL REFERENCE.#
                  IF B<12,12>SORTWORD[I] NQ O"5555" THEN
                    BEGIN 
                      K = K + 1;
                      B<0,6>SCRATCHWD[K] = ":"; 
                      B<6,12>SCRATCHWD[K] = B<12,12>SORTWORD[I];
                    END 
                END 
              ELSE             #IF SUBROUTINE CROSS REFERENCE BEING    #
                BEGIN          #PRINTED, LIST THE SWITCH POSITION ALSO,#
                  ITEMP = SVALUE[0];#IN BOTH DECIMAL AND OCTAL.        #
                  BINTODISPOCT; 
                  FOR M=30 STEP 6 UNTIL 48 DO 
                    BEGIN 
                      IF B<M,6>OCTAL[1] NQ O"33" THEN 
                        GOTO STOREOCTPOS; 
                      B<M,6>OCTAL[1] = O"55"; 
                    END 
 STOREOCTPOS: 
                  B<30,30>SCRATCHWD[2] = B<30,30>OCTAL[1];
                  BINTODISPDEC; 
                  B<30,30>SCRATCHWD[1] = B<0,30>CTEMP;
                END 
              IF P<SYMBOLTABLE2> NQ P<SYMBOLTABLE> THEN #REFERENCING   #
                BEGIN          #SYMBOL PRINTED ONLY IF DIFFERENT FROM  #
                  SCRATCHWD[4] = SNAME2[0];#REFERENCED SYMBOL.         #
                  K = SLENGTH2[0];
                  IF K GR 1 THEN
                    BEGIN 
                      SCRATCHWD[5] = SNAME2[1]; 
                      IF K GR 2 THEN
                        SCRATCHWD[6] = SNAME[2];
                    END 
                  K = K + 3;
                  FOR L=54 STEP -6 WHILE B<L,6>SCRATCHWD[K] EQ 0 DO 
                    B<L,6>SCRATCHWD[K] = " ";#REPLACE ZEROS = BLANKS.  #
                  K = K + 1;
                END 
              ELSE K = 4; 
              B<0,6>SCRATCHWD[K] = ":"; 
              B<6,12>SCRATCHWD[K] = B<0,12>SORTWORD[I]; 
              SCALL CHKLINO;
              SYNORL = SYNORL1; 
              SYNPRNT(SCRATCH); 
            END 
          RETURN; 
        END 
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          BINTODISPDEC                                #
#                                                                      #
#ROUTINE WHICH CONVERTS BINARY INTEGERS INTO DISPLAY-CODED DECIMAL     #
#INTEGERS.                                                             #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  ITEMP CONTAINS AN UNSIGNED BINARY INTEGER TO BE CONVERTED.          #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#  CTEMP CONTAINS THE DECIMAL RESULT IN DISPLAY CODE, TRUNCATED TO FIVE#
#  DIGITS IF NECESSARY, IN THE LEFTMOST FIVE CHARACTERS.               #
#                                                                      #
#ERROR CONDITIONS: NONE                                                #
#                                                                      #
 PROC BINTODISPDEC; 
   ITEM I;
   BEGIN
      CTEMP = "    0";         #INITIALIZE CTEMP.                      #
      FOR I=24 STEP -6 WHILE ITEMP GR 0 DO #CONVERT BY POWERS OF 10.   #
        BEGIN 
          J = ITEMP/10; 
          B<I,6>CTEMP = ITEMP - J*10 + O"33";#ADD DISPLAY CODE BIAS.   #
          ITEMP = J;
        END 
      RETURN; 
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          DISPLAYTOBIN                                #
#                                                                      #
#ROUTINE TO CONVERT DISPLAY-CODED DECIMAL INTEGERS INTO BINARY.        #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  CTEMP CONTAINS A DISPLAY-CODED, UNSIGNED, DECIMAL INTEGER, LEFT-JUS-#
#  TIFIED.                                                             #
#EXIT CONDITIONS:                                                      #
#  ITEMP CONTAINS THE BINARY VALUE OF CTEMP                            #
#                                                                      #
 PROC DISPLAYTOBIN; 
   BEGIN
      ITEMP = 0;               #INITIALIZE RESULT TO ZERO.             #
      FOR I=0 STEP 6 UNTIL 54 DO
        BEGIN 
          J = B<I,6>CTEMP;
          IF J EQ O"55" AND            # SKIP LEADING BUT NOT TRAILING #
             ITEMP NQ 0 THEN           # BLANKS.                       #
            RETURN; 
          IF J GR O"44" OR
             J LS O"33" THEN
               BEGIN
                 BADDIGIT[1] = CTEMP; 
                 SCALL CHKLINO; 
                 SYNORL = 43; 
                 SYNPRNT(BADDIGITMSG);
                 CHKERRCNT; 
               END
          ITEMP = ITEMP*10 + J-O"33"; 
        END 
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          BINTODISPOCT                                #
#                                                                      #
#ROUTINE TO CONVERT BINARY INTEGERS INTO DISPLAY CODED OCTAL INTEGERS. #
#                                                                      #
#ENTRY CONDITIONS:                                                     #
#  ITEMP CONTAINS A BINARY VALUE TO BE CONVERTED.                      #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#  OCTAL CONTAINS THE TWENTY DISPLAY-CODED CHARACTERS WHICH ARE THE    #
#  RESULT.                                                             #
#                                                                      #
 PROC BINTODISPOCT; 
   ITEM I;
   BEGIN
      IF B<0,30>ITEMP NQ 0 THEN #TAKE A SHORT CUT IF LESS THAN 31 SIG- #
        FOR I=0 STEP 3 UNTIL 27 DO #NIFICANT BITS, ELSE GRIND IT OUT.  #
          B<I*2,6>OCTAL[0] = B<I,3>ITEMP + O"33"; 
      ELSE OCTAL[0] = O"33333333333333333333";
      FOR I=30 STEP 3 UNTIL 57 DO 
        B<(I-30)*2,6>OCTAL[1] = B<I,3>ITEMP + O"33";
      RETURN; 
   END
      CONTROL EJECT;
#**********************************************************************#
#                                                                      #
#                          WALKCHAIN                                   #
#                                                                      #
#ROUTINE TO WALK DOWN CHAIN OF REFERENCES AND REPLACE POINTERS WITH THE#
#DISPLAY-CODED INSTRUCTION IN "SYNSTRUCTION".                          #
#THE CHAIN IS TERMINATED BY A NEGATIVE POINTER VALUE.                  #
#                                                                      #
# ENTRY CONDITIONS:                                                    #
#  K CONTAINS THE SYNTBLE WORD ADDRESS OF THE 1ST ENTRY IN THE CHAIN.  #
#  SYNSTRUCTION CONTAINS THE DISPLAY-CODED INSTRUCTION TO BE STORED.   #
#  SYNTBLEWORD CONTAINS THE INDEX OF THE LWA+1 OF SYNTBLE.             #
#                                                                      #
#EXTERNAL REFERENCES:                                                  #
#  SYNTBLR AND SYNTBLW ARE COMPASS ROUTINES WHICH READ AND WRITE THE   #
#  SYNTBLE FILE.                                                       #
#                                                                      #
#EXIT CONDITIONS:                                                      #
#  THE CHAIN POINTERS WILL BE REPLACED BY THE CONTENTS OF SYNSTRUCTION.#
#                                                                      #
#ERROR CONDITIONS:                                                     #
#  A ZERO POINTER VALUE IS AN ERROR, AND IS DIAGNOSED WITH A DAYFILE   #
#  MESSAGE AND AN ABORT OF SYNGEN.                                     #
#                                                                      #
 PROC WALKCHAIN;
   ITEM ITEMP;
   BEGIN
 NEXTENTRY: 
      IF K GR SYNTBLEWORD THEN #IF THE ADDRESS IS IN THE WSA CURRENTLY #
        BEGIN                  #BEING BUILT, THEN 1ST CHAIN ENTRY IS IN#
          ITEMP = K - (SYNTBLEWORD+6);#THE ARRAY "PRESETCODE" AND NOT  #
          L = PRESETI[ITEMP];  #IN THE FILE.                           #
          PRESETI[ITEMP] = SYNSTRUCTION;
          GOTO CKENDOFCHAIN;
        END 
      IF K EQ 0 THEN SYNABT(4);    # IF A ZERO VALUE FOR LINK POINTER  #
      SYNTBLR(SCRATCH,K);      #FETCH WORD OF SYNTBLE CONTAINING NEXT  #
                               #IN CHAIN OF REFERENCES.                #
      L = SCRATCHWD[0];        #SAVE PTR TO NEXT CHAIN ENTRY.          #
      B<0,60>SCRATCHWD[0] = SYNSTRUCTION;#STORE INSTRUCTION.           #
      SYNTBLW(SCRATCH,K);      #STORE UPDATED SYNTBLE WORD BACK.       #
 CKENDOFCHAIN:  
      IF L LS 0 THEN RETURN;   #RETURN IF END OF CHAIN REACHED.        #
      K = L;
      GOTO NEXTENTRY; 
   END
      END 
 TERM 
*CWEOR,0
          IDENT SYNIO 
          ENTRY SYNOPEN 
          ENTRY SYNCLSE 
          ENTRY SYNREAD 
          ENTRY SYNPRNT 
          ENTRY SXREFWS 
          ENTRY  DXREFWS
          ENTRY  LXREFWS
          ENTRY  SYNTWSA
          ENTRY SYNABT
          ENTRY  TRACEW 
          ENTRY  LXREFW 
          ENTRY  DXREFW 
          ENTRY  SXREFW 
          ENTRY  SYNCOPY
          ENTRY  LXREFR 
          ENTRY  DXREFR 
          ENTRY  SXREFR 
          ENTRY  SYNCOM 
          ENTRY SYNIWSA      INPUT WORKING STORAGE AREA 
          ENTRY SYNEOF       INDICATES END OF FILE  (1=EOF) 
          ENTRY LFLAG        LFLAG=1 NO OUTPUT LISTINGS 
          ENTRY REWIND       REWIND=1 REWIND PRESET FILE AT EOJ.
          ENTRY SYNIRL       LENGTH OF THE INPUT RECORD 
          ENTRY SYNORL       LENGTH OF THE OUTPUT RECORD
          ENTRY  TFLAG
          ENTRY  OUTLEN      RECORD LENGTH FOR COMPILE FILE 
          ENTRY  REALEOF
          ENTRY  SKIPFLG           FLAG FOR CONDITIONAL SKIPPING
          ENTRY  DIRFLAG           FLAG FOR COND. SKIP DIRECTIVE
          EXT    HDRDATE
          EXT    HDRTIME
          ENTRY  SYNTIDA
          SST 
************************************************************************
*                *    S Y N O P E N    *                               *
*                                                                      *
*  ENTRY CONDITIONS:                                                   *
*    THE FIRST WORD OF SYNIWSA CONTAINS THE INPUT FILE LFN.            *
*    THE SECOND WORD OF SYNIWSA CONTAINS THE PRESET FILE LFN.          *
*    THE THIRD WORD OF SYNIWSA CONTAINS A RECORD TYPE FLAG.            *
*            0=C (DEFAULT)   (FILES INPUT, OUTPUT AND PRESET)          *
*            1=W                                                       *
*    THE FOURTH WORD OF SYNIWSA CONTAINS A BLOCKING TYPE FLAG.         *
*            0=Z (DEFAULT)   (FILES INPUT, OUTPUT AND PRESET)          *
*            1=I                                                       *
*    LFLAG IS SET TO INDICATE IF LISTINGS ARE ON OR OFF.               *
*            LFLAG = 1   ON                                            *
*            LFLAG = 0   OFF                                           *
*    TFLAG IS SET TO INDICATE IF THE TRACEM PRESET IS TO BE CREATED.   *
*                TFLAG = 1   ON                                        *
*                TFLAG = 0   OFF                                       *
*  EXIT CONDITIONS:                                                    *
*    FILES INPUT, OUTPUT, PRSET, SYNTBLE ARE OPEN. TRACEM FILE IS OPEN *
*    IF TFLAG = 1. FILES LXREF,DXREF, SXREF ARE OPEN IF LFLAG = 1.     *
*    THE FIRST WORD OF SYNIWSA CONTAINS THE NUMBER OF WORDS IN SYNGEN"S*
*    FIELD LENGTH. THE HEADERS:                                        *
*                  PROC SYN                                            *
*                TAXTABLE;                                             *
*                    BEGIN                                             *
*                  XDEF                                                *
*                     BEGIN                                            *
*    ARE WRITTEN ON THE PRESET FILE.                                   *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACROS  OPENM, STORE, FETCH. SCOPE MACRO MEMORY.              *
*  DESCRIPTION:                                                        *
*    THE BUFFERS FOR THE SYNTBLE AND TRACEM FILES ARE ALLOCATED AT EXE-*
*    CUTION TIME. LFLAG IS CHECKED TO DETERMINE IF THE CROSS-REFERENCE *
*    FILES ARE TO BE OPENED. TFLAG IS CHECKED TO SEE IF THE TRACEM FILE*
*    IS TO BE OPENED. THE MEMORY MACRO IS USED TO GET THE NUMBER OF    *
*    WORDS IN SYNGEN"S FIELD LENGTH. CONTROL IS RETURNED TO SYNCNTRL.  *
************************************************************************
 SYNOPEN  DATA   0
          SA1    INFILE      GET INPUT FILE LFN PASSED BY SYNGEN. 
          SA2    OUTFILE     GET PRESET LFN PASSED BY SYNGEN. 
          BX7    X1          OVERLAY THE LFN IN THE INPUT AND COMPILE 
          BX6    X2          FITS WITH THE LFNS IN INFILE AND OUTFILE.
          SA7    INPUT
          SA6    COMPILE
          SA1    LSTFILE     INSERT ALTERNATE NAME FOR LISTING FILE.
          BX6    X1 
          SA6    OUTPUT 
          SA3    65B         GET PTR TO LWA+1 OF LOADED CODE. 
          SX2    260         BUFFER FOR TRACEM
          SX4    X3          ISOLATE ADDRESS OF NEXT AVAILABLE WORD.
          IX6    X2+X3       INCREMENT PTR TO NEXT AVAILABLE WORD.
          SA6    65B         STORE NEW PTR, ALLOCATING THE 2 BUFFERS. 
          STORE  TRACEM,FWB=X4 ASSIGN BUFFER FOR TRACEM.
          OPENM  INPUT,INPUT,N  INPUT TO SYNGEN 
          OPENM  OUTPUT,OUTPUT,N  SYNGENS OUTPUT FILE 
          OPENM  COMPILE,I-O,N  SYNGENS PRESET FILE 
          SA1    LFLAG       GET OUTPUT FLAG. 
          ZR     X1,CKTRACE  IF LFLAG=0 THEN THERE IS NO NEED TO OPEN 
                             THE CROSS-REFERENCE FILES. 
          OPENM  LXREF,I-O,N FILE THAT THE LABEL CROSS-REFERENCE LISTING
                             IS BUILT ON. 
          OPENM  DXREF,I-O,N FILE THAT THE DIAGNOSTIC CROSS-REFERENCE 
                             LISTING IS BUILT ON. 
          OPENM  SXREF,I-O,N FILE THAT THE SUBROUTINE CROSS-REFERENCE 
                             LISTING IS BUILT ON. 
 CKTRACE  SA1    TFLAG       GET TRACE FLAG 
          ZR     X1,OPENEND  IF TFLAG=0 THERE IS NO NEED TO OPEN THE
                             TRACE FILE.
          OPENM  TRACEM,I-O,N FILE THAT THE TRACE PRESET IS BUILT ON. 
 OPENEND  MEMORY CM,SYNMEM,R GET FIELD LENGTH.
          SA1    SYNMEM            STORE FIELD LENGTH.
          AX1    30          SHIFT TO THE RIGHT THE NUMBER OF CM WORDS. 
          BX7    X1 
          SA7    SYNIWSA     PASS THE NUMBER OF CM WORDS BACK TO SYNCTRL
                             IN THE 1ST WORD OF THE INPUT WSA.
          EQ     SYNOPEN     RETURN TO SYNCTRL. 
************************************************************************
* 
*                              *  SYNTIDA  *
* 
*  USE SYSTEM MACROS TO INSERT TIME AND DATE IN HEADER LINE 
* 
 SYNTIDA  DATA 0
          DATE   HDRDATE
          CLOCK  HDRTIME
          EQ     SYNTIDA
************************************************************************
*                *    S Y N R E A D    *                               *
*                                                                      *
*  ENTRY CONDITIONS:                                                   *
*    LFLAG IS SET TO INDICATE IF THE OUTPUT LISTINGS ARE ON OR OFF.    *
*  EXIT CONDITIONS:                                                    *
*    THE INPUT RECORD IS STORED IN WORKING STORAGE AREA "SYNIWSA". THE *
*    LENGTH OF THE INPUT RECORD IS STORED IN SYNIRL. SYNEOF IS SET TO  *
*    1 IF AN END OF FILE CONDITION IS FOUND IN THE INPUT FILE.         *
*  EXTERNAL REFERENCES:                                                *
*    6RM MACROS  GET, PUT AND FETCH.                                   *
*  DESCRIPTION:                                                        *
*    SYNREAD READS A RECORD FROM SYNGEN"S INPUT FILE AND STORES IT IN  *
*    THE WORKING STORAGE AREA SYNIWSA. IF LFLAG IS ON, THE ADDRESS OF  *
*    SYNIWSA IS PASSED TO THE PUT MACRO AND THE INPUT RECORD IS WRITTEN*
*    ONTO THE OUTPUT FILE. THE LENGTH OF THE INPUT RECORD, IN CHARACT- *
*    ERS, IS STORED SYNIRL BY MEANS OF THE FETCH MACRO.                *
*                                                                      *
*    CHKSKIP IS CALLED TO RECOGNIZE SPECIAL COMPILER DIRECTIVES. TWO   *
*    FLAGS, DIRFLAG AND SKIPFLG, WILL BE SET BY CHKSKIP TO INDICATE    *
*    WHETHER OR NOT THE INPUT LINE IS TO BE PROCESSED BY THE COMPILER. *
*    SYNREAD PERFORMS SPECIAL PROCESSING FOR THE FLAG VALUES:          *
*                                                                      *
*       DIRFLAG = 1,  THE INPUT LINE WAS A COMPILER DIRECTIVE, AND IS  *
*                     NOT TO BE PROCESSED BY THE COMPILER. THE VALUE   *
*                     OF SKIPFLG IS IRRELEVANT.                        *
*                                                                      *
*       DIRFLAG = 0,  THE INPUT LINE WAS NOT A COMPILER DIRECTIVE, AND *
*                     THE VALUE OF SKIPFLG CONTROLS WHETHER OR NOT THE *
*                     LINE WILL BE PROCESSED BY THE COMPILER.          *
*                                                                      *
*       SKIPFLG = 0,  THE INPUT LINE IS NOT UNDER THE CONTROL OF       *
*                     CONDITIONAL COMPILATION DIRECTIVES, AND SHOULD   *
*                     BE PROCESSED BY THE COMPILER.                    *
*                                                                      *
*       SKIPFLG = 1,  THE INPUT LINE IS BEING SKIPPED BY CONDITIONAL   *
*                     COMPILATION DIRECTIVES, AND SHOULD NOT BE        *
*                     PROCESSED BY THE COMPILER.                       *
*                                                                      *
*       SKIPFLG = -1, THE INPUT LINE IS BEING INCLUDED BY CONDITIONAL  *
*                     COMPILATION DIRECTIVES, AND SHOULD BE PROCESSED  *
*                     BY THE COMPILER.                                 *
*                                                                      *
************************************************************************
 SYNREAD  JP     *+400000B         ENTRY/EXIT 
 SYNRD1   GET    INPUT,SYNIWSA,90  MOVE 90 CHAR INPUT RECORD TO SYNIWSA 
          RJ     =XCHKSKIP         CHK IF COMPILER DIRECTIVE OR SKIPPING
          FETCH  INPUT,RL,X7       FETCH RECORD LENGTH FROM FIT INTO X7 
          SA7    SYNIRL            SAVE IT FOR FUTURE USE 
          SA3    LFLAG             LISTING FLAG. SHOULD WE WRITE OUTPUT 
          ZR     X3,SYNRD5         IF NO LISTING...JUST CHECK FLAGS 
          SA3    =10H              NULL NOTATION...LEADING BLANKS 
          SA4    DIRFLAG           CHECK FOR A DIRECTIVE
          ZR     X4,SYNRD2         IF NOT A DIRECTIVE 
          SA3    =10H     -        NOTATION FOR A DIRECTIVE 
          EQ     SYNRD4 
  
 SYNRD2   SA4    SKIPFLG           CHECK THE SKIPPING FLAG
          ZR     X4,SYNRD4         IF NO SPECIAL SKIPPING 
          MI     X4,SYNRD3         IF NOT SKIPPING ON AN -IFEQ- 
          SA3    =10H     -        NOTATION FOR SKIPPING
          EQ     SYNRD4 
  
 SYNRD3   SA3    =10H    +         NOTATION FOR IFEQ INCLUSION
 SYNRD4   BX6    X3                (X3) HAS FIRST WORD FOR OUTPUT LINE
          SA6    SYNWS             STORE AS FIRST WORD OF LINE
          SX7    X7+10             RECORD LENGTH + LEADING WORD 
          PUT    OUTPUT,SYNWS,X7   PUT THE RECORD ON THE LISTING FILE 
 SYNRD5   SA3    SKIPFLG           CHECK THE SKIPPING FLAG
          SX3    X3-1              JUST WANT TO CHECK FOR SKIPFLG = 1 
          PL     X3,SYNRD1         IF SKIPPING, GET NEXT RECORD 
          SA3    DIRFLAG           CHECK DIRECTIVE FLAG 
          NZ     X3,SYNRD1         IF SKIPPING, GET NEXT RECORD 
          EQ     SYNREAD           RETURN TO CALLER 
  
************************************************************************
*                *    S Y N P R N T    *                               *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    THE ADDRESS OF THE WORKING STORAGE AREA THAT CONTAINS THE RECORD  *
*    THAT IS TO BE WRITTEN ON THE OUTPUT FILE IS PASSED IN THE PARA-   *
*    METER LIST. THE LENGTH OF THE RECORD TO BE PRINTED IS PASSED IN   *
*    SYNORL                                                            *
*  EXIT CONDITION:                                                     *
*    RECORD IN THE WORKING STORAGE AREA PASSED TO SYNPRNT IS WRITTEN   *
*    ONTO THE OUTPUT FILE.                                             *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO PUT.                                                    *
*  DESCRIPTION:                                                        *
*    WRITES A RECORD CONTAINED IN A WORKING STORAGE AREA ON TO THE     *
*    OUTPUT FILE.                                                      *
************************************************************************
 SYNPRNT  DATA   0
          SA3    SYNORL      LENGTH OF THE OUTPUT RECORD. 
          PUT    OUTPUT,X1,X3  MOVE RECORD FROM WROKING STORAGE AREA, 
*                            PASSED IN X1, TO THE OUTPUT FILE.
          EQ     SYNPRNT     RETURN TO CALLER.
************************************************************************
*                *   TRACEW  *                                         *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    NONE.                                                             *
*  EXIT CONDITION:                                                     *
*    RECORD CONTAINED IN THE WORKING STORAGE AREA "SYTWSA" IS WRITTEN  *
*    TO THE TRACEM FILE.                                               *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO  PUT.                                                   *
*  DESCRIPTION:                                                        *
*    WRITES THE RECORD CONTAINED IN THE WORKING STORAGE AREA "SYNTWSA" *
*    ONTO THE TRACEM FILE.                                             *
************************************************************************
 TRACEW   DATA   0
          PUT    TRACEM,SYNTWSA,60  MOVE TRACE RECORD INTO THE TRACEM 
*                            FILE.
          EQ     TRACEW      RETURN TO CALLER.
************************************************************************
*                *   LXREFW   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    NONE.                                                             *
*  EXIT CONDITION:                                                     *
*    RECORD CONTAINED IN THE WORKING STORAGE AREA "LXREFWS" IS WRITTEN *
*    TO THE LXREF FILE.                                                *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO  PUT.                                                   *
*                                                                      *
*  DESCRIPTION:                                                        *
*    WRITES THE RECORD CONTAINED IN THE WORKING STORAGE AREA "LXREFWS" *
*    ONTO THE LXREF FILE.                                              *
************************************************************************
 LXREFW   DATA   0
          PUT    LXREF,LXREFWS,10  MOVE LABEL CROSS-REFERENCE RECORD
*                            INTO THE LXREF FILE. 
          EQ     LXREFW      RETURN TO CALLER 
************************************************************************
*                *   DXREFW   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    NONE.                                                             *
*  EXIT CONDITION:                                                     *
*    RECORD CONTAINED IN THE WORKING STORAGE AREA "DXREFWS" IS WRITTEN *
*    TO THE DXREF FILE.                                                *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO  PUT.                                                   *
*  DESCRIPTION:                                                        *
*    WRITES THE RECORD CONTAINED IN THE WORKING STORAGE AREA "DXREFWS" *
*    ONTO THE DXREF FILE.                                              *
************************************************************************
 DXREFW   DATA   0
          PUT    DXREF,DXREFWS,10  MOVE DIAGNOSTIC CROSS-REFERENCE
*                            RECORD INTO THE DXREF FILE.
          EQ     DXREFW      RETURN TO CALLER.
************************************************************************
*                *   SXREFW   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    NONE.                                                             *
*  EXIT CONDITION:                                                     *
*    RECORD CONTAINED IN THE WORKING STORAGE AREA "SXREFWS" IS WRITTEN *
*    TO THE SXREF FILE.                                                *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO  PUT.                                                   *
*  DESCRIPTION:                                                        *
*    WRITES THE RECORD CONTAINED IN THE WORKING STORAGE AREA "SXREFWS" *
*    ONTO THE SXREF FILE.                                              *
************************************************************************
 SXREFW   DATA   0
          PUT    SXREF,SXREFWS,10  MOVE SUBROUTINE CROSS-REFERENCE
*                            RECORD INTO THE SXREF FILE.
          EQ     SXREFW      RETURN TO CALLER.
************************************************************************
*                *   SYNCOPY   *                                       *
*                                                                      *
*  ENTRY CONDITIONS:                                                   *
*    LFLAG INDICATES IF THE OUTPUT LISTINGS ARE ON OR OFF. THE HEADER  *
*    OF THE TRACEM ARRAY IS STORED IN THE WORKING STORAGE AREA SYNIWSA.*
*  EXIT CONDITIONS:                                                    *
*    THE FILES "SYNTBLE" AND "TRACEM" ARE WRITTEN TO THE PRESET FILE   *
*    AND IF LFLAG = 1, THEY ARE WRITTEN TO THE OUTPUT FILE. RA + 65 IS *
*    SET TO THE FIRST WORD OF THE SYNTBLE BUFFER (SYNBUF).             *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACROS  GET,PUT,REWIND AND CLOSEM.                            *
*    SYNIO ROUTINES  SYNPRNT AND SYNCOM.                               *
*  DESCRIPTION:                                                        *
*    REWINDS THE FILES "SYNTBLE" AND "TRACEM". COPIES THE FILES TO THE *
*    PRESET FILE, AND IF LFLAG = 1 COPIES THEM TO THE OUTPUT FILE.     *
*    AFTER THE FILES ARE COPIED, THE FILES ARE CLOSED. IN ORDER TO FREE*
*    ENOUGH BUFFER SPACE FOR THE CROSS-REFERENCE SORTS BY SYNBUILD, THE*
*    ADDRESS OF THE FIRST WORD OF THE SYNTBLE BUFFER IS STORED IN      *
*    RA + 65.                                                          *
************************************************************************
 SYNCOPY  DATA   0
          SA1    X1 
          SX6    X1-1 
          SA6    SYNORL      SAVE NUMBER OF WORDS IN SYNTBLE. 
          SX6    -5          INITIALIZE WORD ADDRESS OF LAST RECORD READ
          SA6    SYNIRL      FROM SYNTBLE FILE AND SAVE IN SCRATCH WORD.
 COPYTWO  SA2    SYNIRL      GET ADDRESS OF LAST RECORD READ. 
          SX3    6
          IX6    X3+X2       INCREMENT TO GET WORD ADDRESS OF NEXT
          SA6    A2          RECORD AND SAVE. 
          SA1    SCPARM 
          RJ     =XSYNTBLR   GO READ A RECORD FROM SYNBOL TABLE 
          SX1    SYNCWSA     CKTFLAG. 
          RJ     SYNCOM      WRITE OUT THE RECORD.
          SA1    SYNORL      CHECK FOR EOF. 
          SX6    X1-6 
          ZR     X6,CKTFLAG 
          SA6    A1 
          EQ     COPYTWO     COPY NEXT RECORD.
 CKTFLAG  SA3    TFLAG       GET TRACE FLAG.
          ZR     X3,RA65     IF TFLAG IS OFF THERE IS NO TRACE TABLE, 
*                            GOTO SET RA + 65 ROUTINE. IF TFLAG IS ON 
          REWINDM TRACEM     COPY THE TRACEM FILE TO THE PRESET FILE. 
 REWTRAC  SX1    SYNIWSA     WRITE TRACEM HEADER OUT. 
          RJ     SYNCOM 
 COPY2    GET    TRACEM,SYNTWSA,60   COPY UNTILL END-OF-DATA, THEN GOTO 
          SX1    SYNTWSA     DATA EXIT IN FILE MACRO. 
          RJ     SYNCOM      WRITE OUT THE RECORD.
          EQ     COPY2       COPY NEXT RECORD.
 RA65     FETCH  TRACEM,FWB,X6
          SA3    65B
          MX0    42 
          BX4    X3*X0
          IX7    X6+X4
          SA7    A3          STORE TRACEM BUFFER ADDRESS INTO RA+65.
          SA3    TFLAG       GET TRACE FLAG.
          ZR     X3,SYNCOPY  IF TLFAG = 0 TRACEM FILE WAS NEVER OPENED, 
          REWINDM  TRACEM 
*                            FILE 
          EQ     SYNCOPY     RETURN TO CALLER.
SCPARM    VFD    60/SYNCWSA 
          VFD    60/SYNIRL
************************************************************************
*                *   LXREWR   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    ADDRESS OF THE WORKING STORAGE WHERE THE RECORD IS TO BE STORED   *
*    IS PASSED IN THE PARAMETER LIST.                                  *
*  EXIT CONDITION:                                                     *
*    RECORD IS STORED IN THE WORKING STORAGE AREA PASSED TO LXREWR.    *
*    SYNEOF IS SET TO 1 WHEN END-OF-FILE OCCURS.                       *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACROS  GET AND FETCH.                                        *
*  DESCRIPTION:                                                        *
*    GETS A RECORD FROM THE FILE LXREF AND STORES IT IN THE WORKING    *
*    STORAGE AREA PASSED TO LXREFR. A CHECK IS MADE TO DETERMINE IF AN *
*    END-OF-SECTION OR END-OF-FILE HAS OCCURED. IF END-OF-SECTION READ *
*    NEXT RECORD, IF END-OF-FILE SET SYNEOF TO 1.                      *
************************************************************************
 LXREFR   DATA   0
          SA1    X1 
          BX7    X1 
          SA7    SYNMEM      SAVE ADDRESS.
 LXRD     SA1    SYNMEM 
          GET    LXREF,X1,10 MOVE RECORD TO THE WORKING 
                             STORAGE AREA PASSED TO LXREFR. 
          EQ     LXREFR      RETURN TO CALLER 
************************************************************************
*                *   DXREFR   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    ADDRESS OF THE WORKING STORAGE AREA WHERE THE RECORD IS TO BE     *
*    STORED IS PASSED IN THE PARAMETER LIST.                           *
*  EXIT CONDITION:                                                     *
*    RECORD IS STORE IN THE WORKING STORAGE AREA PASSED TO DXREFR.     *
*    SYNEOF IS SET TO 1 WHEN END-OF-FILE OCCURS.                       *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACROS  GET AND FETCH.                                        *
*  DESCRIPTION:                                                        *
*    GETS A RECORD FROM THE DXREF FILE AND STORES IT IN THE WORKING    *
*    STORAGE AREA PASSED TO DXREFR. A CHECK IS MADE TO DETERMINE IF AN *
*    END-OF-SECTION OR END-OF-FILE HAS OCCURED. IF END-OF-SECTION, READ*
*    NEXT RECORD, IF END-OF-FILE SET SYNEOF TO 1.                      *
************************************************************************
 DXREFR   DATA   0
          SA1    X1 
          BX7    X1 
          SA7    SYNMEM      SAVE ADDRESS.
 DXRD     SA1    SYNMEM 
          GET    DXREF,X1,10 MOVE RECORD TO THE WORKING 
*                            STORAGE AREA PASSED TO DXREFR. JUMPS TO
*                            ROUTINE SPECIFIED IN THE FILE MACRO WHEN 
*                            END-OF-SECTION/END-OF-FILE OCCURS. 
          EQ     DXREFR      RETURN TO CALLER.
************************************************************************
*                *   SXREFR   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    ADDRESS OF THE WORKING STORAGE AREA WHERE THE RECORD IS TO BE     *
*    STORED IS PASSED IN THE PARAMETER LIST.                           *
*  EXIT CONDITION:                                                     *
*    RECORED IS STORED IN THE WORKING STORAGE AREA PASSED TO SXREFR.   *
*    SYNEOF IS SET TO 1 WHEN END-OF-FILE OCCURS.                       *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACROS GET AND FETCH.                                         *
*  DESCRIPTION:                                                        *
*    GETS A RECORD FROM THE SXREF FILE AND STORES IT IN THE WORKING    *
*    STORAGE AREA PASSED TO SXREFR. A CHECK IS MADE TO DETERMINE IF AN *
*    END-OF-SECTION OR END-OF-FILE HAS OCCURED. IF END-OF-SECTION, READ*
*    NEXT RECORD, IF END-OF-FILE, SET SYNEOF TO 1.                     *
************************************************************************
 SXREFR   DATA   0
          SA1    X1 
          BX7    X1 
          SA7    SYNMEM      SAVE ADDRESS.
 SXRD     SA1    SYNMEM 
          GET    SXREF,X1,10 MOVE RECORD TO THE WORKING 
*                            STORAGE AREA PASSED TO SXREFR. JUMPS TO
*                            ROUTINE SPECIFIED IN THE FILE MACRO WHEN 
*                            END-OF-SECTION/END-OF-FILE OCCURS. 
          EQ     SXREFR      RETURN TO CALLER.
************************************************************************
*                *   SYNCOM   *                                        *
*                                                                      *
*  ENTRY CONDITIONS:                                                   *
*    LFLAG INDICATES IF THE OUTPUT LISTINGS ARE ON OR OFF. THE ADDRESS *
*    OF THE WORKING STORAGE AREA IS PASSED IN THE PARAMETER LIST.      *
*  EXIT CONDITIONS:                                                    *
*    RECORD CONTAINED IN THE WORKING STORAGE AREA PASSED TO SYNCON IS  *
*    WRITTEN TO THE PRESET FILE AND IF LFLAG = 1 IT IS WRITTEN TO THE  *
*    OUTPUT FILE.                                                      *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MACRO  PUT.                                                   *
*  DESCRIPTION:                                                        *
*    GETS A RECORD FROM THE WORKING STORAGE AREA PASSED TO SYNCON AND  *
*    STORES IT IN THE PRESET FILE, AND IF LFLAG = 1 STORES IT IN THE   *
*    OUTPUT FILE.                                                      *
************************************************************************
 SYNCOM   DATA   0
          SA2    OUTLEN      FETCH RECORD LENGTH TO WRITE 
SYNCON1   PUT    COMPILE,X1,X2  WRITE RECORD FROM WORKING STORAGE 
*                               AREA PASSED IN THE PARAMETER LIST TO THE
*                             COMPILE FILE
          EQ     SYNCOM      RETURN TO CALLER.
************************************************************************
*                *   SYNABT   *                                        *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    MESSAGE INDICATOR IS PASSED IN THE PARAMETER LIST:                *
*                0 = INSUFFICIENT FIELD LENGTH                         *
*                1 = CONTROL CARD ERROR.                               *
*                2 = UNEXPECTED END OF FILE ON INPUT                   *
*                3 = ERROR LIMIT(100) EXCEEDED                         *
*                4 = INTERNAL ERROR (WALKCHAIN)                        *
*                5 = SOURCE ERRORS -- ABORT REQUESTED                  *
*  EXIT CONDITION:                                                     *
*    ABORTIVE MESSAGE WRITTEN TO THE DAYFILE AND ALL FILES THAT WERE   *
*    OPENED ARE CLOSED.                                                *
*  EXTERNAL REFERENCE: SCOPE MARCO  MESSAGE.                           *
*  DESCRIPTION:                                                        *
*    CHECKS PARAMETER PASSED TO DETERMINE WHICH DIAGNOSTIC IS TO BE    *
*    WRITTEN TO THE DAYFILE. WRITES THE MESSAGE AND JUMPS TO SYNCLSE TO*
*    CLOSE THE FILES THAT ARE OPEN.                                    *
************************************************************************
 SYNABT   DATA   0
          SA1    X1          GET PARAMETER LIST ADDRESS.
          ZR     X1,SYNMSG2  CHECK MESSAGE INDICATOR. 
          SX2    3
          IX2    X1-X2
          ZR     X2,SYNMSG5  CHECK MESSAGE INDICATOR
          SX2    X1-4 
          ZR     X2,SYNMSG6  IF ABORT CODE IS 4 (WALKCHAIN INTERNAL ERR)
          SX2    X1-5 
          ZR     X2,SYNMSG7  IF ABORT CODE IS 5 (SOURCE ERRORS ABORT) 
          LX1    58 
          NG     X1,SYNMSG4 
          MESSAGE MSG1
          ABORT 
 SYNMSG2  MESSAGE MSG2
          CLOSEM OUTPUT,N    CLOSE THE SYSTEM OUTPUT FILE TO FLUSH THE
                             BUFFER.
          ABORT 
 SYNMSG4  MESSAGE MSG4
          EQ     SYNMSG2+2
 SYNMSG5  MESSAGE MSG5
          EQ      SYNMSG2+2 
  
 SYNMSG6  MESSAGE MSG6
          EQ     SYNMSG2+2
  
 SYNMSG7  MESSAGE MSG7
          ABORT 
  
************************************************************************
*                *   SYNCLSE   *                                       *
*                                                                      *
*  ENTRY CONDITION:                                                    *
*    LFLAG INDICATES IF THE OUTPUT LISTING IS ON OR OFF. REWIND IS SET *
*    TO INDICATE HOW THE PRESET FILE IS TO BE CLOSED: 0 = NO REWIND    *
*                                                                      *
*                                                                      *
*  EXIT CONDITIONS:                                                    *
*    ALL OF SYNGENS FILES ARE CLOSED. THE PRESET FILE MAY OR MAY NOT BE*
*    REWOUND.                                                          *
*  EXTERNAL REFERENCE:                                                 *
*    6RM MARCO: CLOSEM.                                                *
*  DESCRIPTION:                                                        *
*    LFLAG IS CHECKED TO SEE IF THE LISTINGS ARE ON. IF IT IS ON, TERM-*
*    INATING HEADERS ARE WRITTEN TO THE PRESET AND OUTPUT FILES, IF ITS*
*    OFF THE HEADERS ARE WRITTEN TO THE PRESET FILE ONLY. IF LFLAG IS  *
*    ON THE CROSS REFERENCE FILES ARE CLOSED WITH THE INPUT AND OUTPUT *
*    FILES. REWIND IS CHECKED TO INDICATE HOW THE PRESET FILE IS TO BE *
*    CLOSED: 0 = NO REWIND, 1 = REWIND.                                *
************************************************************************
 SYNCLSE  DATA   0
          SA2    A1+1 
          SA3    X1          1ST PARAMETER IS DISPLAY-CODED DIAGNOSTIC
          SA1    X2          COUNT AND 2ND PARAMETER IS DISPLAY-CODED 
          MX0    30          OCTAL VALUE OF CORE SIZE REQUIRED FOR THE
          LX6    X3          CURRENT COMPILATION. 
          BX7    -X0*X1 
          SA2    MSG3+3 
          LX7    6
          SX4    2
          SA5    LFLAG
          IX7    X4+X7
          SA6    MSG3+5 
          BX7    X2+X7
          SA7    A2 
          ZR     X5,PUTLAST  IF THE LISTING FLAG IS TURNED ON, THEN 
          CLOSEM SXREF,U     CLOSE-UNLOAD CROSS REFERENCE FILES.
          CLOSEM LXREF,U
          CLOSEM DXREF,U
 PUTLAST  BSS    0
          CLOSEM INPUT,N     CLOSE THE INPUT FILE, NO REWIND. 
          CLOSEM OUTPUT,N    CLOSE THE OUTPUT FILE. NO REWIND.
          SA3     TFLAG 
          ZR      X3,SYNCLS1
          CLOSEM  TRACEM,U
SYNCLS1   BSS     0 
          MESSAGE MSG3,,RECALL
          SA2    REWIND      GET THE ADDRESS OF THE REWIND INDICATOR. 
          ZR     X2,REWPRST  IF THEREWIND INDICATOR IS OFF, CLOSE THE 
*                            PRESET FILE WITH NO REWIND, OTHERWISE CLOSE
*                            THE PRESET FILE WITH A REWIND. 
          CLOSEM COMPILE,R   CLOSE WITH REWIND. 
          EQ     SYNCLSE     RETURN TO CALLER.
 REWPRST  CLOSEM COMPILE,N   CLOSE, NO REWIND.
          EQ     SYNCLSE     RETURN TO CALLER.
 LXCK     DATA   0
          SX1    LXREF       GET FIT ADDRESS. 
          RJ     CKEOF       CHECK FOR END-OF-FILE. 
          SA1    SYNEOF      GET THE END-OF-FILE FLAG.
          ZR     X1,LXRD     CHECK IF FLAG IS ON OR OFF.
          EQ     LXREFR      RETURN TO CALLER. END-OF-FILE. 
 DXCK     DATA   0
          SX1    DXREF       GET FIT ADDRESS. 
          RJ     CKEOF       CHECK FOR END-OF-FILE. 
          SA1    SYNEOF      GET THE END-OF-FILE FLAG.
          ZR     X1,DXRD     CHECK IF FLAG IS ON OR OFF.
          EQ     DXREFR      RETURN TO CALLER. END-OF-FILE. 
 SXCK     DATA   0
          SX1    SXREF       GET FIT ADDRESS. 
          RJ     CKEOF       CHECK FOR END-OF-FILE. 
          SA1    SYNEOF      GET THE END-OF-FILE FLAG.
          ZR     X1,SXRD     CHECK IF FLAG IS ON OR OFF.
          EQ     SXREFR      END-OF-FILE, RETURN TO CALLER. 
 TRACECK  DATA   0
          SX1    TRACEM      GET FIT ADDRESS. 
          RJ     CKEOF       CHECK FOR END-OF-FILE. 
          SA1    SYNEOF      GET THE END-OF-FILE FLAG.
          ZR     X1,COPY2    CHECK IF FLAG IS ON. 
          SX7    0
          SA7    SYNEOF      RESET END-OF-FILE FLAG TO ZERO.
          EQ     RA65        RETURN TO SYNCOPY
 CKEOF    DATA   0
          FETCH  X1,FP,X2    FETCH STATUS OF THE FILE POSITION FIELD. 
          SB1    X2 
          SB2    64          END-OF-INFORMATION STATUS. 
          EQ     B1,B2,SETEOF   IF FP STATUS EQUALS END-OF-INFORMATION, 
                             SET END-OF-FILE FLAG.
          EQ     CKEOF       RETURN TO CALLER.
 SETEOF   SX7    1
          SA7    SYNEOF      SET END-OF-FILE FLAG ON. 
          EQ     CKEOF       RETURN TO CALLER.
 INCK     DATA   0           CHECK FOR END OF SYNGEN INPUT. 
          SX1    INPUT       GET FIT ADDRESS. 
          RJ     CKEOF
          SA1    SYNEOF      CHECK IF END-OF-FILE FLAG IS ON. 
          NZ     X1,ENDIN    EOF REACHED ON SYNGEN INPUT FILE.
 INLFN    SB2    8           END-OF-SECTION STATUS (7/8/9). 
          NE     B1,B2,SYNRD2 NOT END OF SECTION SO READ ANOTHER CARD.
          SX7    1
          SA7    REALEOF
          SA7    SYNEOF      SET EOF FLAG.
ENDIN     RJ     ENDINP 
          EQ     SYNREAD
          ENTRY  ENDINP 
ENDINP    DATA   0
          SA1    LFLAG        CHECK FOR LISTING REQUEST 
          ZR     X1,ENDINP    RETURN IF NO LISTING REQUESTED
          REWINDM DXREF 
          REWINDM SXREF 
          REWINDM LXREF 
          EQ     ENDINP       RETURN TO CALLER
*THE BUFFERS FOR INPUT, OUTPUT, AND COMPILE ARE EXTRA-BIG IN CASE THEY *
*SHOULD BE REDEFINED AS I,W FILES BY THE USER.                         *
          FILE   LFN=INPUT,BFS=520,FWB=INBUF,WSA=SYNIWSA,DX=INCK,LT=UL,E
,RL=1,BT=C,RT=Z,FL=90 
          FILE   LFN=OUTPUT,BFS=520,FWB=OUTBUF,WSA=SYNOWSA,LT=UL,ERL=1,B
,T=C,RT=Z,FL=137
          FILE   LFN=COMPILE,BFS=520,FWB=COMBUF,WSA=SYNCWSA,LT=UL,ERL=1,
,BT=C,RT=Z,FL=90
          FILE   LFN=LXREF,BFS=260,FWB=LBUF,WSA=LXREFWS,LT=UL,RT=F,BT=C,
,FL=10,DX=LXCK
          FILE   LFN=DXREF,BFS=260,FWB=DBUF,WSA=DXREFWS,LT=UL,RT=F,BT=C,
,FL=10,DX=DXCK
          FILE   LFN=SXREF,BFS=260,FWB=SBUF,WSA=SXREFWS,LT=UL,RT=F,BT=C,
,FL=10,DX=SXCK
          FILE   LFN=TRACEM,BFS=260,WSA=SYNTWSA,LT=UL,RT=F,BT=C,FL=60,DX
,=TRACECK,FWB=TBUF
 SQ       STLD.RM USERT=(Z,F),USEBT=(C),USE=(OPENM,CLOSEM,GET,PUT,REWIND
,M,FETCH,STORE),OMIT=CMM
 SYNWS    DATA   10H
 SYNIWSA  BSS    9           INPUT WORKING STORAGE AREA.
 SYNOWSA  DATA   40H
          DATA   40H
 SYNCWSA  DATA   10H            PRESET WORKING STORAGE AREA.
          DATA   50H
 LXREFWS  BSSZ   1           LABEL CROSS-REFERENCE WORKING STORAGE AREA.
 DXREFWS  BSSZ   1           DIAG CROSS-REFERENCE WORKING STORAGE AREA. 
 SXREFWS  BSSZ   1           SUBR CROSS-REFERENCE WORKING STORAGE AREA. 
 SYNTWSA  BSSZ   6           TRACE CROSS-REFERENCE WORKING STORAGE AREA.
 SYNIN    BSSZ   10          INPUT FET. 
 SYNOUT   BSSZ   10          OUTPUT FET.
 SYNPRE   BSSZ   10          PRESET FET.
 SYNL     BSSZ   10          LABEL CROSS-REF FET. 
 SYND     BSSZ   10          IDAGNOSTIC CROSS-REF FET.
 SYNS     BSSZ   10          SUBROUTINE CROSS-REF FET.
 SYNT     BSSZ   10          TRACEM FET.
 SYNIRL   BSSZ   1           CONTAINS INPUT RECORD LENGTH.
 LFLAG    BSS    1           0=NO LISTING  1=LISTING  (SYSTEM OUTPUT).
 SKIPFLG  BSSZ   1                 FLAG FOR CONDITIONAL SKIPPING
 DIRFLAG  BSSZ   1                 CONDITIONAL SKIP DIRECTIVE ON INPUT
 TFLAG    BSS    1
 REWIND   BSS    1           0=NO REWIND    1=REWIND   (PRESET OUTPUT). 
 SYNORL   BSSZ   1           CONTAINS OUTPUT RECORD LENGTH. 
 SYNEOF   BSSZ   1           FLAG TO INDICATE END-OF-FILE.
 SYNMEM   BSSZ   1           CONTAINS FIELD LENGTH, RESULT FROM THE 
OUTLEN    BSSZ   1           LENGTH OF COMPILE RECORDS
 REALEOF  BSSZ   1           TRUE IF REALLY AT EOF ON *INPUT* 
 INBUF    BSSZ   520         INPUT BUFFER.
 OUTBUF   BSSZ   520         OUTPUT BUFFER. 
 COMBUF   BSSZ   520         PRESET OUTPUT BUFFER.
 LBUF     BSSZ   260         LABEL CROSS-REF BUFFER.
 DBUF     BSSZ   260         DIAGNOSTIC CROSS-REF BUFFER. 
 SBUF     BSSZ   260         SUBROUTINE CROSS-REF BUFFER. 
 TBUF     BSS    1           TRACEM BUFFER - BUFFER ACTUALLY ALLOCATED
*                                           - EXECUTION TIME. 
 MSG3     DIS    ,* SYNGEN COMPLETE.      SCM USED = *
          DIS    ,*                    DIAGNOSTICS* 
 MSG1     DATA   28LCONTROL CARD ERROR     *****
 MSG2     DATA   C* INSUFFICIENT FIELD LENGTH*
 MSG4     DATA   28LUNEXPECTED EOF ON INPUT ****
 MSG5     DATA   32LERROR LIMIT(100) EXCEEDED  *****
 MSG6     DATA   C* INTERNAL ERROR (WALKCHAIN)* 
 MSG7     DATA   C* SOURCE ERRORS -- ABORT REQUESTED* 
 CKLFNI   DATA   5LINPUT
 INFILE   EQU    SYNIWSA     CONTAINS THE INPUT LFN.
 OUTFILE  EQU    SYNIWSA+1   CONTAINS THE OUTPUT LFN. 
 LSTFILE  EQU    SYNIWSA+2   CONTAINS THE FILENAME FOR LISTINGS 
          END 
