DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦1179f73e8⟧ TextFile

    Length: 337152 (0x52500)
    Types: TextFile
    Names: »mpasc0«

Derivation

└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
    └─⟦b2ec5d50f⟧ 
        └─⟦this⟧ »mpasc0« 

TextFile

(*$M20 COMPILE 68000 *)
 (*$L+ OPTIONS HERE *) (* %M% %I% %H% ID KEYWORDS TO SCCS  *)

 (* +++++++++++++++++++++++++++++++++++++++++++++++++++++++*
  *                                                       *
  *     10/7/73   SYNTAX ANALYSIS INCLUDING ERROR         *
  *               HANDLING; CHECKS BASED ON DECLARA-      *
  *               TIONS; ADDRESS AND CODE GENERATION      *
  *               FOR A HYPOTHETICAL STACK COMPUTER       *
  *                      URS AMMANN  ETH ZURICH           *
  *                                                       *
  *     05/20/74                                          *
  *     THE COMPILER IS NOW WRITTEN IN A SUBSET OF        *
  *     STANDARD PASCAL  -  AS DEFINED IN THE NEW         *
  *     MANUAL BY K. JENSEN AND N. WIRTH  - AND IT        *
  *     PROCESSES EXACTLY THIS SUBSET.                    *
  *                      KESAV NORI  ETH ZURICH           *
  *                                                       *
  *     THE COMPILER IS NOW CHANGED TO:                   *
  *                                                       *
  *           -PRODUCE THE INTERMEDIATE CODE IN AN        *
  *           ASSEMBLER  READABLE FORM (NAMELY THE        *
  *           370, ASSEMBLER_H), 15-NOV-75.               *
  *                                                       *
  *           -PRESERVE PROCEDURE NAMES AND THEIR         *
  *           STATIC LEVELS AT THE OBJECT LEVEL, THUS     *
  *           ALLOWING A SET OF 'DISPLAY' REGISTERS TO    *
  *           BE USED IN ACCESSING NON_LOCAL, NON_GLOBAL  *
  *           VARIABLES (INSTEAD OF GOING THROUGH A       *
  *           CHAIN OF POINTERS), 10-DEC-75.              *
  *                                                       *
  *           -INCLUDE THE TYPE OF THE OPERANDS IN THE    *
  *           P_INSTRUCTIONS AS FOLLOWS:                  *
  *                                                       *
  *                A : ADDRESS (POINTER) OPERAND          *
  *                B : BOOLEAN              "             *
  *                C : CHARACTER            "             *
  *                I : INTEGER              "             *
  *                R : REAL                 "             *
  *                S : SET                  "             *
  *                                                       *
  *           THE P_INSTRUCTION NOW LOOKS LIKE:           *
  *           (LAB)  OPCODE  (TYPE),(OPERANDS)            *
  *           A NEW PROCEDURE 'HALT(RC: INTEGER)' IS      *
  *           ADDED TO THE SET OF STANDARD PROCEDURES     *
  *           TO FACILITATE TERMINATING A PROGRAM AT      *
  *           ANY POINT AND RETURNING A 'RETURN CODE'     *
  *           TO THE OPERATING SYSTEM, 26-JAN-76.         *
  *                                                       *
  *           -TREAT THE INPUT AS A TEXT FILE WITH        *
  *           LINES (RECORDS) OF LINELGTH CHAR. EACH,     *
  *           THIS ALLOWS A MORE EFFICIENT STRING         *
  *           ORIENTED INPUT, 20-MAR-76.                  *
  *                                                       *
  *           -ALLOCATE AND PROPERLY ALIGN VARIABLES ON   *
  *           THE BASIS OF THEIR TYPES, I.E.              *
  *                                                       *
  *                TYPE    SIZE    ALIGNED ON             *
  *                                                       *
  *                B,C     1-BYTE    1-BYTE               *
  *                A,I     4-BYTES   4-BYTE               *
  *                S       8-BYTES   4-BYTE               *
  *                R       8-BYTES   8-BYTE               *
  *                                                       *
  *           DYNAMIC STORAGE HOWEVER IS ALWAYS ALLOC-    *
  *           CATED ON 8-BYTE BOUNDARIES TO AVOID RUN-    *
  *           TIME CHECKING OVERHEAD, 25-APR-76.          *
  *                                                       *
  *          -'READ' OF 'STRING' VARIABLES (I.E. ARRAY    *
  *          OF CHAR) IS NOW IMPLEMENTED AND IT IS TO     *
  *          COMPLEMENT THE SIMILAR 'WRITE' FUNCTION.     *
  *          ALSO THE STANDARD PROCEDURE:                 *
  *          TRAP(I: INTEGER; VAR V: (.ANY TYPE.) );        *
  *          IS ADDED TO THE SET OF STANDARD PROCEDURES   *
  *          TO FACILITATE COMMUNICATION WITH THE OUT-    *
  *          SIDE WORLD, 10-SEP-76.                       *
  *                                                       *
  *          -RELEVENT INFORMATION ON/ABOUT PROCEDURES    *
  *          ARE NOW SENT TO 'QRD' FILE. THIS INCLUDES    *
  *          SUCH INFORMATION AS THE SIZE OF THE PROCE-   *
  *          DURE AS WELL AS ITS DATA AREA, LIST OF THE   *
  *          PROCEDURES CALLED AND THE # OF CALLS, THE    *
  *          LEVEL OF THE HIGHEST_LEVEL PROCEDURE CALLED  *
  *          ETC. THIS INFORMATION IS MAINLY INTENDED     *
  *          FOR INTER_PROCEDURAL ANALYSIS, BUT IT IS     *
  *          ALSO USEFUL FOR MORE EFFICIENT PROCEDURE     *
  *          ENTRY/EXIT CODE, 22-MAR-77.                  *
  *                                                       *
  *          -THE COMPILER IS NOW SET UP TO  GENERATE     *
  *          P_CODE  SUITABLE  FOR  A MICRO_PROCESSOR     *
  *          IMPLEMENTATION.  THE  LENGTH  (IN  #  OF     *
  *          BYTES)  OF  BASIC  DATA TYPES AS WELL AS     *
  *          THE FORMAT OF THE OUTPUT  IS  (SLIGHTLY)     *
  *          DIFFERENT  FROM THAT OF THE 370 VERSION,     *
  *          11-FEB-78.                                   *
  *                                                       *
  *                                                       *
  *     THE ABOVE CHANGES (INCLUDING ADDITIONS AND/OR     *
  *     DELETIONS) HAVE BEEN TAGGED BY A '#' TAG AT       *
  *     THE BEGINNING OR THE END OF AFFECTED LINES.       *
  *                        S. HAZEGHI    SLAC             *
  *                                                       *
  *                                                       *
  *     NEW CHANGES MADE 12/78 BY EPS (MARKED BY 'EPS')   *
  *     TO PERMIT COMPILATION BY THE BERKELEY UNIX        *
  *     COMPILER.                                         *
  *             -FIX LOOSE TYPE MATCHES (ARG TO GENLABEL) *
  *                                     (TYPE OF CSTPART) *
  *             -CHANGE READ(LINEBUF) TO FOR LOOP WHICH   *
  *                     READS CHAR BY CHAR                *
  *             -FILL IN ALL UNUSED VARIANTS OF RECORD    *
  *                     CASES                             *
  *             -COMMENT ALL UNUSED VARIABLES             *
  *             -COMMENT ALL # COMMENTS PUT IN BY HAZEGHI *
  *                                                       *
  *                     SKIP STRITTER                     *
  *                     MOTOROLA                          *
  *                                                       *
  *     GOTO'S ELIMINATED IN INSYMBOL, NEW1, SEARCHID,    *
  *     SEARCHSECTION, AND CASESTATEMENT FOR COMPILATION  *
  *     BY NBS COMPILER                                   *
  *                     12/28/78  EPS MOTOROLA            *
  *                                                       *
  *     01/04/79  CHANGES IN INSYMBOL (COLLECTING         *
  *     INTEGERS) FOR NON-DECIMAL RADIX INTEGER CONSTANTS *
  *     (OF THE FORM RR#NN...N WHERE RR IS BASE 10 AND    *
  *     1 <= RR <= 16 AND N < RR )                EPS     *
  *                                                       *
  *     01/05/79 CHANGE INSYMBOL AND ADD ARRAY UPPER FOR  *
  *     TRANSLATION OF ALL INPUT IDENTIFIERS AND          *
  *     RESERVED WORDS TO UPPER CASE - UPPER CASE         *
  *     AND LOWER CASE ARE INDISTINGUISHABLE TO THE       *
  *     COMPILER EXCEPT IN STRINGS                EPS     *
  *                                                       *
  *     01/23/79 UPDATE INSYMBOL TO ACCEPT MOTOROLA       *
  *     OPTIONS                                   EPS     *
  *                                                       *
  *     01/23/79 CREATE WARNING FACILITY SIMILAR TO       *
  *     EXISTING ERROR FACILITY.  NEW PROC WARNING;       *
  ▶1a◀▶1a◀     NEW C▶1a◀LOBALS WARNINGS:BOOLEAN AND WARNCOUNT:       ▶1a◀▶1a◀
     *     INTEGER                                   EPS     *
     *                                                       *
     *     01/23/79  CHANGES TO SUPPORT ALPHANUMERIC         *
     *     LABELS.  CHANGES MADE IN 'LABELDECL',             *
     *     'GOTOST', AND 'STATEMENT'.  RECORD 'LABL'         *
     *     CHANGED TO INCLUDE A VARIANT FIELD OF INTEGER     *
     *     OR ALPHA VALUE.  LABELS ARE KEPT IN A STRING      *
     *     OF 'LABL'S;  ALPHA LABELS ARE ALSO ENTERED        *
     *     INTO THE SYMBOL TABLE TO AVOID CONFLICTING        *
     *     DEFINITIONS WITH VARIABLES.  'GOTOST' AND 'ST'    *
     *     SCAN THE STRING OF DECLARED LABELS TO FIND        *
     *     THE LABEL THEY ARE PARSING.               EPS     *
     *                                                       *
     *     01/25/79  CHANGE TO SUPPORT UNORDERED DECLARATION *
     *     STATEMENTS.  CHANGE 'ERROR(18)' TO 'WARNING(502)' *
     *     IN 'BLOCK' AND MOVE CHECK FOR UNRESOLVED FORWARD  *
     *     TYPE DECL'S FROM INSIDE 'TYPEDECLARATION'         *
     *     AND 'VARDECLARATION' TO 'BLOCK'           EPS     *
     *                                                       *
     *     01/30/79  ALL GEN ROUTINES REPLACED BY MOTOROLA   *
     *     VERSIONS.  ALL CALLS TO GEN ROUTINES REPLACED     *
     *     BY CALLS TO NEW ROUTINE.  THE COMPILER NOW        *
     *     COMPILES TO PM, THE MOTOROLA P LANGUAGE   EPS     *
     *                                                       *
     *     02/02/79  ADDED 'OTHERWISE' CLAUSE TO 'CASE'      *
     *     STATEMENT.  NEW SYMBOL 'OTHERWISE' AND CORRE-     *
     *     SPONDING ENTRIES IN RW AND FRW.  'OTHERWISE'      *
     *     IS OPTIONAL; IT FOLLOWS ALL ALTERNATIVES IN       *
     *     THE CASE BODY; THE SYMBOL ITSELF IS NOT FOLLOWED  *
     *     BY A SEMICOLON.  EVEN WITHOUT THE OTHERWISE       *
     *     CLAUSE THE CASE STATEMENT IS SAFE - IT MAY BE     *
     *     EQUIV TO A NULL STATEMENT FOR SOME VALUES OF THE  *
     *     CASE INDEX, BUT IT NEVER EXEC'S BAD CODE          *
     *                                               EPS     *
     *                                                       *
     *     02/02/79  ADDED 'EXIT' STATEMENT.  NEW PROCEDURES *
     *     'LOOPENTRY', 'LOOPEXIT', AND 'EXITSTATEMENT'      *
     *     AND VARIABLES 'LOOPLISTPTR' AND TYPES 'LOOPPTR'   *
     *     AND LOOPLABL.  COMMENTS IN THE CODE.      EPS     *
     *                                                       *
     *     02/21/79 CHANGED LINELGTH TO 133 TO ALLOW LONGER  *
     *     INPUT LINES.  ADDED WARNING(503) IN INSYMBOL WHEN *
     *     SCANNING A LEFTHAND-CURLY-BRACKET COMMENT IF      *
     *     ENCOUNTER  ANOTHER LEFTHAND CURLY BRACKET,        *
     *     TO HELP DETECT BADLY FORMED, E.G. NESTED COMMENTS *
     *                                                EPS    *
     *                                                       *
     *     02/23/79 ADDED 'ORIGIN' FEATURE.  CHANGES IN      *
     *     'VARDECLARATION', 'SELECTOR', AND ADDITION OF     *
     *     NEW SYMBOL TYPE 'ORIGINSY' AND NEW RESERVED WORD  *
     *     'ORIGIN'                                   EPS    *
     *                                                       *
     *     02/26/79 CHANGE FORM OF CONSTANT TO HAVE PTR TO   *
     *     'STRCONST' INSTEAD OF CONTAINING THE LITERAL      *
     *     STRING IN THE RECORD. SAVES SPACE AND ALLOWS      *
     *     MAX STRING LITERAL SIZE TO BE BIGGER (NOW 64)     *
     *                                                EPS    *
     *     FIXIBM SHELL FILE FOR TRANSPORTATION TO IBM/370   *
     *                                                EPS    *
     *                                                       *
     *     03/30/79 ADDED FACILITY FOR COUNTING EXECUTION    *
     *     UNITS FOR PROFILING BY A DEBUG PROGRAM.  UNITS    *
     *     CALLED 'EXECUTION ENTITIES' ARE COUNTED BY        *
     *     'LSC N' OR 'ISC' P-CODE STATEMENTS. THESE ENTITIES*
     *     ARE PRIMITIVE STATEMENTS (CALL,ASSIGN,GOTO,EXIT)  *
     *     OR LOOP HEADER COMPUTATIONS (CASE,FOR) OR THE     *
     *     BOOLEAN EXPR COMPUTATION IN (WHILE,IF,REPEAT)     *
     *     CHANGES: IN 'STATEMENT' TO CALL GENKOUNT          *
     *             IN ENDOFLINE TO DELAY PRINTING LINE       *
     *                          TO PRINT 'ENTITY' # FOR LINE *
     *             IN MAIN TO REFLECT CHANGES IN ENDOFLINE   *
     *     ADDITION: OF VARIABLES KOUNT,KOUNTERS,HOLDKOUNT,  *
     *                     AND FIRSTKOUNT                    *
     *               OF PROC GENKOUNT               EPS      *
     *                                                       *
     *     04/16/79 CHANGE IN THE WAY VARIABLE OFFSETS ARE   *
     *     GENERATED: PARAMETERS ARE POSITIVE OFFSETS        *
     *     (RELATIVE TO THE "FRAME POINTER") AND LOCAL       *
     *     VARIABLES ARE MINUS OFFSETS.             EPS      *
     *                                                       *
     *     04/17/79 HANDLING OF STRUCTURED NON-VAR PARAMETERS*
     *     CHANGED:  THEY ARE NOW LOADED DIRECTLY ONTO       *
     *     THE STACK BY THE CALLER (1 INSTRUCTION IN         *
     *     MOTOROLA P-CODE) RATHER THE OLD WAY OF CALLER     *
     *     LOADING PARAMETER ADDRESS ON STACK AND CALLEE     *
     *     COPYING THE STRUCTURED VALUE TO LOCAL STORAGE     *
     *                                              EPS      *
     *                                                       *
     *     04/17/79 STRUCTURED FUNCTION VALUES ALLOWED.      *
     *     SPACE IS ALLOCATED ON THE STACK BEFORE PARAMS     *
     *     ARE PUSHED (BY AST P-INSTRUCTION) FOR ARBITRARY   *
     *     SIZED FUNCTION VALUE                     EPS      *
     *                                                       *
     *     05/02/79 DISPOSE ADDED, 'NEW1' NOW CALLED         *
     *     'NEWDISPOSE'                             EPS      *
     *                                                       *
     *     05/03/79 HANDLING OF FILES COMPLETELY RESTRUCTURED*
     *     FILES IN HEADER ARE CHAINED ON 'FEXTFILEP'.       *
     *     FILES IN HEADER MUST BE DECLARED IN OUTERMOST     *
     *     LEVEL. INPUT AND OUTPUT MUST NOT BE DECL'D BUT    *
     *     MUST APPEAR IN HEADER IF THEY ARE USED.           *
     *     FILES ARE DECL'D IN LOCAL SCOPES AND OPENED       *
     *     (WITH 'IFD') AND CLOSED (WITH 'CLO') IN THAT      *
     *     SCOPE. UNDECL'D FILES FROM HEADER GENERATE        *
     *     ERROR MESSAGE.  FILE COMPONENTS CAN BE ANY TYPE   *
     *     NOT RESTRICTED TO 'CHAR'                 EPS      *
     *                                                       *
     *     05/04/79 EXTERNAL PROC/FUNCS IMPLEMENTED.         *
     *     'FORWARD' DEFINED PROCEDURES AND FUNCTIONS ARE    *
     *     NOW FLAGGED IF NOT LATER DEFINED IN THE SAME      *
     *     SCOPE.  'FORWARD' DEFINED PROC/FUNCS AT GLOBAL    *
     *     LEVEL ARE ASSUMED TO BE EXTERNAL REFERENCES, AND  *
     *     THEY GENERATE "$N DEF 'PROCFUNCNAME' " IN THE     *
     *     OUTPUT FILE (AS WELL AS A WARNING IN THE LISTING) *
     *                                              EPS      *
     *     05/09/79 SUBPROGRAM CONCEPT (FOR SEPARATE         *
     *     COMPILATION) IMPLEMENTED.  SOURCE FILES BEGINNING *
     *     WITH 'SUBPROGRAM' ARE COMPILED. THEY MAY NOT HAVE *
     *     A MAIN PROGRAM BODY.  THE LAST INNER PROC/FUNC    *
     *     BODY ENDS WITH '.' INSTEAD OF ';'        EPS      *
     *                                                       *
     *     06/13/79 MACHINE M OPTION NOW SETS ALIGNMENT SIZE.*
     *     SMALL OBJECTS (BOOL,CHAR) NOW ALLOCATED THE       *
     *     MINIMUM SPACE REQ'D SUBJECT TO ALIGNMENT RULES    *
     *     OF THE TARGET MACHINE(BELOW).                     *
     *                                                       *
     *     IN THE CASE OF A BYTE ALIGNED MACHINE (6809) ALL  *
     *     OBJECTS TAKE THE MINIMUM NUMBER OF BYTES REGARD-  *
     *     LESS OF COMPOSITION.  IN THE CASE OF WORD ALIGNED *
     *     MACHINE (68000) ANY OBJECT THAT IS 2 BYTES OR     *
     *     BIGGER IS WORD ALIGNED (AND SUB-OBJECTS, SUCH     *
     *     AS RECORDS WITHIN RECORDS, FOLLOW THE SAME RULE.) *
     *                                                       *
     *     OBJECTS IN STATIC STORAGE TAKE THE MINIMUM SPACE  *
     *     SUBJECT TO THE ABOVE RULES.  OBJECTS IN DYNAMIC   *
     *     STORAGE (HEAP) SHOULD BE NEW'ED ON ALIGNMENT      *
     *     BOUNDARIES SINCE THEIR INTERNAL ALIGNMENT IS NOT  *
     *     KNOWN AT RUNTIME. PARAMETER OBJECTS FOR 68000 ARE *
     *     CURRENTLY ALL ALIGNED ON WORD BOUNDARIES REGARD-  *
     *     LESS OF SIZE, BECAUSE OF THE STACK POINTER        *
     *     ALIGNMENT RESTRICTION ON THE 68000.  SLIGHTLY     *
     *     MORE EFFICIENT STORAGE OF PARAMETERS IS POSSIBLE  *
     *     (WITH CONSIDERABLY MORE WORK.)          EPS       *
     *                                                       *
     *     7/29/79  STRING FACILITY IMPLEMENTED.  A NEW      *
     *     TYPE CONSTRUCTOR "STRING" IS RECOGNIZED. DECL'S   *
     *     TAKE THE FORM "VARIABLENAME: STRING(.INTEGER.);"    *
     *     THE INTEGER INDICATES THE MAXIMUM SIZE IN CHARS   *
     *     THAT THE STRING WILL TAKE.  SIZE+1 BYTES ARE      *
     *     ALLOCATED FOR STRING STORAGE; THE FIRST BYTE      *
     *     BEING USED TO HOLD THE CURRENT STRING LENGTH AT   *
     *     RUN-TIME.  STRINGS MAY BE INDEXED TO OBTAIN       *
     *     INDIVIDUAL CHARACTERS ("STRINGVAR(.N.)" IS THE NTH  *
     *     CHAR OF STRINGVAR).  STRINGS ARE ASSIGNABLE TO    *
     *     PACKED ARRAY OF CHAR BUT NOT VICE VERSA.  STRINGS *
     *     ARE COMPATIBLE WITH OTHER STRINGS REGARDLESS OF   *
     *     SIZE. MANIFEST STRING CONSTANTS ARE STRINGS.      *
     *                                              EPS      *
     *     07/25/79  BUILTIN FUNCTIONS AND PROCEDURES CAN    *
     *     NOW BE REDEFINED BY THE USER PROGRAM     EPS      *
     *                                                       *
     *     07/27/79 LINES MARKED '%MOTO' ARE REMOVED BY      *
     *     FIXMOTO SHELL FILE FOR TRANSPORTATION TO PHOENIX  *
     *                                                EPS    *
     *                                                       *
     *     08/15/79 READ AND WRITE OF NON-TEXT FILES  EPS    *
     *                                                       *
     * NEXT COMMENT                                          *
     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++ *)



   PROGRAM PASCALCOMPILER(OUTPUT, SOURCE, PCODE, LISTING);


   CONST
         VERSION      = ' 1.10';
         M6809        = 1;
         M68000       = 2;
         MACHINE      = M68000;

         DISPLIMIT    = 20;     MAXLEVEL   = 8;
         MINADDR      =-32000;  MAXADDR    = 32000 ;
         MAXINTEGER   = 32767;

         INT2SIZE     = 2;      REALSIZE   = 4;
         INT1SIZE     = 1;      INT4SIZE   = 4;
         CHARSIZE     = 1;      BOOLSIZE   = 1;
         SETSIZE      = 8;

         LASTRESWD    = 40;     NEXTRESWD  = 41 ;
         STRGLNGTH    = 64;     ORDMAXCHAR =127 (*WAS 63  EPS*);
         REALLNGTH    = 11;
         DIGMAX       = 11 ;    (*=REALLNGTH*)
         IDLNGTH      =  8 ;    (*SIZE OF TYPE ALPHA*)
         SETRANGE     = 63 ;
         LINELGTH     = 133;    (*CHANGED FROM 81  EPS*)
         MAXLABEL     = 4000;   (* MAXIMUM NUMBER OF LABELS *)
         PAGEDEFAULT  = 76;     (* DEFAULT TOTAL LENGTH OF A PAGE *)
         ENDOFPAGE    = 76;     (* DEFAULT END OF PAGE *)
         STARTPAGE    = 77;     (* START PAGE POS HERE (MDOS = 66) *)
         WIDTHDEFAULT = 132;    (* DEFAULT PAGE WIDTH TO 132 COLUMNS *)
         LMARGIN      = 21;     (* WIDTH OF THE LEFT MARGIN IN LISTING FILE *)
         ORDMAXBASECHAR = 255;  (* ORD OF MAX CHAR IN BASE CHAR TYPE *)
                                (* 255 FOR EBCDIC, 127 FOR ASCII    *)
         SYSTEM       = 0;
         USER         = 1;


   TYPE                                                        (* DESCRIBING: *)
                                                               (* +++++++++++ *)

                                                               (* BASIC SYMBOLS
*)                                                             (* +++++++++++++
*)
        SYMBOL = (IDENT,INT1CONST,INT2CONST,INT4CONST,REALCONST,STRINGCONST,NOTS
Y,                MULOP,ADDOP,RELOP,LPARENT,RPARENT,LBRACK,RBRACK,COMMA,SEMICOLO
N,                PERIOD,ARROW,COLON,RANGE,BECOMES,LABELSY,CONSTSY,TYPESY,VARSY,
                  FUNCSY,PROGSY,PROCSY,SETSY,PACKEDSY,ARRAYSY,RECORDSY,FILESY,
                  FORWARDSY,BEGINSY,IFSY,CASESY,REPEATSY,WHILESY,FORSY,WITHSY,
                  GOTOSY,ENDSY,ELSESY,UNTILSY,OFSY,DOSY,TOSY,DOWNTOSY,
                  THENSY,OTHERSY,OTHERWZSY,EXITSY,ORIGINSY,STRINGSY,SUBPROGSY);

        OPERATOR = (MUL,RDIV,ANDOP,IDIV,IMOD,PLUS,MINUS,OROP,LTOP,LEOP,GEOP,GTOP
,                   NEOP,EQOP,INOP,NOOP);

        (* THE FOLLOWING IS AN ENUMERATED TYPE OF STANDARD NAMES, EXCLUDING *)
        (* INPUT AND OUTPUT.  THEY ARE ARRANGED IN THE FOLLOWING ORDER:     *)
        (* CONSTANTS FIRST, TYPES SECOND, FUNCTIONS THIRD, AND PROCEDURES   *)
        (* LAST.  WITHIN EACH CLASS, THE INDIVIDUAL NAMES ARE ARRANGED IN   *)
        (* THE ORDER IN WHICH THEY WILL GO INTO THE TREE - TO HELP BALANCE  *)
        (* IT.                                                              *)

        STDNAMES = (XMAXINT,    XFALSE,     XTRUE,      XNIL,
                    XTEXT,      XCHAR,      XREAL,      XINTEGER,
                    XBOOLEAN,   XODD,       XEOLN,      XCONCAT,
                    XLENGTH,    XDELETE,    XPOS,       XSQR,
                    XARCTAN,    XCHR,       XCOPY,      XLN,
                    XPOSITION,  XROUND,     XSQRT,      XABS,
                    XCLOCK,     XCOS,       XEOF,       XEXP,
                    XINSERT,    XORD,       XPRED,      XSIN,
                    XSUCC,      XTRUNC,     XREWRITE,   XPUT,
                    XHALT,      XUNPACK,    XDISPOSE,   XNEW,
                    XPACK,      XREAD,      XRELEASE,   XWRITE,
                    XGET,       XMARK,      XPAGE,      XREADLN,
                    XRESET,     XWRITELN                             );

        SETOFSYS = SET OF SYMBOL;
                        (*POTENTIAL PORTABILITY PROBLEM: SET OF 54 ELEMENTS*)

           CHTYP = (ATOZ, NUMBER, STRQUOTE, COLONCHAR, PERIODCHAR,
                   LPOINTY, RPOINTY, LPARN, MISCCHAR,
                   CMNTBRACK,BLANKCHAR, ILLEGALCHAR);

         LNGINT =  PACKED ARRAY (.1..4.) OF INTEGER;

         LNGRELATION = (LNGLESS,LNGEQUAL,LNGGREATER);



                                                               (* CONSTANTS *)
                                                               (* +++++++++ *)

        CSTCLASS = (LINT,REEL,PSET,STRG);

        SETCONST = SET OF 0..SETRANGE;
               (*POTENTIAL PORTABILITY PROBLEM: SET OF 64 ELEMENTS*)
        STRCONST = PACKED ARRAY (.1..STRGLNGTH.) OF CHAR;

        CSP = @ CONSTANT;
        CONSTANT = RECORD CASE   CSTCLASS OF
                            LINT: (LINTVAL:  LNGINT);
                            REEL: (RVAL: PACKED ARRAY (.0..REALLNGTH.) OF CHAR);
                            PSET: (PVAL: SETCONST );
                            STRG: (SLNGTH: 0..STRGLNGTH;
                                   SVAL: @STRCONST)
                          END;

        VALU = RECORD CASE (*INTVAL:*) BOOLEAN OF (*INTVAL NEVER SET NOR TESTED*
)                       TRUE:  (IVAL: INTEGER);
                        FALSE: (VALP: CSP)
                      END;

                                                         (* DATA STRUCTURES *)
                                                         (* +++++++++++++++ *)
        MNRANGE = 0..118;
        ADDRRANGE = MINADDR..MAXADDR;
        LEVRANGE  = 0..MAXLEVEL;
        LABELRNG  = 0..MAXLABEL ;
        STRUCTFORM = (SCALAR,SUBRANGE,POINTER,POWER,STRINGS,ARRAYS,RECORDS,
                      FILES,TAGFLD,VARIANT); (*ORDER OF ELEMENTS IS IMPORTANT*)

        CTP = @IDENTIFIER;
        STP = @STRUCTURE;
        STRUCTURE = PACKED RECORD
                      SIZE: ADDRRANGE;
                      CASE FORM: STRUCTFORM OF
                        SCALAR:   (FCONST: CTP);
                        SUBRANGE: (RANGETYPE: STP; MIN,MAX: VALU);
                        POINTER:  (ELTYPE: STP);
                        POWER:    (ELSET: STP);
                       (*STRINGS:  ();*)
                        ARRAYS:   (AELTYPE,INXTYPE: STP);
                        RECORDS:  (FSTFLD: CTP; RECVAR: STP);
                        FILES:    (FILTYPE: STP);
                        TAGFLD:   (TAGFIELDP: CTP; FSTVAR: STP);
                        VARIANT:  (NXTVAR,SUBVAR: STP; VARVAL: VALU)
                      END;

                                                               (* NAMES *)
                                                               (* +++++ *)

        IDCLASS = (TYPES,LABELS,KONST,VARS,FIELD,PROC,FUNC);
        SETOFIDS = SET OF IDCLASS;
        IDKIND = (ACTUAL,FORMAL,ORIGINED);
        ALPHA = PACKED ARRAY(.1..IDLNGTH.) OF CHAR;(*SIZE(ALPHA) MUST=IDLNGTH*)
        DECLKIND = (BUILTIN,DECLARED);

        IDENTIFIER = PACKED RECORD
                      NAME: ALPHA; LLINK, RLINK: CTP;
                      IDTYPE: STP; NEXT: CTP;
                      CASE KLASS: IDCLASS OF
                  (*      TYPES,LABELS: ( ); NOT ALLOWED BY AMSTERDAM  EPS *)
                  (*                               REQ'D BY BERKELEY   EPS *)
                        KONST: (VALUES: VALU);
                         VARS:  (VKIND: IDKIND; EXTRNL: BOOLEAN;
                                VLEV: LEVRANGE; VADDR: LNGINT);
                        FIELD: (FLDADDR: ADDRRANGE);
                        PROC,
                        FUNC:  (CASE PFDECKIND: DECLKIND OF
                                 BUILTIN: (KEY: STDNAMES);
                                 DECLARED: (PFLEV: LEVRANGE; PFNAME: LABELRNG;
                                            PFADDR: ADDRRANGE;
                                             CASE PFKIND: IDKIND OF
                                              (*ORIGINED, FORMAL: ( ); *)
                                   (*ABOVE NOT ALLOWED BY AMSTERDAM  EPS *)
                                   (*         BUT REQ'D BY BERKELEY  EPS *)
                                               ACTUAL: (FORWDECL(*, EXTERN*):
                                                        BOOLEAN)))
                      END;


        DISPRANGE = 0..DISPLIMIT;
        WHERE = (BLCK,CREC,VREC,REC);

                                                               (* EXPRESSIONS *)
                                                               (* +++++++++++ *)
        ATTRKIND = (CST,VARBL,FILEPTR,EXPR);
        VACCESS = (DRCT,INDRCT);

         ATTR = RECORD TYPTR : STP;
                 CASE KIND: ATTRKIND OF
                   CST:   (CVAL: VALU);
              (*    EXPR:  ( );    NOT ALLOWED BY AMSTERDAM  EPS *)
              (*                         REQ'D BY BERKELEY   EPS *)
                   VARBL,FILEPTR: (CASE ACCESS: VACCESS OF
                             DRCT: (VLEVEL: LEVRANGE; DPLMT: ADDRRANGE);
                             INDRCT: (IDPLMT: ADDRRANGE) )
                 END;

        TESTP = @ TESTPOINTER;
        TESTPOINTER = PACKED RECORD
                        ELT1,ELT2 : STP;
                        LASTTESTP : TESTP
                      END;

                                                                    (* LABELS *)
                                                                    (* ++++++ *)
        LBP = @ LABL;
        LABL = RECORD NEXTLAB: LBP;
                      DEFINED: BOOLEAN;
                      LABNO: LABELRNG;
                      CASE ALF:BOOLEAN OF
                        FALSE:(LABVAL: INTEGER);
                        TRUE: (LABNAME: ALPHA )
               END;

        LOOPPTR = @LOOPLABL;

        LOOPLABL = RECORD LABNO: LABELRNG; (*ENTRY ON STACK OF LOOPEXIT LABELS*)
                          ASSOCLAB: LBP;
                          NEXTLOOP: LOOPPTR;
                          USED: BOOLEAN
                   END;

        EXTFILEP = @FILEREC;
        FILEREC = RECORD FILENAME:ALPHA;
                         NEXTFILE:EXTFILEP;
                         POS: INTEGER;
                         DEF:BOOLEAN
                  END;

   (* -------------------------------------------------------------------------
*)

   VAR

      SOURCE,
      PCODE,
      LISTING: FILE OF CHAR;
                    (*NOT ALLOWED BY AMSTERDAM; REQ'D BY MOTO AND TSO*)


                                       (* RETURNED BY SOURCE PROGRAM SCANNER
                                        INSYMBOL:
                                        +++++++++ *)

       SY: SYMBOL;                     (* LAST SYMBOL *)
       OP: OPERATOR;                   (* CLASSIFICATION OF LAST SYMBOL *)
       CH: CHAR;                       (* LAST CHARACTER READ *)
       EOL: BOOLEAN;                   (* END OF LINE FLAG *)

       DOUBLECHAR:  BOOLEAN;           (*DOUBLE CHAR FOUND IN NUMBER FLAG*)
       DOUBLESYM:   SYMBOL;            (*SYMBOL TYPE OF DOUBLE CHAR FOUND*)


                                       (* COUNTERS: *)
                                       (* +++++++++ *)

       CHCNT:  0..LINELGTH;            (* CHARACTER COUNTER *)
       LINELEN:1..LINELGTH;            (* LENGTH OF CURRENT LINE *)
       LOCN,IC,OLDIC: ADDRRANGE ;      (* DATA LOCATION AND INSTRUCTION COUNTER
*)     LINECOUNT,I: INTEGER;
       INTLABEL,                      (* LABEL NUMBER *)
       PROCLAB: LABELRNG;           (* PROCEDURE LABEL NUMBER *)

       ERRORCOUNT:INTEGER ;            (* TOTAL ERROR COUNT *)
       WARNCOUNT:INTEGER ;
       ERRORS, WARNINGS: BOOLEAN;

       GATTR: ATTR;                    (* DESCRIBES THE EXPR CURRENTLY COMPILED
*)     VAL: VALU;                      (* VALUE OF LAST CONSTANT *)
       LNGTH: INTEGER;                 (* LENGTH OF LAST STRING CONSTANT *)
       ID, BLANKID, PROGNAME: ALPHA;   (* LAST IDENTIFIER (POSSIBLY TRUNCATED) *
)
                                       (* SWITCHES: *)
                                       (* +++++++++ *)
       LONGONLY,                       (*LONG INTEGER ONLY ALLOWED IN INSYMBOL*)
       SUBPROG,
       DP,                             (* DECLARATION PART *)
       PRTERR,                         (* TO ALLOW FORWARD REF IN PTR VARIABLES
*)     ASSIGN,                         (* DECLARATION BY SUPPRESSING ERROR MSG *
)      LIST,                           (* SOURCE PROGRAM LISTING OPTION *)
       PLIST,                          (* INCLUDE SOURCE IN PCODE OPTION *)
       PRCODE,                         (* PRODUCE PCODE OPTION *)
       DEBUG,                          (* PRODUCE RANGE CHECKING *)
       KOUNTERS,                       (* PRODUCE LINE COUNTING CODE OPTION *)
       PKOUNTERS,                      (* PRODUCE PROCEDURE COUNTING CODE OPT *)
       STANDARD: BOOLEAN;              (* PRINT WARNINGS IF NON STANDARD OPTION
*)
       JUMPENTRIES:    INTEGER;        (*# OF JUMP TABLE ENTRIES*)
       JUMPBASE,                       (*JUMP TABLE BASE ADDRESS*)
       HEAPSTART,                      (*HEAP START ADDRESS*)
       STACKSTART:     LNGINT;         (*STACK START (TOP) ADDRESS*)

       ADDRSIZE, ALIGNMENT:INTEGER;
                       (* SET BY THE OPTION 'M' TO 2 OR 4 DEPENDING ON
                         ADDRESS SIZE (BYTES) OF TARGET *)


       PAGENUM,                        (* LISTING FORMAT VARIABLES *)
       PAGEPOS,
       LINEWIDTH,
       PAGEEND,
       PAGELEN,
       LASTERR: INTEGER;

       BLEV, MLEV: CHAR;               (* BLOCK NESTING ACCOUNTING VARS *)
       SBLOCK,
       EBLOCK: BOOLEAN;

       KOUNT,
       MINKOUNT: INTEGER;              (* STATEMENT COUNTING VARIBLES *)

       PRINTKOUNT,
       LABELEDKOUNT: BOOLEAN;

       ARITHMETICSIZE:  CHAR;          (* SIZE OF INTEGER ARITHMETIC *)

                                       (* POINTERS: *)
                                       (* +++++++++ *)
       INT1PTR,INT2PTR,INT4PTR,
       REALPTR,CHARPTR,
       BOOLPTR,NILPTR,TEXTPTR: STP;  (* POINTERS TO ENTRIES OF STANDARD IDS *)

       SINGLECHARSTRING: STP;  (* POINTER TO RESULT OF CONVERTING CHAR TO STR *)

       UTYPPTR,UCSTPTR,UVARPTR,
       UFLDPTR,UPRCPTR,UFCTPTR,      (* POINTERS TO ENTRIES FOR UNDECLARED IDS*)
       ULABPTR,FWPTR:CTP;            (* HEAD OF CHAIN OF FORW DECL TYPE IDS *)

       STDINPUT,STDOUTPUT: CTP;      (* POINTERS TO DEFAULT FILES FOR READ,WRITE
 *)
       GLOBFILELIST: CTP;
       FEXTFILEP: EXTFILEP;          (* HEAD OF CHAIN OF EXTERNAL FILES *)
       GLOBTESTP: TESTP;             (* LAST TESTPOINTER *)

       CNSTVALPTR : CSP ;            (* POINTERS TO CURRENT STRING/REAL CNST*)
       CNSTSTRPTR : @STRCONST;


                                     (* BOOKKEEPING OF DECLARATION LEVELS: *)
                                       (* ++++++++++++++++++++++++++++++++++ *)

       LEVEL: LEVRANGE;                (* CURRENT STATIC LEVEL *)

       STKSIZES:  ARRAY (.LEVRANGE.)  (*MAX STACK SIZE OF EACH STATIC LEVEL*)
                     OF INTEGER;

       DISX,                           (* LEVEL OF LAST ID SEARCHED BY SEARCHID
*)     TOP: DISPRANGE;                 (* TOP OF DISPLAY *)

       DISPLAY:                        (* WHERE:   MEANS: *)
         ARRAY (.DISPRANGE.) OF
           PACKED RECORD               (* =BLCK: ID IS VARIABLE ID *)
             FNAME: CTP; FLABEL: LBP;  (* =CREC: ID IS FIELD ID IN RECORD WITH*)
             CASE OCCUR: WHERE OF      (*          CONSTANT ADDRESS *)
               CREC: (CLEV: LEVRANGE;  (* =VREC: ID IS FIELD ID IN RECORD WITH*)
                     CDSPL: ADDRRANGE);(*          VARIABLE ADDRESS *)
               VREC: (VDSPL: ADDRRANGE)
             END;                      (*  --> PROCEDURE WITHSTATEMENT *)


                                       (* ERROR MESSAGES: *)
                                       (* +++++++++++++++ *)

       ERRINX: 0..10;                  (* NR OF ERRORS IN CURRENT SOURCE LINE *)
       ERRLIST:
         ARRAY (.1..10.) OF
           PACKED RECORD POS: 0..LINELGTH;
                         NMR: 1..999
                  END;


                                       (* STRUCTURED CONSTANTS: *)
                                       (* +++++++++++++++++++++ *)

       LONGZERO,                       (*LONG ZERO VALUE*)
       LINT1MIN,LINT1MAX,
       LINT2MIN,LINT2MAX,
       LINT4MIN,LINT4MAX,
       LONGORDMAXCHAR:  LNGINT;        (*LONG VALUE OF ORDMAXCHR*)

        LINEBUF: ARRAY(.0..LINELGTH.) OF CHAR ; (* CURRENT LINE BUFFER *)

       CONSTBEGSYS,SIMPTYPEBEGSYS,TYPEBEGSYS,BLOCKBEGSYS,SELECTSYS,FACBEGSYS,
       STATBEGSYS,TYPEDELS,LOOPBEGSYS: SETOFSYS;

       RW:  ARRAY (.0..LASTRESWD(* NR. OF RES. WORDS *).) OF ALPHA;
       FRW: ARRAY (.0..14.) OF 1..NEXTRESWD(* NR. OF RES. WORDS + 1 *);
       RSY: ARRAY (.0..LASTRESWD(* NR. OF RES. WORDS *).) OF SYMBOL;
       SSY: ARRAY (.CHAR.) OF SYMBOL;
       ROP: ARRAY (.0..LASTRESWD(* NR. OF RES. WORDS *).) OF OPERATOR;
       SOP: ARRAY (.CHAR.) OF OPERATOR;
       MN:  ARRAY (.MNRANGE.) OF PACKED ARRAY (.1..4.) OF CHAR;
       UPPER: ARRAY(.CHAR.) OF CHAR;   (*  INSYMBOL UPPERCASE TABLE  *)
       ASCII: ARRAY(.CHAR.) OF INTEGER;
       CHTAB: ARRAY(.CHAR.) OF CHTYP;  (*  INSYMBOL DIRECTOR TABLE   *)

       HEADER: PACKED ARRAY (. 1..29 .) OF CHAR; (* HEADER MESSAGE & DATE *)
       EOFMESSAGE: PACKED ARRAY (. 1..35 .) OF CHAR; (* EOF MESSAGE *)
       STARS: PACKED ARRAY (. 1..5 .) OF CHAR;   (* 4 STARS *)
       ERRMES: PACKED ARRAY (. 1..9 .) OF CHAR;  (* **ERROR-- MESSAGE *)

   (*----------------------------------------------------------------------
      FUNCTION USUCC
     -----------------------------------------------------------------------*)

   FUNCTION USUCC(C: CHAR): CHAR; (* UNIVERSAL SUCCSESOR FUNCTION *)

      BEGIN
         IF (C <> 'I') AND (C <> 'R') THEN
            USUCC := SUCC(C)
         ELSE IF C = 'I' THEN
            USUCC := 'J'
         ELSE IF C = 'R' THEN
            USUCC := 'S'
      END;

   (*---------------------------------------------------------
      FUNCTION UPRED
     ----------------------------------------------------------*)

   FUNCTION UPRED(C: CHAR): CHAR; (* UNIVERSAL PREDISESOR FUNCTION *)

      BEGIN
         IF (C <> 'J') AND (C <> 'S') AND (C <> 'A') THEN
            UPRED := PRED(C)
         ELSE IF C = 'J' THEN
            UPRED := 'I'
         ELSE IF C = 'S' THEN
            UPRED := 'R'
         ELSE
            UPRED := C
      END;

   (*-------------------------------------------------------------------
      PROCEDURE NEWPAGE
     --------------------------------------------------------------------*)

   PROCEDURE NEWPAGE;

      VAR
         I: INTEGER;

      BEGIN
         PAGENUM := PAGENUM + 1;

         FOR I := PAGEPOS TO PAGELEN DO
            WRITELN(LISTING,' ');

         WRITE(LISTING,'LINE   LOC LEV BE ':20,HEADER,VERSION);
         WRITELN(LISTING,'PAGE ':(LINEWIDTH - 64),PAGENUM:0);
         WRITELN(LISTING,' ');

         PAGEPOS := 3
      END;

   (*-----------------------------------------------------------------
      PROCEDURE WRITELINE
     ------------------------------------------------------------------*)

   PROCEDURE WRITELINE;

      VAR
         I,LINESIZE: INTEGER;

      BEGIN  (* WRITELINE *)
         IF PAGEPOS > PAGEEND THEN
            NEWPAGE
         ELSE IF ERRORS OR WARNINGS THEN
            IF PAGEPOS > PAGEEND - 2 THEN
               NEWPAGE;

         WRITE(LISTING,LINECOUNT:6);
         IF DP THEN
            WRITE(LISTING,'(',LOCN:6,')')
         ELSE IF PRINTKOUNT THEN
            WRITE(LISTING, MINKOUNT:7,' ')
         ELSE
            WRITE(LISTING, ' ':8);

         WRITE(LISTING,LEVEL:2,')');

         IF SBLOCK THEN
            WRITE(LISTING, MLEV)
         ELSE
            WRITE(LISTING, '-');
         IF EBLOCK THEN
            WRITE(LISTING, BLEV,' ')
         ELSE
            WRITE(LISTING, '- ');

         IF LINELEN <= LINEWIDTH - LMARGIN THEN
            LINESIZE := LINELEN
         ELSE
            LINESIZE := LINEWIDTH - LMARGIN;

         FOR I := 1 TO LINESIZE DO
            WRITE(LISTING, LINEBUF(. I .));
         WRITELN(LISTING,' ');
         PAGEPOS := PAGEPOS + 1
      END;   (* WRITELINE *)

   (*------------------------------------------------------------------
      PROCEDURE PRINTERROR
     -------------------------------------------------------------------*)

   PROCEDURE PRINTERROR;

      VAR
         SECONDLINE: BOOLEAN;
         F,K,
         LASTPOS,
         FREEPOS,
         CURRPOS,
         CURRNMR: INTEGER;

      BEGIN  (* PRINTERROR *)

         IF NOT LIST THEN WRITELINE;
         IF ERRORS THEN
            WRITE(LISTING, ERRMES:11)
         ELSE
            WRITE(LISTING, '*WARNING-':11);
         WRITE(LISTING, LASTERR:6,'** ':3);

         LASTPOS := 0;
         FREEPOS := 1;
         SECONDLINE := FALSE;

         FOR K := 1 TO ERRINX DO
            BEGIN
               WITH ERRLIST(. K .) DO
                  BEGIN
                     CURRPOS := POS;
                     CURRNMR := NMR
                  END; (* WITH *)

               IF CURRNMR < 10 THEN
                  F := 1
               ELSE IF CURRNMR < 100 THEN
                  F := 2
               ELSE
                  F := 3;

               IF SECONDLINE THEN
                  BEGIN
                     WRITE(LISTING,',',CURRNMR:F);
                     FREEPOS := FREEPOS + F + 1
                  END
               ELSE IF ((CURRPOS = LASTPOS)
                        AND (FREEPOS + F + 1 > LINEWIDTH - LMARGIN))
                        OR (CURRPOS + F + 1 > LINEWIDTH - LMARGIN) THEN
                  BEGIN
                     IF K > 1 THEN
                        BEGIN
                           IF (CURRPOS = LASTPOS) THEN
                              WRITELN(LISTING,',')
                           ELSE
                              WRITELN(LISTING,' ');
                           PAGEPOS := PAGEPOS + 1;
                           WRITE(LISTING,'****CONTINUED**** ':20);
                           FREEPOS := 1
                        END;
                     WRITE(LISTING,CURRNMR:F);
                     FREEPOS := FREEPOS + F;
                     SECONDLINE := TRUE
                  END
               ELSE
                  BEGIN
                     IF CURRPOS = LASTPOS THEN
                        WRITE(LISTING,',')
                     ELSE IF CURRPOS <= FREEPOS THEN
                        WRITE(LISTING,'@')
                     ELSE
                        BEGIN
                           WRITE(LISTING,'@':(CURRPOS - FREEPOS + 1));
                           FREEPOS := CURRPOS
                        END;
                     WRITE(LISTING, CURRNMR:F);
                     FREEPOS := FREEPOS + F + 1
                  END;
               LASTPOS := CURRPOS;
            END; (* FOR K ... *)

         IF SECONDLINE THEN
            WRITELN(LISTING,'>')
         ELSE
            WRITELN(LISTING,' ');

         PAGEPOS := PAGEPOS + 1;

         LASTERR := LINECOUNT;
         ERRINX := 0;
         PRCODE := NOT ERRORS AND PRCODE;
         PLIST  := NOT ERRORS AND PLIST;
         ERRORS := FALSE;
         WARNINGS := FALSE
      END;    (* PRINTERROR *)


   (* -------------------------------------------------------------------------
      PROCEDURE ERROR
     ------------------------------------------------------------------------- *
)
     PROCEDURE ERROR(FERRNR: INTEGER);
     BEGIN
          ERRORS := TRUE;
          IF ERRINX >= 9 THEN
               BEGIN ERRLIST(.10.).NMR := 255; ERRINX := 10 END
          ELSE
               BEGIN ERRINX := ERRINX + 1;
               ERRLIST(.ERRINX.).NMR := FERRNR
          END;
          ERRLIST(.ERRINX.).POS := CHCNT ;
          ERRORCOUNT := ERRORCOUNT+1 ;
     END (* ERROR *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE WARNING
     ------------------------------------------------------------------------- *
)
     PROCEDURE WARNING(FERRNR: INTEGER);
     BEGIN
          WARNINGS := TRUE;
          IF ERRINX >= 9 THEN
               BEGIN ERRLIST(.10.).NMR := 255; ERRINX := 10 END
          ELSE
               BEGIN ERRINX := ERRINX + 1;
               ERRLIST(.ERRINX.).NMR := FERRNR
          END;
          ERRLIST(.ERRINX.).POS := CHCNT ;
          WARNCOUNT := WARNCOUNT+1 ;
     END (* ERROR *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE READLINE
     ------------------------------------------------------------------------- *
)
     PROCEDURE READLINE;

      VAR
         I: INTEGER;

      BEGIN  (* READLINE *)
         IF EOF(SOURCE) THEN
            BEGIN
               WRITELN(LISTING,EOFMESSAGE:45);
               WRITELN(OUTPUT, EOFMESSAGE:36);
               WRITELN(PCODE,'END':4);
   (*PP*)      HALT                          (* POSSIBLE PORTABILLITY PROBLEM *)
            END
         ELSE
            BEGIN
               LINELEN := 1;

               WHILE NOT EOLN(SOURCE) AND (LINELEN < LINELGTH) DO
                  BEGIN
                     READ(SOURCE, LINEBUF(. LINELEN .));
                     LINELEN := LINELEN + 1
                  END;
               READLN(SOURCE);
               CHCNT := 0;
               LINEBUF(. LINELEN .) := ' ';
               MINKOUNT := KOUNT;
               PRINTKOUNT := FALSE;

               MLEV := BLEV;
               SBLOCK := FALSE;
               EBLOCK := FALSE;
               LINECOUNT := LINECOUNT + 1;
               IF PLIST THEN
                  BEGIN
                     WRITE(PCODE,'.',' ':10);
                     FOR I := 1 TO LINELEN DO WRITE(PCODE,LINEBUF(. I .));
                     WRITELN(PCODE,' ')
                  END
            END (* ELSE *)
      END;   (* READLINE *)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  WRITELONG (FIL,LVAL)                             *)
   (*                                                                    *)
   (*        THIS PROCEDURE WRITES THE VALUE OF THE LONG INTEGER IN      *)
   (*        'LVAL' TO THE TEXT FILE 'FIL'.                              *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  WRITELONG (VAR FIL: TEXT;  LVAL: LNGINT);

      VAR
         I:  INTEGER;

      BEGIN (*WRITELONG*)

         FOR I := 4 DOWNTO 1 DO
            BEGIN
               WRITE (FIL,LVAL(.I.):1);
               IF I <> 1 THEN WRITE (FIL,', ')
            END (*FOR*)

      END; (*WRITELONG*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  OUTHEX (FIL,LVAL)                                *)
   (*                                                                    *)
   (*        THIS PROCEDURE OUTPUTS THE LONG INTEGER IN LVAL TO THE      *)
   (*        FILE FIL IN HEX FORMAT.                                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  OUTHEX (VAR FIL: TEXT;  LVAL: LNGINT);

      VAR
         I:    INTEGER;


      PROCEDURE  OUTBYTE (BYTE: INTEGER);

         PROCEDURE  OUTNIBBLE (NIBBLE: INTEGER);
            BEGIN (*OUTNIBBLE*)
               IF NIBBLE < 10
                  THEN  WRITE (FIL,CHR(ORD('0') + NIBBLE))
                  ELSE  WRITE (FIL,CHR(ORD('A') + NIBBLE - 10))
            END; (*OUTNIBBLE*)

         BEGIN (*OUTBYTE*)
            OUTNIBBLE (BYTE DIV 16);
            OUTNIBBLE (BYTE MOD 16)
         END; (*OUTNIBBLE*)

      BEGIN (*OUTHEX*)
         FOR I := 4 DOWNTO 1 DO
            OUTBYTE (LVAL(.I.))
      END; (*OUTHEX*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        FUNCTION  COMPLONGS (VAL1,VAL2): LNGRELATION                *)
   (*                                                                    *)
   (*        THIS FUNCTION COMPARES THE SIGNED VALUE REPRESENTED BY      *)
   (*        THE LONG INTEGER IN 'VAL1' TO THE SIGNED VALUE REPRESENTED  *)
   (*        BY THE LONG INTEGER IN 'VAL2'.                              *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   FUNCTION  COMPLONGS (VAL1,VAL2: LNGINT): LNGRELATION;

      VAR
         I:  INTEGER;

      BEGIN (*COMPLONGS*)
         IF (VAL1(.4.) >= 128) AND (VAL2(.4.) < 128)
            THEN  COMPLONGS  := LNGLESS
            ELSE
               IF (VAL1(.4.) < 128) AND (VAL2(.4.) >= 128)
                  THEN  COMPLONGS  := LNGGREATER
                  ELSE
                     BEGIN                 (*SIGNS ARE THE SAME - COMPARE THEM*)
                        I  := 5;

                        REPEAT
                           I  := I - 1
                        UNTIL (I = 1) OR (VAL1(.I.) <> VAL2(.I.));

                        IF VAL1(.I.) < VAL2(.I.)
                           THEN  COMPLONGS  := LNGLESS
                           ELSE
                              IF VAL1(.I.) = VAL2(.I.)
                                 THEN  COMPLONGS  := LNGEQUAL
                                 ELSE  COMPLONGS  := LNGGREATER
                     END (*ELSE*)
      END; (*COMPLONGS*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  ADDLONG (LONGVALUE,ADDVALUE,OVERFLOW)            *)
   (*                                                                    *)
   (*        THIS PROCEDURE ADDS THE INTEGER IN 'ADDVALUE' TO THE LONG   *)
   (*        INTEGER IN 'LONGVALUE'.  'OVERFLOW' IS RETURNED TRUE IF     *)
   (*        THE ADDITION RESULTED IN AN OVERFLOW.                       *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  ADDLONG (VAR LONGVALUE: LNGINT;  ADDVALUE: INTEGER;
                       VAR OVERFLOW: BOOLEAN);

      VAR
         I:      0..4;
         C:      INTEGER;
         TEMP:   INTEGER;

      BEGIN (*ADDLONG*)
         I  := 0;
         C  := ADDVALUE;

         REPEAT
            I     := I + 1;
            TEMP  := LONGVALUE(.I.) + C;
            C     := TEMP DIV 256;
            IF C > 0 THEN  TEMP  := TEMP MOD 256;
            LONGVALUE(.I.)  := TEMP
         UNTIL (I = 4) OR (C = 0);

         OVERFLOW  := C <> 0
      END; (*ADDLONG*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  MULTLONG (LONGVALUE,RADIX,OVERFLOW)              *)
   (*                                                                    *)
   (*        THIS PROCEDURE MULTIPLIES THE LONG INTEGER IN 'LONGVALUE'   *)
   (*        BY THE INTEGER IN 'RADIX'.  IF AN OVERFLOW OCCURS,          *)
   (*        'OVERFLOW' IS RETURNED TRUE.                                *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  MULTLONG (VAR LONGVALUE: LNGINT;  RADIX: INTEGER;
                        VAR OVERFLOW: BOOLEAN);

      VAR
         I:     1..4;
         C:     INTEGER;
         TEMP:  INTEGER;

      BEGIN (*MULTLONG*)
         C  := 0;

         FOR I := 1 TO 4 DO
            BEGIN
               TEMP  := LONGVALUE(.I.) * RADIX  +  C;
               C     := TEMP DIV 256;
               IF C > 0 THEN  TEMP  := TEMP MOD 256;
               LONGVALUE(.I.)  := TEMP
            END; (*FOR*)

         OVERFLOW  := C <> 0
      END; (*MULTLONG*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  ADD2LONGS (LVAL1,LVAL2,RVAL,OVERFLOW)            *)
   (*                                                                    *)
   (*        THIS PROCEDURE ADDS THE TWO LONG INTEGERS IN 'LVAL1' AND    *)
   (*        'LVAL2' AND PUTS THE RESULT IN 'RVAL'.  IF AN OVERFLOW      *)
   (*        OCCURS, 'OVERFLOW' IS RETURNED TRUE.                        *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  ADD2LONGS (LVAL1,LVAL2: LNGINT;  VAR RVAL: LNGINT;
                         VAR OVERFLOW: BOOLEAN);

      VAR
         I,C,R:   INTEGER;

      BEGIN (*ADD2LONGS*)
         C  := 0;                               (*INIT THE CARRY*)

         FOR I := 1 TO 4 DO
            BEGIN                               (*ADD A BYTE*)
               R          := LVAL1(.I.) + LVAL2(.I.) + C;
               C          := R DIV 256;
               RVAL(.I.)  := R MOD 256
            END; (*FOR*)

         OVERFLOW  := (C <> 0)                  (*SET UP OVERFLOW FLAG*)

      END; (*ADD2LONGS*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  RSHIFTLONG (LVAL,BITS)                           *)
   (*                                                                    *)
   (*        THIS PROCEDURE PERFORMS A LOGICAL SHIFT RIGHT OF THE LONG   *)
   (*        INTEGER IN 'LVAL' FOR 'BITS' BITS.                          *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  RSHIFTLONG (VAR LVAL: LNGINT;  BITS: INTEGER);

      VAR
         I,J,C:  INTEGER;

      BEGIN (*RSHIFTLONG*)

         FOR I := 1 TO BITS DO
            BEGIN                               (*SHIFT RIGHT ONE BIT*)
               LVAL(.1.)  := LVAL(.1.) DIV 2;

               FOR J := 2 TO 4 DO
                  BEGIN
                     C          := LVAL(.J.) MOD 2;
                     LVAL(.J.)  := LVAL(.J.) DIV 2;
                     IF C = 1 THEN  LVAL(.J - 1.)  := LVAL(.J - 1.) + 128
                  END (*FOR*)

            END (*FOR*)

      END; (*RSHIFTLONG*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  NEGLONG (LVAL)                                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE NEGATES (TWO'S COMPLEMENT) THE VALUE IN      *)
   (*        THE LONG INTEGER 'LVAL'.                                    *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  NEGLONG (VAR LVAL: LNGINT);

      VAR
         I:    INTEGER;
         B:    BOOLEAN;

      BEGIN (*NEGLONG*)
         B  := FALSE;                          (*INIT THE BORROW FLAG*)

         FOR I := 1 TO 4 DO
            IF B
               THEN  LVAL(.I.)  := 255 - LVAL(.I.)
               ELSE  IF LVAL(.I.) > 0 THEN     (*HAVE TO BORROW*)
                        BEGIN
                           LVAL(.I.)  := 256 - LVAL(.I.);
                           B          := TRUE
                        END (*THEN*)

      END; (*NEGLONG*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  MAKELONG (IVAL,LVAL)                             *)
   (*                                                                    *)
   (*        THIS PROCEDURE TURNS THE SIGNED INTEGER VALUE IN 'IVAL'     *)
   (*        INTO A SIGNED LONG INTEGER VALUE IN 'LVAL'.                 *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  MAKELONG (IVAL: INTEGER;  VAR LVAL: LNGINT);

      VAR  TEMP: INTEGER;

      BEGIN (*MAKELONG*)
         TEMP       := IVAL;

         IF TEMP < 0 THEN
            BEGIN                           (*MAKE IT POSITIVE*)
               TEMP  := TEMP + 32767;
               TEMP  := TEMP + 1
            END; (*THEN*)

         LVAL       := LONGZERO;
         LVAL(.2.)  := TEMP DIV 256;
         LVAL(.1.)  := TEMP MOD 256;

         IF IVAL < 0 THEN
            BEGIN                     (*MAKE IT NEGATIVE*)
               LVAL(.2.)  := LVAL(.2.) + 128;
               LVAL(.3.)  := 255;
               LVAL(.4.)  := 255
            END (*THEN*)
      END; (*MAKELONG*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        FUNCTION  MAKESHORT (LVAL): INTEGER                         *)
   (*                                                                    *)
   (*        THIS FUNCTION TURNS THE VALUE IN THE LONG INTEGER 'LVAL'    *)
   (*        INTO A REGULAR INTEGER.                                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   FUNCTION  MAKESHORT (LVAL: LNGINT): INTEGER;

      VAR
         NEG:    BOOLEAN;
         IVAL:   INTEGER;

      BEGIN (*MAKESHORT*)
         IF LVAL(.4.) >= 128
            THEN  BEGIN
                     NEGLONG (LVAL);
                     NEG  := TRUE
                  END (*THEN*)
            ELSE  NEG  := FALSE;

         IVAL  := LVAL(.2.) * 256  +  LVAL(.1.);

         IF NEG THEN  IVAL  := -IVAL;

         MAKESHORT  := IVAL
      END; (*MAKESHORT*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  INSYMBOL                                         *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS THE NEXT BASIC SYMBOL OF THE SOURCE     *)
   (*        PROGRAM AND RETURNS ITS DESCRIPTION IN THE GLOBAL           *)
   (*        VARIABLES 'SY', 'OP', 'ID', 'VAL', AND 'LNGTH'.             *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  INSYMBOL;

      VAR  SYMBOLGOTTEN:  BOOLEAN;            (*SYMBOL GOTTEN YET?*)




   (* -------------------------------------------------------------------------
      PROCEDURE NEXTCH
     ------------------------------------------------------------------------- *
)
      PROCEDURE NEXTCH;

         BEGIN (* NEXTCH *)
            IF EOL THEN
               BEGIN
                  IF LIST THEN WRITELINE;
                  IF ERRORS OR WARNINGS THEN PRINTERROR;
                  READLINE
               END;
            CHCNT := CHCNT + 1;
            EOL := (CHCNT = LINELEN);
            CH := LINEBUF (. CHCNT .)
         END;  (* NEXTCH *)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  OPTIONS                                          *)
   (*                                                                    *)
   (*        THIS PROCEDURE PROCESSES THE OPTIONS IN A COMMENT.          *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  OPTIONS;


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  COMMENTWARNING                                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE GENERATES A 511 WARNING IN AN OPTION         *)
   (*        COMMENT.  IT THEN SKIPS CHARACTERS UNTIL IT FINDS A         *)
   (*        COMMA, ASTERISK, OR RIGHT CURLY BRACE.                      *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  COMMENTWARNING;

      BEGIN (*COMMENTWARNING*)
         WARNING (511);

         WHILE (CH <> ',') AND (CH <> '*') AND (CH <> 'å') DO
            NEXTCH

      END; (*COMMENTWARNING*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETARITHMETICSIZE                                *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS THE SIZE OF INTEGER ARITHMETIC.         *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETARITHMETICSIZE;

      BEGIN (*GETARITHMETICSIZE*)
         NEXTCH;

         IF CH <> '='
            THEN  COMMENTWARNING
            ELSE
               BEGIN                         (*LOOK FOR A 1, 2, OR 4*)
                  NEXTCH;

                  IF CH = '1'
                     THEN  BEGIN
                              ARITHMETICSIZE  := 'H';
                              NEXTCH
                           END (*THEN*)
                     ELSE
                        IF CH = '2'
                           THEN  BEGIN
                                    ARITHMETICSIZE  := 'I';
                                    NEXTCH
                                 END (*THEN*)
                           ELSE
                              IF CH = '4'
                                 THEN  BEGIN
                                          ARITHMETICSIZE  := 'J';
                                          NEXTCH
                                       END (*THEN*)
                                 ELSE  COMMENTWARNING
               END (*ELSE*)

      END; (*GETARITHMETICSIZE*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETPLUSORMINUS (PLUSFLAG,ERR)                    *)
   (*                                                                    *)
   (*        THIS PROCEDURE LOOKS FOR A PLUS OR MINUS SIGN IN THE NEXT   *)
   (*        CHARACTER OF INPUT.  IF A PLUS SIGN IS FOUND, PLUSFLAG IS   *)
   (*        RETURNED TRUE.  IF A MINUS SIGN IS FOUND, PLUSFLAG IS       *)
   (*        RETURNED FALSE.  IF NEITHER IS FOUND, ERR IS RETURNED TRUE. *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETPLUSORMINUS (VAR PLUSFLAG,ERR: BOOLEAN);

      BEGIN (*GETPLUSORMINUS*)
         PLUSFLAG  := FALSE;
         ERR       := FALSE;
         NEXTCH;

         IF CH = '+'
            THEN  BEGIN
                     PLUSFLAG  := TRUE;
                     NEXTCH
                  END (*THEN*)
            ELSE  IF CH = '-'
                     THEN  NEXTCH
                     ELSE  BEGIN
                              ERR  := TRUE;
                              COMMENTWARNING
                           END (*ELSE*)

      END; (*GETPLUSORMINUS*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GET1PLUSORMINUS (FLAG)                           *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A PLUS OR MINUS SIGN AND ASSIGNS THE    *)
   (*        PROPER BOOLEAN VALUE TO 'FLAG'.                             *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GET1PLUSORMINUS (VAR FLAG: BOOLEAN);

      VAR
         PLUSFLAG,
         ERR:         BOOLEAN;

      BEGIN (*GET1PLUSORMINUS*)
         GETPLUSORMINUS (PLUSFLAG,ERR);
         IF NOT ERR THEN  FLAG  := PLUSFLAG
      END; (*GET1PLUSORMINUS*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GET2PLUSORMINUS (FLAG1,FLAG2)                    *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A PLUS OR MINUS FLAG FOR AN OPTION      *)
   (*        AND ASSIGNS THE PROPER BOOLEAN VALUE TO THE FLAGS 'FLAG1'   *)
   (*        AND 'FLAG2'.                                                *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GET2PLUSORMINUS (VAR FLAG1,FLAG2: BOOLEAN);

      VAR
         PLUSFLAG,
         ERR:         BOOLEAN;

      BEGIN (*GET2PLUSORMINUS*)
         GETPLUSORMINUS (PLUSFLAG,ERR);
         IF NOT ERR THEN
            BEGIN
               FLAG1  := PLUSFLAG;
               FLAG2  := PLUSFLAG
            END (*THEN*)
      END; (*GET2PLUSORMINUS*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETLINT (LVAL)                                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS AN '=<LONG INT>' IN AN OPTION COMMENT   *)
   (*        AND ASSIGNS IT TO 'LVAL'.                                   *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETLINT (VAR LVAL: LNGINT);

      BEGIN (*GETLINT*)
         NEXTCH;

         IF CH <> '='
            THEN  COMMENTWARNING
            ELSE
               BEGIN                      (*NOW LOOK FOR THE LINT*)
                  NEXTCH;
                  IF CHTAB(.CH.) <> NUMBER
                     THEN  COMMENTWARNING
                     ELSE
                        BEGIN             (*GET THE LINT*)
                           LONGONLY  := TRUE;
                           INSYMBOL;
                           LONGONLY  := FALSE;
                           IF SY <> INT4CONST
                              THEN  COMMENTWARNING
                              ELSE  LVAL  := VAL.VALP@.LINTVAL
                        END (*ELSE*)
               END (*ELSE*)

      END; (*GETLINT*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETINT (IVAL)                                    *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS AN '=<INTEGER>' IN AN OPTION COMMENT    *)
   (*        AND ASSIGNS IT TO 'IVAL'.                                   *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETINT (VAR IVAL: INTEGER);

      BEGIN (*GETINT*)
         NEXTCH;

         IF CH <> '='
            THEN  COMMENTWARNING
            ELSE
               BEGIN
                  NEXTCH;
                  IF CHTAB(.CH.) <> NUMBER
                     THEN  COMMENTWARNING
                     ELSE
                        BEGIN
                           INSYMBOL;
                           IF (SY <> INT1CONST) AND (SY <> INT2CONST)
                              THEN  COMMENTWARNING
                              ELSE  IVAL  := VAL.IVAL
                        END (*ELSE*)
               END (*ELSE*)

      END; (*GETINT*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETMACHINETYPE                                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS THE MACHINE TYPE FROM AN OPTION         *)
   (*        COMMENT.                                                    *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETMACHINETYPE;

      VAR
         MACHINENUM: 1..2;

      BEGIN (*GETMACHINETYPE*)
         MACHINENUM := MACHINE;
         NEXTCH;

         IF CH = '2'
            THEN  BEGIN                    (*MAKE SURE 'M20'*)
                     NEXTCH;
                     IF CH <> '0'
                        THEN  COMMENTWARNING
                        ELSE
                           BEGIN
                              NEXTCH;
                              MACHINENUM := M68000;
                           END;
                  END (*THEN*)
            ELSE
               IF CH <> '0'                (*MAKE SURE 'M09'*)
                  THEN  COMMENTWARNING
                  ELSE
                     BEGIN
                        NEXTCH;
                        IF CH <> '9'
                           THEN  COMMENTWARNING
                           ELSE
                              BEGIN        (*SET UP FOR THE 6809*)
                                 NEXTCH;
                                 MACHINENUM := M6809;
                              END (*ELSE*)
                     END (*ELSE*);
         ADDRSIZE := 2 * MACHINENUM;
         ALIGNMENT := MACHINENUM;
         TEXTPTR@.SIZE := 2 * ADDRSIZE;
         NILPTR@.SIZE := ADDRSIZE;

      END; (*GETMACHINETYPE*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        OPTIONS STARTS HERE                                         *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

      BEGIN (*OPTIONS*)

         REPEAT                            (*FOR EACH OPTION*)
            NEXTCH;                        (*GET THE...     *)
            CH  := UPPER(.CH.);            (*NEXT CHARACTER.*)

            IF CH = 'A' THEN  GETARITHMETICSIZE

            ELSE  IF CH = 'C' THEN  GET1PLUSORMINUS (PRCODE)

            ELSE  IF CH = 'D' THEN  GET2PLUSORMINUS (DEBUG,KOUNTERS)

            ELSE  IF CH = 'E' THEN
                     BEGIN
                        IF LIST THEN  NEWPAGE;
                        NEXTCH
                     END (*THEN*)

            ELSE  IF CH = 'H' THEN  GETLINT (HEAPSTART)

            ELSE  IF CH = 'J' THEN  GETLINT (JUMPBASE)

            ELSE  IF CH = 'K' THEN  GET1PLUSORMINUS (KOUNTERS)

            ELSE  IF CH = 'L' THEN
                     BEGIN
                        GET1PLUSORMINUS (LIST);
                        IF NOT LIST THEN
                           BEGIN
                              WRITELN (LISTING,' ');
                              PAGEPOS  := PAGEPOS + 1
                           END (*THEN*)
                     END (*THEN*)

            ELSE  IF CH = 'M' THEN  GETMACHINETYPE

            ELSE  IF CH = 'O' THEN  GET1PLUSORMINUS (PLIST)

            ELSE  IF CH = 'P' THEN  GET1PLUSORMINUS (PKOUNTERS)

            ELSE  IF CH = 'R' THEN  GET1PLUSORMINUS (DEBUG)

            ELSE  IF CH = 'T' THEN  GETLINT (STACKSTART)

            ELSE  IF CH = 'W' THEN  GET1PLUSORMINUS (STANDARD)

            ELSE  IF CH = 'X' THEN  GETINT (JUMPENTRIES)

         UNTIL CH <> ','

      END; (*OPTIONS*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*         PROCEDURE  GETIDENTIFIER                                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS AN IDENTIFIER FROM THE SOURCE INPUT.    *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETIDENTIFIER;

      VAR
         I,J:      INTEGER;
         FOUND:    BOOLEAN;
         LASTRW:   INTEGER;

      BEGIN
         J    := 1;
         ID   := BLANKID;

         (*GET THE IDENTIFIER*)

         REPEAT
            IF J <= IDLNGTH THEN
               BEGIN                     (*SAVE THE CURRENT CHARACTER*)
                  ID(.J.)  := UPPER(.CH.);
                  J        := J + 1
               END; (*THEN*)
            NEXTCH                       (*GET THE NEXT CHARACTER*)
         UNTIL (CHTAB(.CH.) <> ATOZ) AND (CHTAB(.CH.) <> NUMBER);

         (*NOW SEE IF THIS IDENTIFIER IS A RESERVED WORD*)

         I       := FRW(.J - 1.);
         LASTRW  := FRW(.J.) - 1;
         FOUND   := FALSE;

         WHILE NOT FOUND AND (I <= LASTRW) DO
            IF RW(.I.) = ID
               THEN  FOUND  := TRUE
               ELSE  I      := I + 1;

         IF FOUND
            THEN  BEGIN        (*IS A RESERVED WORD - SET UP SYMBOL AND OPERATOR
*)                   SY  := RSY(.I.);
                     OP  := ROP(.I.)
                  END (*THEN*)
            ELSE  BEGIN        (*ISN'T A RESERVED WORD - SHOW IT IS AN IDENTIFIE
R*)                  SY  := IDENT;
                     OP  := NOOP
                  END (*ELSE*)

      END; (*GETIDENTIFIER*)

   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETNUMBER                                        *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A CONSTANT NUMBER FROM THE SOURCE       *)
   (*        INPUT.                                                      *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETNUMBER;

      CONST
         HEXOK     = TRUE;               (*HEX DIGITS OK IN NUMBER*)
         HEXNOTOK  = FALSE;              (*HEX DIGITS ARE NOT OK IN NUMBER*)

      TYPE
         DIGITSTR  = PACKED ARRAY (.1..35.) OF CHAR;   (*DIGITS IN A NUMBER*)

      VAR
         REAL:       BOOLEAN;            (*IS THIS A REAL NUMBER?*)
         I:          INTEGER;
         DIGITS:     DIGITSTR;           (*DIGITS IN THE NUMBER*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  STORECHAR (CH,INDEX,DIGITS)                      *)
   (*                                                                    *)
   (*        THIS PROCEDURE STORES THE CHARACTER 'CH' IN THE DIGIT       *)
   (*        STRING 'DIGITS' AT THE POSITION AFTER 'INDEX'.              *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  STORECHAR (CH: CHAR;  VAR INDEX: INTEGER;  VAR DIGITS: DIGITSTR);

      BEGIN (*STORECHAR*)
         INDEX  := INDEX + 1;
         IF INDEX <= DIGMAX THEN        (*SAVE THIS CHARACTER*)
            DIGITS(.INDEX.)  := CH;
      END; (*STORECHAR*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETDIGITS (HEXOK,INDEX,DIGITS)                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A STRING OF DIGITS FROM THE SOURCE      *)
   (*        INPUT.  IF 'HEXOK' IS TRUE, HEX DIGITS WILL BE ALLOWED.     *)
   (*        THE DIGITS WILL BE STORED IN THE DIGIT STRING 'DIGITS'      *)
   (*        STARTING AT THE POSITION AFTER 'INDEX'.                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETDIGITS (HEXOK: BOOLEAN;  VAR INDEX: INTEGER;
                         VAR DIGITS: DIGITSTR);

      VAR  CHT:  CHTYP;

      BEGIN (*GETDIGITS*)

         REPEAT
            STORECHAR (UPPER(.CH.),INDEX,DIGITS);     (*STORE CURRENT CHARACTER*
)           NEXTCH;                                   (*GET THE NEXT CHARACTER*)
            CHT  := CHTAB(.CH.)
         UNTIL    (HEXOK AND (CHT <> NUMBER) AND (CHT <> ATOZ))
               OR (NOT HEXOK AND (CHT <> NUMBER))

      END; (*GETDIGITS*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  MAKEINT (LEN,DIGITS)                             *)
   (*                                                                    *)
   (*        THIS PROCEDURE MAKES AN INTEGER OUT OF THE FIRST 'LEN'      *)
   (*        DIGITS IN THE DIGIT STRING 'DIGITS'.                        *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  MAKEINT (LEN: INTEGER;  VAR DIGITS: DIGITSTR);

      VAR
         DIGITCH:   CHAR;               (*CURRENT CHARACTER CONSIDERING*)
         RADIX:     0..99;              (*RADIX OF NUMBER BUILDING*)
         DIGIT:     0..15;              (*VALUE OF CURRENT DIGIT*)
         ZERO:      INTEGER;            (*ORD OF CHARACTER '0'*)
         A:         INTEGER;
         LONGVAL:   LNGINT;             (*THE LONG VALUE OF THE INTEGER*)
         I:         INTEGER;
         OVRFLW1,
         OVRFLW2: BOOLEAN;              (*OVERFLOW FLAGS*)

      BEGIN (*MAKEINT*)
         ZERO     := ORD('0');
         A        := ORD('A');
         LONGVAL  := LONGZERO;

         IF CH <> '#'
            THEN  RADIX  := 10          (*USE DEFAULT RADIX*)
            ELSE
               BEGIN                    (*USER SUPPLIED RADIX - USE IT*)
                  IF STANDARD THEN  WARNING(500);

                  IF LEN = 1
                     THEN  RADIX  := ORD(DIGITS(.1.)) - ZERO
                     ELSE
                        IF LEN = 2
                           THEN  RADIX  :=   (ORD(DIGITS(.1.)) - ZERO) * 10
                                           + (ORD(DIGITS(.2.)) - ZERO)
                           ELSE  RADIX  := 0;     (*FORCE AN ERROR*)

                  IF (RADIX > 16) OR (RADIX < 2) THEN
                     BEGIN                        (*BAD RADIX - LET HIM KNOW*)
                        ERROR (400);
                        RADIX  := 10
                     END; (*THEN*)

                  (*GET DIGITS AFTER RADIX CHARACTER '#'*)

                  NEXTCH;
                  LEN  := 0;
                  IF (CHTAB(.CH.) <> NUMBER) AND (CHTAB(.CH.) <> ATOZ)
                     THEN  ERROR (401)
                     ELSE  GETDIGITS (HEXOK,LEN,DIGITS)
               END; (*ELSE*)

         IF LEN > DIGMAX
            THEN  BEGIN                          (*NUMBER IS TOO LONG*)
                     ERROR (203);
                     SY       := INT2CONST;
                     VAL.IVAL := 0
                  END (*THEN*)
            ELSE
              BEGIN                              (*MAKE THE INTEGER*)

                 FOR I := 1 TO LEN DO
                    BEGIN                        (*PROCESS A DIGIT*)
                       DIGITCH  := DIGITS(.I.);

                       IF (DIGITCH >= '0') AND (DIGITCH <= '9')
                          THEN  DIGIT  := ORD(DIGITCH) - ZERO
                          ELSE  IF (DIGITCH >= 'A') AND (DIGITCH <= 'F')
                                   THEN  DIGIT  := ORD(DIGITCH) - A + 10
                                   ELSE  BEGIN   (*ILLEGAL DIGIT*)
                                            ERROR (402);
                                            DIGIT  := 0
                                         END; (*ELSE*)

                       IF DIGIT >= RADIX
                          THEN  ERROR (402)      (*ILLEGAL DIGIT*)
                          ELSE  BEGIN            (*ADD DIGIT TO CURRENT NUMBER*)
                                   MULTLONG (LONGVAL,RADIX,OVRFLW1);
                                   ADDLONG (LONGVAL,DIGIT,OVRFLW2);
                                   IF OVRFLW1 OR OVRFLW2 THEN
                                      BEGIN      (*NUMBER TOO BIG*)
                                         ERROR (203);
                                         LONGVAL  := LONGZERO
                                      END (*THEN*)
                                END; (*ELSE*)
                     END; (*FOR*)

                  WITH CNSTVALPTR@ DO
                     BEGIN                       (*NOW SET UP THE CONSTANT*)
                        IF     (LONGVAL(.4.) = 0) AND (LONGVAL(.3.) = 0)
                           AND (LONGVAL(.2.) <= 127) AND (NOT LONGONLY)
                           THEN  BEGIN           (*MAKE A REGULAR INTEGER*)
                                    VAL.IVAL  := LONGVAL(.2.) * 256 + LONGVAL(.1
.);                                 IF VAL.IVAL <= 127
                                       THEN  SY  := INT1CONST
                                       ELSE  SY  := INT2CONST
                                 END (*THEN*)
                           ELSE  BEGIN           (*SET UP A LONG INTEGER*)
                                    SY        := INT4CONST;
                                    LINTVAL   := LONGVAL;
                                    VAL.VALP  := CNSTVALPTR
                                 END (*ELSE*)
                     END (*WITH*)

               END (*ELSE*)

      END; (*MAKEINT*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  MAKEREAL (LEN,DIGITS)                            *)
   (*                                                                    *)
   (*        THIS PROCEDURE CONSTRUCTS A REAL NUMBER OUT OF THE FIRST    *)
   (*        'LEN' DIGITS IN THE DIGIT STRINT 'DIGITS'.                  *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  MAKEREAL (LEN: INTEGER;  VAR DIGITS: DIGITSTR);

      VAR  I:  INTEGER;

      BEGIN (*MAKEREAL*)
         ERROR (398);                          (*UNTIL REALS ARE REAL*)
         SY  := REALCONST;                     (*SET UP SYMBOL TYPE*)

         WITH CNSTVALPTR@ DO
            BEGIN                              (*BUILD THE REAL NUMBER*)

               FOR I := 1 TO REALLNGTH DO
                  RVAL(.I.)  := ' ';

               IF LEN > REALLNGTH
                  THEN  BEGIN                  (*REAL IS TOO LONG*)
                           ERROR (203);
                           RVAL(.1.)  := '0';
                           RVAL(.2.)  := '.';
                           RVAL(.3.)  := '0'
                        END (*THEN*)
                  ELSE  FOR I := 1 TO LEN DO
                           RVAL(.I.)  := DIGITS(.I.)
            END; (*WITH*)

         VAL.VALP  := CNSTVALPTR
      END; (*MAKEREAL*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*      GETNUMBER STARTS HERE                                         *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

      BEGIN (*GETNUMBER*)
         OP    := NOOP;
         I     := 0;
         REAL  := FALSE;
         GETDIGITS (HEXNOTOK,I,DIGITS);       (*GET STRING OF DIGITS*)

         IF CH = '.' THEN
            BEGIN                             (*POSSIBLY HAVE A REAL NUMBER*)
               NEXTCH;
               IF CH = '.'
                  THEN  BEGIN                 (*NOPE - HAVE A '..'*)
                           DOUBLECHAR  := TRUE;
                           DOUBLESYM   := RANGE
                        END (*THEN*)
                  ELSE
                     IF CH = ')'
                        THEN  BEGIN           (*NOPE - HAVE A '.)'*)
                                 DOUBLECHAR  := TRUE;
                                 DOUBLESYM   := RBRACK
                              END (*THEN*)
                        ELSE
                           IF CHTAB(.CH.) <> NUMBER
                              THEN  ERROR (201)    (*ILLEGAL CHAR AFTER '.'*)
                              ELSE  BEGIN          (*HAVE A REAL # - GET THE RES
T*)                                    STORECHAR ('.',I,DIGITS);
                                       GETDIGITS (HEXNOTOK,I,DIGITS);
                                       REAL  := TRUE
                                    END (*ELSE*)
            END; (*THEN*)

         IF UPPER(.CH.) = 'E' THEN
            BEGIN                            (*HAVE AN EXPONENT - GET IT*)
               REAL  := TRUE;
               STORECHAR ('E',I,DIGITS);
               NEXTCH;

               IF (CH = '+') OR (CH = '-') THEN
                  BEGIN                      (*SAVE THE SIGN*)
                     STORECHAR (CH,I,DIGITS);
                     NEXTCH
                  END; (*THEN*)

               IF CHTAB(.CH.) <> NUMBER
                  THEN  ERROR (201)         (*HAVE TO HAVE AT LEAST ONE DIGIT*)
                  ELSE  GETDIGITS (HEXNOTOK,I,DIGITS)
            END; (*THEN*)

         IF REAL
            THEN  MAKEREAL (I,DIGITS)       (*MAKE A REAL NUMBER*)
            ELSE  MAKEINT  (I,DIGITS)       (*MAKE AN INTEGER*)

      END; (*GETNUMBER*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETSTRING                                        *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A CONSTANT STRING FROM THE SOURCE       *)
   (*        INPUT.                                                      *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETSTRING;

      BEGIN (*GETSTRING*)
         LNGTH  := 0;
         SY     := STRINGCONST;
         OP     := NOOP;

         WITH CNSTVALPTR@ DO
            BEGIN                                (*SET UP THE CONSTANT*)
               SVAL  := CNSTSTRPTR;

               REPEAT

                  REPEAT
                     NEXTCH;                     (*GET THE NEXT CHARACTER*)
                     LNGTH  := LNGTH + 1;
                     IF LNGTH <= STRGLNGTH THEN
                        SVAL@(.LNGTH.)  := CH    (*SAVE THE CHARACTER*)
                  UNTIL (EOL) OR (CH = '''');

                  IF EOL
                     THEN  ERROR (202)           (*END OF LINE IN MIDDLE OF STR*
)                    ELSE  NEXTCH                (*GET NEXT CHARACTER*)

               UNTIL CH <> '''';                  (*TO CHECK FOR DOUBLE QUOTES*)

               LNGTH  := LNGTH - 1;
               IF LNGTH = 1
                  THEN  VAL.IVAL  := ORD(SVAL@(.1.))   (*HAVE A SINGLE CHARACTER
*)                ELSE
                     BEGIN                        (*CHECK ON LENGTH OF STRING*)
                        IF LNGTH > STRGLNGTH THEN
                           BEGIN                  (*STRING IS TOO LONG*)
                              ERROR (398);
                              LNGTH  := STRGLNGTH
                           END; (*THEN*)
                        VAL.VALP  := CNSTVALPTR;
                        SLNGTH    := LNGTH
                     END (*ELSE*)

            END (*WITH*)

      END; (*GETSTRING*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETCOLONORBECOMES                                *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A SINGLE COLON OR A BECOMES SYMBOL.     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETCOLONORBECOMES;

      BEGIN (*GETCOLONORBECOMES*)
         OP  := NOOP;
         NEXTCH;                                  (*LOOK AT NEXT CHARACTER*)

         IF CH = '='
            THEN  BEGIN                           (*HAVE A BECOMES (':=')*)
                     SY  := BECOMES;
                     NEXTCH
                  END  (*THEN*)
            ELSE  SY  := COLON

      END; (*GETCOLONORBECOMES*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETPERIODBRACKETORRANGE                          *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A PERIOD, A RIGHT BRACKET, OR A         *)
   (*        RANGE SYMBOL.                                               *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETPERIODBRACKETORRANGE;

      BEGIN (*GETPERIODBRACKETORRANGE*)
         OP  := NOOP;
         NEXTCH;                                  (*LOOK AT NEXT CHARACTER*)

         IF CH = '.'
            THEN  BEGIN                           (*HAVE A RANGE*)
                     SY  := RANGE;
                     NEXTCH
                  END (*THEN*)
            ELSE  IF CH = ')'
                     THEN  BEGIN                  (*HAVE A RIGHT BRACKET*)
                              SY  := RBRACK;
                              NEXTCH
                           END (*THEN*)
                     ELSE  SY  := PERIOD          (*JUST A PERIOD*)

      END; (*GETPERIODBRACKETORRANGE*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETLESSLESSEQUALORNOTEQUAL                       *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A LESS THAN, A LESS THAN OR EQUAL, OR   *)
   (*        A NOT EQUAL SYMBOL.                                         *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETLESSLESSEQUALORNOTEQUAL;

      BEGIN (*GETLESSLESSEQUALORNOTEQUAL*)
         SY  := RELOP;
         NEXTCH;                                  (*LOOK AT NEXT CHARACTER*)

         IF CH = '='
            THEN  BEGIN                           (*LESS THAN OR EQUAL*)
                     OP  := LEOP;
                     NEXTCH
                  END (*THEN*)
            ELSE  IF CH = '>'
                     THEN  BEGIN                  (*NOT EQUAL*)
                              OP  := NEOP;
                              NEXTCH
                           END (*THEN*)
                     ELSE  OP  := LTOP            (*JUST A LESS THAN*)

      END; (*GETLESSLESSEQUALORNOTEQUAL*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETGREATERORGREATEREQUAL                         *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A GREATER THAN OR A GREATER THAN OR     *)
   (*        EQUAL SYMBOL.                                               *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETGREATERORGREATEREQUAL;

      BEGIN (*GETGREATERORGREATEREQUAL*)
         SY  := RELOP;
         NEXTCH;

         IF CH = '='
            THEN  BEGIN                         (*GREATER THAN OR EQUAL*)
                     OP  := GEOP;
                     NEXTCH
                  END (*THEN*)
            ELSE  OP  := GTOP                    (*JUST A GREATER THAN*)

      END; (*GETGREATERORGREATEREQUAL*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETMISCCHAR                                      *)
   (*                                                                    *)
   (*        THIS PROCEDURE HANDLES A MISCELLANEOUS CHARACTER.           *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETMISCCHAR;

      BEGIN (*GETMISCCHAR*)
         SY  := SSY(.CH.);
         OP  := SOP(.CH.);
         NEXTCH
      END; (*GETMISCCHAR*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  SKIPILLEGALCHAR (SYMBOLGOTTEN)                   *)
   (*                                                                    *)
   (*        THIS PROCEDURE SKIPS OVER AN ILLEGAL CHARACTER, AFTER       *)
   (*        GENERATING AN ERROR FOR THAT CHARACTER.                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  SKIPILLEGALCHAR (VAR SYMBOLGOTTEN: BOOLEAN);

      BEGIN (*SKIPILLEGALCHAR*)
         SY  := OTHERSY;
         OP  := NOOP;
         ERROR (398);
         NEXTCH;
         SYMBOLGOTTEN  := FALSE
      END; (*SKIPILLEGALCHAR*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE GETPARNCOMMENTORBRACKET (SYMBOLGOTTEN)            *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A LEFT PAREN, A COMMENT, OR A           *)
   (*        LEFT BRACKET.  'SYMBOLGOTTEN' IS RETURNED TRUE IF A         *)
   (*        SYMBOL OTHER THAN A COMMENT WAS FOUND.                      *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETPARNCOMMENTORBRACKET (VAR SYMBOLGOTTEN: BOOLEAN);

      BEGIN (*GETPARNCOMMENTORBRACKET*)
         NEXTCH;                               (*TAKE A LOOK AT THE NEXT CHAR*)

         IF CH = '*'
            THEN  BEGIN                        (*THIS IS A COMMENT*)
                     NEXTCH;
                     IF CH = '$' THEN OPTIONS; (*PROCESS OPTION COMMENT*)

                     REPEAT                    (*FIND END OF COMMENT*)

                        WHILE CH <> '*' DO
                           BEGIN
                              IF CH = '(' THEN
                                 BEGIN         (*CHECK FOR NESTED COMMENT*)
                                    NEXTCH;
                                    IF CH = '*' THEN  WARNING (503)
                                 END; (*THEN*)
                              NEXTCH
                           END; (*WHILE*)

                        NEXTCH
                     UNTIL CH = ')';

                     NEXTCH;
                     SYMBOLGOTTEN  := FALSE
                  END (*THEN*)
            ELSE  IF CH = '.'
                     THEN  BEGIN               (*HAVE A LEFT BRACKET*)
                              SY  := LBRACK;
                              OP  := NOOP;
                              NEXTCH
                           END (*THEN*)
                     ELSE  BEGIN               (*JUST A LEFT PAREN*)
                              SY  := LPARENT;
                              OP  := NOOP
                           END (*ELSE*)

      END; (*GETPARNCOMMENTORBRACKET*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  GETCOMMENT                                       *)
   (*                                                                    *)
   (*        THIS PROCEDURE GETS A COMMENT THAT WAS STARTED BY A LEFT    *)
   (*        CURLY BRACKET.                                              *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  GETCOMMENT (VAR SYMBOLGOTTEN: BOOLEAN);

      BEGIN (*GETCOMMENT*)
         NEXTCH;
         IF CH = '$' THEN  OPTIONS;           (*PROCESS AN OPTION COMMENT*)

         WHILE CH <> 'å' DO                   (*FIND THE END OF THE COMMENT*)
            BEGIN
               NEXTCH;
               IF CH = 'æ' THEN  WARNING (503)
            END; (*WHILE*)

         NEXTCH;
         SYMBOLGOTTEN  := FALSE
      END; (*GETCOMMENT*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        INSYMBOL STARTS HERE                                        *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

      BEGIN (*INSYMBOL*)

         REPEAT
            SYMBOLGOTTEN  := TRUE;

            IF DOUBLECHAR
               THEN  BEGIN                 (*HAVE DOUBLE CHAR LEFT OVER FROM NUM
*)                      DOUBLECHAR  := FALSE;
                        SY          := DOUBLESYM;
                        OP          := NOOP;
                        NEXTCH
                     END (*THEN*)
               ELSE  BEGIN                 (*HAVE TO GET A SYMBOL*)

                        (*FIRST SKIP BLANKS*)

                        WHILE CHTAB(.CH.) = BLANKCHAR DO  NEXTCH;

                        (*NOW XFER CONTROL BASED ON CURRENT CHARACTER*)

                        CASE CHTAB(.CH.) OF
                           ATOZ:         GETIDENTIFIER;
                           NUMBER:       GETNUMBER;
                           STRQUOTE:     GETSTRING;
                           COLONCHAR:    GETCOLONORBECOMES;
                           PERIODCHAR:   GETPERIODBRACKETORRANGE;
                           LPOINTY:      GETLESSLESSEQUALORNOTEQUAL;
                           RPOINTY:      GETGREATERORGREATEREQUAL;
                           MISCCHAR:     GETMISCCHAR;
                           ILLEGALCHAR:  SKIPILLEGALCHAR (SYMBOLGOTTEN);
                           LPARN:        GETPARNCOMMENTORBRACKET (SYMBOLGOTTEN);
                           CMNTBRACK:    GETCOMMENT (SYMBOLGOTTEN)
                        END (*CASE*)

                     END (*ELSE*)

         UNTIL SYMBOLGOTTEN

      END; (*INSYMBOL*)


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        FUNCTION  INTTYPE (TYPTR): BOOLEAN                          *)
   (*                                                                    *)
   (*        THIS FUNCTION DETERMINES IF THE TYPE POINTED TO BY 'TYPTR'  *)
   (*        IS AN INTEGER (SHORT, MEDIUM, OR TALL).                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   FUNCTION  INTTYPE (TYPTR: STP): BOOLEAN;

      BEGIN (*INTTYPE*)
         INTTYPE  := (TYPTR = INT1PTR) OR (TYPTR = INT2PTR) OR (TYPTR = INT4PTR)
      END; (*INTTYPE*)



   (* -------------------------------------------------------------------------
      PROCEDURE ENTERID
     ------------------------------------------------------------------------- *
)
     PROCEDURE ENTERID(FCP: CTP);
       (* ENTER ID POINTED AT BY FCP INTO THE NAME-TABLE,
        WHICH ON EACH DECLARATION LEVEL IS ORGANISED AS
        AN UNBALANCED BINARY TREE *)
       VAR NAM: ALPHA; LCP, LCP1: CTP; LLEFT: BOOLEAN;
     BEGIN NAM := FCP@.NAME;
       LCP := DISPLAY(.TOP.).FNAME;
       IF LCP = NIL THEN
         DISPLAY(.TOP.).FNAME := FCP
       ELSE
         BEGIN
           REPEAT LCP1 := LCP;
             IF LCP@.NAME = NAM THEN   (* NAME CONFLICT, FOLLOW RIGHT LINK *)
               BEGIN ERROR(101); LCP := LCP@.RLINK; LLEFT := FALSE END
             ELSE
               IF LCP@.NAME < NAM THEN
                 BEGIN LCP := LCP@.RLINK; LLEFT := FALSE END
               ELSE BEGIN LCP := LCP@.LLINK; LLEFT := TRUE END
           UNTIL LCP = NIL;
           IF LLEFT THEN LCP1@.LLINK := FCP ELSE LCP1@.RLINK := FCP
         END;
       FCP@.LLINK := NIL; FCP@.RLINK := NIL
     END (* ENTERID *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE SEARCHSECTION
     ------------------------------------------------------------------------- *
)
     PROCEDURE SEARCHSECTION(FCP: CTP; VAR FCP1: CTP);
       (* TO FIND RECORD FIELDS AND FORWARD DECLARED PROCEDURE ID'S
        --> PROCEDURE PROCEDUREDECLARATION
        --> PROCEDURE SELECTOR *)
       VAR DONE: BOOLEAN;
     BEGIN
       DONE := FALSE;
       WHILE (FCP <> NIL) AND NOT DONE DO
         IF FCP@.NAME = ID THEN DONE := TRUE
         ELSE IF FCP@.NAME < ID THEN FCP := FCP@.RLINK
           ELSE FCP := FCP@.LLINK;
       FCP1 := FCP
     END (* SEARCHSECTION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE SEARCHID
     ------------------------------------------------------------------------- *
)
     PROCEDURE SEARCHID(FIDCLS: SETOFIDS; VAR FCP: CTP);
       VAR LCP: CTP;
           FOUND: BOOLEAN;
     BEGIN
       FOUND := FALSE;
       DISX := TOP + 1;
       WHILE NOT FOUND AND (DISX > 0) DO
         BEGIN DISX := DISX - 1;
           LCP := DISPLAY(.DISX.).FNAME;
           WHILE NOT FOUND AND (LCP <> NIL) DO
             IF LCP@.NAME = ID THEN
               IF LCP@.KLASS IN FIDCLS THEN FOUND := TRUE
               ELSE
                 BEGIN IF PRTERR THEN ERROR(103);
                   LCP := LCP@.RLINK
                 END
             ELSE
               IF LCP@.NAME < ID THEN
                 LCP := LCP@.RLINK
               ELSE LCP := LCP@.LLINK;
         END;
          (*IF SEARCH NOT SUCCESSFUL; SUPPRESS ERROR MESSAGE IN CASE
           OF FORWARD REFERENCED TYPE ID IN POINTER TYPE DEFINITION
           --> PROCEDURE SIMPLETYPE *)
       IF NOT FOUND AND PRTERR THEN
         BEGIN ERROR(104);
           (*TO AVOID RETURNING NIL, REFERENCE AN ENTRY
            FOR AN UNDECLARED ID OF APPROPRIATE CLASS
            --> PROCEDURE ENTERUNDECL *)
           IF TYPES IN FIDCLS THEN LCP := UTYPPTR
           ELSE
             IF VARS IN FIDCLS THEN LCP := UVARPTR
             ELSE
               IF FIELD IN FIDCLS THEN LCP := UFLDPTR
               ELSE
                 IF KONST IN FIDCLS THEN LCP := UCSTPTR
                 ELSE
                   IF PROC IN FIDCLS THEN LCP := UPRCPTR
                   ELSE
                     IF LABELS IN FIDCLS THEN LCP := ULABPTR
                     ELSE LCP := UFCTPTR;
         END;
       FCP := LCP
     END (* SEARCHID *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE GETBOUNDS
     ------------------------------------------------------------------------- *
)
     PROCEDURE GETBOUNDS(FSP: STP; VAR FMIN,FMAX: LNGINT);
       (* GET INTERNAL BOUNDS OF SUBRANGE OR SCALAR TYPE *)
       (* ASSUME (FSP <> NIL) AND (FSP@.FORM <= SUBRANGE)
        AND NOT COMPTYPES(REALPTR,FSP) *)
     BEGIN
       WITH FSP@ DO
         IF FORM = SUBRANGE THEN
           BEGIN
             IF RANGETYPE = CHARPTR THEN
               BEGIN
                 MAKELONG (ASCII(.CHR(MIN.IVAL).),FMIN);
                 MAKELONG (ASCII(.CHR(MAX.IVAL).),FMAX)
               END
             ELSE
               IF RANGETYPE = INT4PTR
                 THEN  BEGIN
                         FMIN  := MIN.VALP@.LINTVAL;
                         FMAX  := MAX.VALP@.LINTVAL
                       END (*THEN*)
                 ELSE  BEGIN
                         MAKELONG (MIN.IVAL,FMIN);
                         MAKELONG (MAX.IVAL,FMAX)
                       END (*ELSE*)
           END
         ELSE
           BEGIN FMIN := LONGZERO;
             IF FSP = CHARPTR THEN FMAX := LONGORDMAXCHAR
             ELSE  IF FSP = INT1PTR THEN
                      BEGIN
                         FMIN  := LINT1MIN;
                         FMAX  := LINT1MAX
                      END (*THEN*)
             ELSE  IF FSP = INT2PTR THEN
                      BEGIN
                         FMIN  := LINT2MIN;
                         FMAX  := LINT2MAX
                      END (*THEN*)
             ELSE  IF FSP = INT4PTR THEN
                      BEGIN
                         FMIN  := LINT4MIN;
                         FMAX  := LINT4MAX
                      END (*THEN*)
             ELSE
               IF (FORM = SCALAR) AND ((* FSP@. *)FCONST <> NIL) THEN
                 MAKELONG (FSP@.FCONST@.VALUES.IVAL,FMAX)
               ELSE  FMAX  := LONGZERO
           END
     END (* GETBOUNDS *) ;



   (* -------------------------------------------------------------------------
      PROCEDURE GENLABEL
     ------------------------------------------------------------------------- *
)
     PROCEDURE GENLABEL(VAR NXTLAB: LABELRNG);
     BEGIN INTLABEL := INTLABEL + 1;
       NXTLAB := INTLABEL
     END (* GENLABEL *);



   (* -------------------------------------------------------------------------
      PROCEDURE GENLI    (USED TO BE INSIDE "BODY" NEAR OTHER "GEN.."S)
     ------------------------------------------------------------------------- *
)
           PROCEDURE GENLI (FOP:MNRANGE; LEVEL:LEVRANGE; OPERAND:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, LEVEL:3, ' ', OPERAND);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENLI*)

           PROCEDURE GENDEF1(L1: LABELRNG; LNAME:ALPHA ) ;
           BEGIN
              IF PRCODE THEN
                 WRITELN(PCODE,'$', L1:3,MN(.17(* DEF *).):5,
                               '''',LNAME:IDLNGTH,'''');
           END (* GENDEF1 *) ;



   (* -------------------------------------------------------------------------
      PROCEDURE BLOCK
     ------------------------------------------------------------------------- *
)
     PROCEDURE BLOCK(FSYS: SETOFSYS; FSY: SYMBOL; FPROCP: CTP);
         TYPE FWDREC = RECORD PF:CTP; NEXTPF:@FWDREC END;
         VAR LSY: SYMBOL; TEST: BOOLEAN;
             LOOPLISTPTR: LOOPPTR;
             FWDLIST,KFWD: @FWDREC;
             LOCFILELIST: CTP;
             PARMLEN: INTEGER ;


   (* -------------------------------------------------------------------------
      PROCEDURE SKIP
     ------------------------------------------------------------------------- *
)
       PROCEDURE SKIP(FSYS: SETOFSYS);
         (* SKIP INPUT STRING UNTIL RELEVANT SYMBOL FOUND *)
       BEGIN
         WHILE NOT(SY IN FSYS) DO INSYMBOL
       END (* SKIP *) ;


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  NEGICONST (LSP,IVAL,LVAL)                        *)
   (*                                                                    *)
   (*        THIS PROCEDURE NEGATES THE INTEGER CONSTANT WHOSE STP IS    *)
   (*        'LSP' AND VALUE IS 'IVAL' OR 'LVAL'.                        *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  NEGICONST (VAR LSP: STP;  VAR IVAL: INTEGER;  VAR LVAL: LNGINT);

      BEGIN (*NEGICONST*)
         IF LSP = INT1PTR
            THEN
               BEGIN                        (*NEGATE A 1-BYTE VALUE*)
                  IVAL  := -IVAL;
                  IF IVAL = 128 THEN  LSP  := INT2PTR
               END (*THEN*)
            ELSE
               IF LSP = INT2PTR
                  THEN
                     BEGIN                  (*NEGATE A 2-BYTE VALUE*)
                        IF IVAL + 1 = -32767
                           THEN
                              BEGIN         (*MAKE A LONG VALUE*)
                                 LVAL       := LONGZERO;
                                 LVAL(.2.)  := 128;
                                 LSP        := INT4PTR
                              END (*THEN*)
                           ELSE
                              BEGIN
                                 IVAL  := -IVAL;
                                 IF IVAL = -128 THEN  LSP  := INT1PTR
                              END (*ELSE*)
                     END (*THEN*)
                  ELSE                      (*NEGATE A 4-BYTE VALUE*)
                     IF     (LVAL(.4.) = 0) AND (LVAL(.3.) = 0)
                        AND (LVAL(.2.) = 128) AND (LVAL(.1.) = 0)
                        THEN
                           BEGIN            (*MAKE IT A 2-BYTE VALUE*)
                              IVAL  := -32767;
                              IVAL  := IVAL - 1;
                              LSP  := INT2PTR
                           END (*THEN*)
                        ELSE  NEGLONG (LVAL)

      END; (*NEGICONST*)

   (* -------------------------------------------------------------------------
      PROCEDURE CONSTANT
     ------------------------------------------------------------------------- *
)
       PROCEDURE CONSTANT(FSYS: SETOFSYS; VAR FSP: STP; VAR FVALU: VALU);
         VAR LSP: STP; LCP: CTP; SIGN: (NONE,POS,NEG);
             LVP: CSP; I: 0..REALLNGTH;
             INTVAL:   INTEGER;
             LNGVAL:   LNGINT;
       BEGIN LSP := NIL; FVALU.IVAL := 0;
         IF NOT(SY IN CONSTBEGSYS) THEN
           BEGIN ERROR(50); SKIP(FSYS+CONSTBEGSYS) END;
         IF SY IN CONSTBEGSYS THEN
           BEGIN
             IF SY = STRINGCONST THEN
               BEGIN
                 IF LNGTH = 1 THEN LSP := CHARPTR
                 ELSE
                   BEGIN
                     NEW(LSP,STRINGS);
                     WITH LSP@ DO
                       BEGIN
                          IF ODD(LNGTH) AND (ALIGNMENT = 2) THEN
                            LNGTH := LNGTH + 1;
                          SIZE := LNGTH+ALIGNMENT; FORM := STRINGS;
                       END ;
                     LVP := VAL.VALP ;
                     NEW(VAL.VALP, STRG) ;
                     VAL.VALP@.SLNGTH := LVP@.SLNGTH ;
                     VAL.VALP@.SVAL := LVP@.SVAL ;(* COPY STRING CONST TO HEAP *
)                  END;
               FVALU(* .VALP *) := VAL(* .VALP *) ; INSYMBOL;
               END
             ELSE
               BEGIN
                 SIGN := NONE;
                 IF (SY = ADDOP) AND (OP IN (.PLUS,MINUS.)) THEN
                   BEGIN IF OP = PLUS THEN SIGN := POS ELSE SIGN := NEG;
                     INSYMBOL
                   END;
                 IF SY = IDENT THEN
                   BEGIN SEARCHID((.KONST.),LCP);
                     WITH LCP@ DO
                       BEGIN LSP := IDTYPE; FVALU := VALUES END;
                     IF SIGN <> NONE THEN
                       IF INTTYPE(LSP) THEN
                          BEGIN
                             IF SIGN = NEG THEN
                                BEGIN             (*NEGATE AN INTEGER CONST*)
                                   INTVAL  := FVALU.IVAL;
                                   IF LSP = INT4PTR THEN
                                      LNGVAL  := FVALU.VALP@.LINTVAL;
                                   NEGICONST (LSP,INTVAL,LNGVAL);
                                   IF (LSP = INT1PTR) OR (LSP = INT2PTR)
                                      THEN  FVALU.IVAL  := INTVAL
                                      ELSE  BEGIN     (*MAKE A LONG*)
                                               NEW (LVP,LINT);
                                               LVP@.LINTVAL  := LNGVAL;
                                               FVALU.VALP    := LVP
                                            END (*ELSE*)
                                END (*THEN*)
                          END (*THEN*)
                       ELSE
                         IF LSP = REALPTR THEN
                           BEGIN
                             IF SIGN = NEG THEN
                               BEGIN NEW(LVP,REEL);
                                  IF FVALU.VALP@.RVAL(.0.) = '-' THEN
                                       LVP@.RVAL(.0.) := '+'
                                  ELSE LVP@.RVAL(.0.) := '-';
                                  FOR I := 1 TO REALLNGTH DO
                                    LVP@.RVAL(.I.) := FVALU.VALP@.RVAL(.I.);
                                 FVALU.VALP := LVP;
                               END
                             END
                           ELSE ERROR(105);
                     INSYMBOL;
                   END
                 ELSE
                   IF (SY = INT1CONST) OR (SY = INT2CONST) OR (SY = INT4CONST) T
HEN                   BEGIN
                         INTVAL  := VAL.IVAL;

                         IF SY = INT1CONST
                            THEN  LSP  := INT1PTR
                            ELSE
                               IF SY = INT2CONST
                                  THEN  LSP  := INT2PTR
                                  ELSE
                                     BEGIN
                                        LSP     := INT4PTR;
                                        LNGVAL  := VAL.VALP@.LINTVAL
                                     END; (*ELSE*)

                         IF SIGN = NEG THEN  NEGICONST (LSP,INTVAL,LNGVAL);

                         IF (LSP = INT1PTR) OR (LSP = INT2PTR)
                            THEN  FVALU.IVAL  := INTVAL
                            ELSE  BEGIN
                                     NEW (LVP,LINT);
                                     LVP@.LINTVAL  := LNGVAL;
                                     FVALU.VALP    := LVP
                                  END; (*ELSE*)

                         INSYMBOL
                      END (*THEN*)
                   ELSE
                     IF SY = REALCONST THEN
                       BEGIN
                         WITH VAL.VALP@ DO
                            IF SIGN = NEG THEN RVAL(.0.) := '-'
                                          ELSE RVAL(.0.) := '+' ;
                          NEW(LVP, REEL) ;
                          LVP@.RVAL := VAL.VALP@.RVAL ;
                          LSP := REALPTR; FVALU.VALP := LVP; INSYMBOL
                       END
                     ELSE
                       BEGIN ERROR(106); SKIP(FSYS) END
               END;
             IF NOT (SY IN FSYS) THEN
               BEGIN ERROR(6); SKIP(FSYS) END
             END;
         FSP := LSP;
       END (* CONSTANT *) ;

   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*                       FUNCTION COMPTYPES                           *)
   (*                                                                    *)
   (*      FUNCTION COMPTYPES CHECKS TO SEE IF THE TYPES DESCRIBED BY    *)
   (* THE POINTERS FSP1, AND FSP2 ARE ASSIGNMENT COMPATIBLE.             *)
   (*--------------------------------------------------------------------*)

       FUNCTION COMPTYPES(FSP1,FSP2: STP) : BOOLEAN;
         (*DECIDE WHETHER STRUCTURES PTED AT BY FSP1 & FSP2 ARE COMPATIBLE *)
         VAR NXT1,NXT2: CTP; COMP: BOOLEAN;
           LTESTP1,LTESTP2 : TESTP;
       BEGIN
         IF FSP1 = FSP2 THEN COMPTYPES := TRUE
         ELSE
           IF (FSP1 <> NIL) AND (FSP2 <> NIL) THEN
             IF FSP1@.FORM = FSP2@.FORM THEN
               CASE FSP1@.FORM OF
                 SCALAR:
                   COMPTYPES := INTTYPE (FSP1) AND INTTYPE (FSP2);
                   (*  IDENTICAL SCALARS DECLARED ON DIFFERENT LEVELS ARE
                    NOT RECOGNIZED TO BE COMPATIBLE UNLESS THE ARE BOTH
                    INTEGER TYPES (LONG REG, OR SHORT)                   *)
                 SUBRANGE:
                   COMPTYPES := COMPTYPES(FSP1@.RANGETYPE,FSP2@.RANGETYPE);
                 POINTER:
                     BEGIN
                       COMP := FALSE; LTESTP1 := GLOBTESTP;
                       LTESTP2 := GLOBTESTP;
                       WHILE LTESTP1 <> NIL DO
                         WITH LTESTP1@ DO
                           BEGIN
                             IF (ELT1 = FSP1@.ELTYPE) AND
                               (ELT2 = FSP2@.ELTYPE) THEN COMP := TRUE;
                             LTESTP1 := LASTTESTP
                           END;
                       IF NOT COMP THEN
                         BEGIN NEW(LTESTP1);
                           WITH LTESTP1@ DO
                             BEGIN ELT1 := FSP1@.ELTYPE;
                               ELT2 := FSP2@.ELTYPE;
                               LASTTESTP := GLOBTESTP
                             END;
                           GLOBTESTP := LTESTP1;
                           COMP := COMPTYPES(FSP1@.ELTYPE,FSP2@.ELTYPE)
                         END;
                       COMPTYPES := COMP; GLOBTESTP := LTESTP2
                     END;
                 POWER:
                   COMPTYPES := COMPTYPES(FSP1@.ELSET,FSP2@.ELSET);
                 STRINGS:
                   COMPTYPES := TRUE;
                 ARRAYS:
                   COMPTYPES := COMPTYPES(FSP1@.AELTYPE,FSP2@.AELTYPE)
                                AND (FSP1@.SIZE = FSP2@.SIZE);
                   (* ALTERNATIVES: -- ADD A THIRD BOOLEAN TERM: INDEXTYPE MUST
                                     BE COMPATIBLE.
                                  -- ADD A FOURTH BOOLEAN TERM: LOWBOUNDS MUST
                                     BE THE SAME *)
                 RECORDS:
                   BEGIN NXT1 := FSP1@.FSTFLD; NXT2 := FSP2@.FSTFLD; COMP:=TRUE;
                     WHILE (NXT1 <> NIL) AND (NXT2 <> NIL) DO
                       BEGIN COMP:=COMP AND COMPTYPES(NXT1@.IDTYPE,NXT2@.IDTYPE)
;                        NXT1 := NXT1@.NEXT; NXT2 := NXT2@.NEXT
                       END;
                     COMPTYPES := COMP AND (NXT1 = NIL) AND (NXT2 = NIL)
                                 AND(FSP1@.RECVAR = NIL)AND(FSP2@.RECVAR = NIL)
                   END;
                   (* IDENTICAL RECORDS ARE RECOGNIZED TO BE COMPATIBLE
                    IFF NO VARIANTS OCCUR *)
                 FILES:
                   COMPTYPES := COMPTYPES(FSP1@.FILTYPE,FSP2@.FILTYPE);
                 TAGFLD:  ;
                 VARIANT:
               END (* CASE *)
             ELSE (* FSP1@.FORM <> FSP2@.FORM *)
               IF FSP1@.FORM = SUBRANGE THEN
                 COMPTYPES := COMPTYPES(FSP1@.RANGETYPE,FSP2)
               ELSE
                 IF FSP2@.FORM = SUBRANGE THEN
                   COMPTYPES := COMPTYPES(FSP1,FSP2@.RANGETYPE)
                 ELSE COMPTYPES := FALSE
           ELSE COMPTYPES := TRUE
       END (* COMPTYPES *) ;

       FUNCTION SAMELABEL(SYM:SYMBOL; LPTR:LBP) : BOOLEAN;
                   (* NEW FUNCTION TO SUPPORT ALPHANUMERIC LABELS *)
                   (* CALLED BY LABELDECLARATION, GOTOSTATEMENT AND *)
                   (* STATEMENT FOR USE IN LOOKING UP A LABEL VALUE   *)
       BEGIN
       IF LPTR <> NIL THEN
         BEGIN IF (SYM = INT2CONST) AND NOT LPTR@.ALF THEN
                     SAMELABEL := VAL.IVAL = LPTR@.LABVAL
             ELSE IF (SYM = IDENT) AND LPTR@.ALF THEN
                     SAMELABEL := ID = LPTR@.LABNAME
              ELSE SAMELABEL := FALSE
         END
       ELSE SAMELABEL := FALSE;
       END (* SAMELABEL *) ;

       FUNCTION CHARARRAY(FSP: STP) : BOOLEAN;
       BEGIN CHARARRAY := FALSE;
         IF FSP <> NIL THEN
           IF FSP@.FORM = ARRAYS THEN
              CHARARRAY := COMPTYPES(FSP@.AELTYPE,CHARPTR)
       END ;    (* CHARARRAY *)

       FUNCTION ALIGN(OP:INTEGER):INTEGER; (*ALIGN OP TO 'ALIGNMENT' BOUNDARY*)

          VAR
           ADJUSTMENT: INTEGER;

          BEGIN
           ADJUSTMENT := ABS(OP) MOD ALIGNMENT;
           IF ADJUSTMENT = 0 THEN ALIGN := OP
           ELSE
             IF OP < 0 THEN
               ALIGN := OP - (ALIGNMENT - ADJUSTMENT)
             ELSE
               ALIGN := OP + (ALIGNMENT - ADJUSTMENT)
          END;

   (*$E------------------------------------------------------------------------
      PROCEDURE TYP
     ------------------------------------------------------------------------- *
)
       PROCEDURE TYP(FSYS: SETOFSYS; VAR FSP: STP; VAR FSIZE: ADDRRANGE);
         VAR
            LSP,
            LSP1,
            LSP2:    STP;
            OLDTOP:  DISPRANGE;
            LCP:     CTP;
            KVALU:   VALU;
            LSIZE,
            DISPL:   ADDRRANGE;
            LMIN,
            LMAX:    INTEGER;
            LNGMIN,
            LNGMAX:  LNGINT;


   (* -------------------------------------------------------------------------
      PROCEDURE SIMPLETYP
     ------------------------------------------------------------------------- *
)
         PROCEDURE SIMPLETYPE(FSYS:SETOFSYS;
                              VAR FSP:STP (* ; VAR FSIZE:ADDRRANGE *));
           VAR LSP,LSP1,LSP2: STP; LCP,LCP1: CTP; TTOP: DISPRANGE;
               LCNT: INTEGER; VAL1,VAL2: VALU;
               SUBR,BADRANGE:  BOOLEAN;
               CVAL:           CSP;
               LVAL:           LNGINT;
         BEGIN FSIZE := 1;
           IF NOT (SY IN SIMPTYPEBEGSYS) THEN
             BEGIN ERROR(1); SKIP(FSYS + SIMPTYPEBEGSYS) END;
           IF SY IN SIMPTYPEBEGSYS THEN
             BEGIN
               IF SY = LPARENT THEN
                 BEGIN TTOP := TOP;   (* DECL. CONSTS LOCAL TO INNERMOST BLOCK *
)                  WHILE DISPLAY(.TOP.).OCCUR <> BLCK DO TOP := TOP - 1;
                   NEW(LSP,SCALAR);
                   WITH LSP@ DO
                     BEGIN SIZE := INT2SIZE; FORM := SCALAR;
                     END;
                   LCP1 := NIL; LCNT := 0;
                   REPEAT INSYMBOL;
                     IF SY = IDENT THEN
                       BEGIN NEW(LCP,KONST);
                         WITH LCP@ DO
                           BEGIN NAME := ID; IDTYPE := LSP; NEXT := LCP1;
                             VALUES.IVAL := LCNT; KLASS := KONST
                           END;
                         ENTERID(LCP);
                         LCNT := LCNT + 1;
                         LCP1 := LCP; INSYMBOL
                       END
                     ELSE ERROR(2);
                     IF NOT (SY IN FSYS + (.COMMA,RPARENT.)) THEN
                       BEGIN ERROR(6); SKIP(FSYS + (.COMMA,RPARENT.)) END
                   UNTIL SY <> COMMA;
                   LSP@.FCONST := LCP1; TOP := TTOP;
                   IF LCNT <= 128 THEN  LSP@.SIZE  := INT1SIZE;
                   IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
                 END
               ELSE
                 BEGIN
                   SUBR  := FALSE;
                   LSP   := NIL;

                   IF SY = IDENT THEN
                     BEGIN SEARCHID((.TYPES,KONST.),LCP);
                       INSYMBOL;
                       IF LCP@.KLASS = KONST THEN
                         BEGIN
                           WITH LCP@ DO
                             BEGIN
                               LSP1  := IDTYPE;
                               IF CHARARRAY(LSP1)
                                 THEN  ERROR(148)
                                 ELSE  BEGIN
                                         SUBR  := TRUE;
                                         VAL1  := VALUES
                                       END (*ELSE*)
                             END (*WITH*)
                         END
                       ELSE
                         BEGIN LSP := LCP@.IDTYPE;
                          (*  IF LSP <> NIL THEN FSIZE := LSP@.SIZE   *)
                         END
                     END (* SY = IDENT *)
                   ELSE
                     BEGIN
                       CONSTANT(FSYS + (.RANGE.),LSP1,VAL1);
                       IF CHARARRAY(LSP1)
                         THEN  ERROR(148)
                         ELSE  SUBR  := TRUE
                     END;
                   IF SUBR THEN
                      BEGIN                    (*PROCESS THE REST OF THE SUBRANG
E*)                      IF SY = RANGE
                            THEN  INSYMBOL
                            ELSE  ERROR(5);

                         CONSTANT (FSYS,LSP2,VAL2);

                         IF INTTYPE(LSP1) AND INTTYPE(LSP2) THEN
                            IF LSP1 <> LSP2 THEN
                               IF     ((LSP1 = INT1PTR) OR (LSP1 = INT2PTR))
                                  AND ((LSP2 = INT1PTR) OR (LSP2 = INT2PTR))
                                  THEN  BEGIN           (*MAKE EM BOTH REGULAR*)
                                           LSP1  := INT2PTR;
                                           LSP2  := INT2PTR
                                        END (*THEN*)
                                  ELSE
                                     BEGIN
                                        NEW(CVAL,LINT);
                                        IF LSP1 = INT4PTR
                                           THEN  BEGIN
                                                    MAKELONG (VAL2.IVAL,LVAL);
                                                    VAL2.VALP  := CVAL;
                                                    LSP2       := INT4PTR
                                                 END (*THEN*)
                                           ELSE  BEGIN
                                                    MAKELONG (VAL1.IVAL,LVAL);
                                                    VAL1.VALP  := CVAL;
                                                    LSP1       := INT4PTR
                                                 END; (*ELSE*)
                                        CVAL@.LINTVAL  := LVAL
                                     END; (*ELSE*)

                         IF LSP1 <> LSP2
                            THEN  ERROR(107)
                            ELSE

                         IF LSP1 = REALPTR
                            THEN  ERROR(398)
                            ELSE

                         BEGIN                  (*CHECK FOR LEGAL RANGE*)
                            IF LSP1 = INT4PTR
                               THEN  BADRANGE  := COMPLONGS (VAL1.VALP@.LINTVAL,
                                                             VAL2.VALP@.LINTVAL)
 =                                                LNGGREATER
                               ELSE  BADRANGE  := VAL1.IVAL > VAL2.IVAL;

                            IF BADRANGE
                               THEN  ERROR(102)
                               ELSE

                            BEGIN               (*MAKE THE SUBRANGE*)
                               NEW (LSP,SUBRANGE);
                               WITH LSP@ DO
                                  BEGIN
                                     RANGETYPE  := LSP1;
                                     FORM       := SUBRANGE;
                                     MIN        := VAL1;
                                     MAX        := VAL2;
                                     SIZE       := LSP1@.SIZE
                                  END (*WITH*)

                            END (*ELSE*)

                         END (*ELSE*)

                      END (*THEN*)
                 END;
               FSP := LSP;
               IF NOT (SY IN FSYS) THEN
                 BEGIN ERROR(6); SKIP(FSYS) END
             END
               ELSE FSP := NIL
         END (* SIMPLETYPE *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE FIELDLIST
     ------------------------------------------------------------------------- *
)
         PROCEDURE FIELDLIST(FSYS: SETOFSYS; VAR FRECVAR: STP);
           VAR LCP,LCP1,NXT,NXT1: CTP; LSP,LSP1,LSP2,LSP3,LSP4: STP;
                MINSIZE,MAXSIZE,LSIZE: ADDRRANGE; LVALU: VALU;
          BEGIN NXT1 := NIL; LSP := NIL;
           IF NOT (SY IN FSYS+(.IDENT,CASESY.)) THEN
             BEGIN ERROR(19); SKIP(FSYS + (.IDENT,CASESY.)) END;
           WHILE SY = IDENT DO
             BEGIN NXT := NXT1;
               REPEAT
                 IF SY = IDENT THEN
                   BEGIN NEW(LCP,FIELD);
                     WITH LCP@ DO
                       BEGIN NAME := ID; IDTYPE := NIL; NEXT := NXT;
                         KLASS := FIELD
                       END;
                     NXT := LCP;
                     ENTERID(LCP);
                     INSYMBOL
                   END
                 ELSE ERROR(2);
                 IF NOT (SY IN (.COMMA,COLON.)) THEN
                   BEGIN ERROR(6); SKIP(FSYS + (.COMMA,COLON,SEMICOLON,CASESY.))
                   END;
               TEST := SY <> COMMA;
                 IF NOT TEST  THEN INSYMBOL
               UNTIL TEST;
               IF SY = COLON THEN INSYMBOL ELSE ERROR(5);
               TYP(FSYS + (.CASESY,SEMICOLON.),LSP,LSIZE);
               WHILE NXT <> NXT1 DO
                 WITH NXT@ DO
                    BEGIN  IDTYPE := LSP;
                     IF LSIZE > 1 THEN DISPL := ALIGN(DISPL);
                     FLDADDR := DISPL;
                     DISPL := DISPL + LSIZE;
                     NXT := NEXT
                   END;
               NXT1 := LCP;
               IF SY = SEMICOLON THEN
                 BEGIN INSYMBOL;
                   IF NOT (SY IN (.IDENT,CASESY,ENDSY.)) THEN (*IGNORE EXTRA ;*)
                     BEGIN ERROR(19); SKIP(FSYS + (.IDENT,CASESY.)) END
                 END
             END (* WHILE *);
           NXT := NIL;
           WHILE NXT1 <> NIL DO
             WITH NXT1@ DO
               BEGIN LCP := NEXT; NEXT := NXT; NXT := NXT1; NXT1 := LCP END;
           IF SY = CASESY THEN
             BEGIN NEW(LSP,TAGFLD);
               WITH LSP@ DO
                 BEGIN TAGFIELDP := NIL; FSTVAR := NIL; FORM:=TAGFLD END;
               FRECVAR := LSP;
               INSYMBOL;
               IF SY = IDENT THEN
                 BEGIN NEW(LCP,FIELD);
                   WITH LCP@ DO
                     BEGIN NAME := ID; IDTYPE := NIL; KLASS:=FIELD;
                       NEXT := NIL ; (*FLDADDR WILL BE SET WHEN TYPE IS KNOWN*)
                     END;
                 PRTERR := FALSE ;  SEARCHID((.TYPES.),LCP1) ;  PRTERR := TRUE ;
                 IF LCP1 = NIL THEN  BEGIN  (* EXPLICIT TAG FIELD  *)
                    ENTERID(LCP);  INSYMBOL ;
                    IF SY = COLON THEN INSYMBOL ELSE ERROR(5);
                    IF SY <> IDENT THEN
                      BEGIN ERROR(2); SKIP(FSYS + (.OFSY,LPARENT.)) END
                   END (*  IF LCP1 = NIL  *)
                   ELSE (*  NO EXPLICT TAG FIELD   *)
                   LCP@.NAME := BLANKID ;
                     BEGIN SEARCHID((.TYPES.),LCP1);
                       LSP1 := LCP1@.IDTYPE;
                       IF LSP1 <> NIL THEN
                         WITH LSP1@ DO
                            BEGIN
                         IF LCP@.NAME <> BLANKID THEN  BEGIN
                            IF SIZE > 1 THEN DISPL := ALIGN(DISPL);
                            LCP@.FLDADDR := DISPL ;  DISPL := DISPL + SIZE;
                         END (* LCP@.NAME <> BLANKID *) ;
                           IF (FORM <= SUBRANGE) OR CHARARRAY(LSP1) THEN
                             BEGIN IF COMPTYPES(REALPTR,LSP1) THEN ERROR(109)
                               ELSE IF CHARARRAY(LSP1) THEN ERROR(398);
                               LCP@.IDTYPE := LSP1; LSP@.TAGFIELDP := LCP;
                             END
                           ELSE ERROR(110);
                           END (*  WITH LSP1@ DO  *) ;
                       INSYMBOL;
                     END
                 END
               ELSE BEGIN ERROR(2); SKIP(FSYS + (.OFSY,LPARENT.)) END;
                LSP@.SIZE := DISPL;
               IF SY = OFSY THEN INSYMBOL ELSE ERROR(8);
               LSP1 := NIL; MINSIZE := DISPL; MAXSIZE := DISPL;
               REPEAT LSP2 := NIL;
                 REPEAT CONSTANT(FSYS + (.COMMA,COLON,LPARENT.),LSP3,LVALU);
                   IF LSP@.TAGFIELDP <> NIL THEN
                    IF NOT COMPTYPES(LSP@.TAGFIELDP@.IDTYPE,LSP3)THEN ERROR(111)
;                  NEW(LSP3,VARIANT);
                   WITH LSP3@ DO
                     BEGIN NXTVAR := LSP1; SUBVAR := LSP2; VARVAL := LVALU;
                       FORM := VARIANT
                     END;
                   LSP1 := LSP3; LSP2 := LSP3;
                   TEST := SY <> COMMA;
                   IF NOT TEST THEN INSYMBOL
                 UNTIL TEST;
                 IF SY = COLON THEN INSYMBOL ELSE ERROR(5);
                 IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
                 FIELDLIST(FSYS + (.RPARENT,SEMICOLON.),LSP2);
                 IF DISPL > MAXSIZE THEN MAXSIZE := DISPL;
                 WHILE LSP3 <> NIL DO
                   BEGIN LSP4 := LSP3@.SUBVAR; LSP3@.SUBVAR := LSP2;
                     LSP3@.SIZE := DISPL;
                     LSP3 := LSP4
                   END;
                 IF SY = RPARENT THEN
                   BEGIN INSYMBOL;
                     IF NOT (SY IN FSYS + (.SEMICOLON.)) THEN
                       BEGIN ERROR(6); SKIP(FSYS + (.SEMICOLON.)) END
                   END
                 ELSE ERROR(4);
                 TEST := SY <> SEMICOLON;
                 IF NOT TEST THEN
                   BEGIN DISPL := MINSIZE;
                       INSYMBOL ;  TEST := SY = ENDSY ; (* IGNORE EXTRA ; *)
                   END
               UNTIL TEST;
               DISPL := MAXSIZE;
               LSP@.FSTVAR := LSP1;
             END
           ELSE FRECVAR := NIL
         END (* FIELDLIST *) ;

       BEGIN (* **START** TYP *)
         IF NOT (SY IN TYPEBEGSYS) THEN
            BEGIN ERROR(10); SKIP(FSYS + TYPEBEGSYS) END;
         IF SY IN TYPEBEGSYS THEN
           BEGIN
             IF SY IN SIMPTYPEBEGSYS THEN SIMPLETYPE(FSYS,FSP(* ,FSIZE *))
             ELSE
       (* @ *)     IF SY = ARROW THEN
                 BEGIN NEW(LSP,POINTER); FSP := LSP;
                   WITH LSP@ DO
                     BEGIN ELTYPE := NIL;
                      SIZE := ADDRSIZE;  FORM:=POINTER
                     END;
                   INSYMBOL;
                   IF SY = IDENT THEN
                     BEGIN PRTERR := FALSE; (*NO ERROR IF SRCH NOT SUCCESSFUL*)
                       SEARCHID((.TYPES.),LCP); PRTERR := TRUE;
                       IF LCP = NIL THEN   (* FORWARD REFERENCED TYPE ID *)
                         BEGIN NEW(LCP,TYPES);
                           WITH LCP@ DO
                             BEGIN NAME := ID; IDTYPE := LSP;
                               NEXT := FWPTR; KLASS := TYPES
                             END;
                           FWPTR := LCP
                         END
                       ELSE
                         BEGIN
                           IF LCP@.IDTYPE <> NIL THEN
                             IF LCP@.IDTYPE@.FORM = FILES THEN ERROR(108)
                             ELSE LSP@.ELTYPE := LCP@.IDTYPE
                         END;
                       INSYMBOL;
                     END
                   ELSE ERROR(2);
                 END
               ELSE
                 BEGIN
                   IF SY = PACKEDSY THEN
                     BEGIN INSYMBOL;
                       IF NOT (SY IN TYPEDELS) THEN
                         BEGIN
                           ERROR(10); SKIP(FSYS + TYPEDELS)
                         END
                     END;
       (* STRING *)    IF SY = STRINGSY THEN
                     BEGIN
                        IF STANDARD THEN WARNING(510);
                        INSYMBOL;
                        IF SY = LBRACK THEN
                           INSYMBOL
                        ELSE
                           ERROR(11);
                        CONSTANT(FSYS + (. RBRACK .), LSP2, KVALU);
                        IF (LSP2 = INT1PTR) OR (LSP2 = INT2PTR) THEN
                            BEGIN
                               NEW(LSP,STRINGS);
                               WITH LSP@ DO
                                  BEGIN
                                     FORM := STRINGS;
                                     SIZE := ALIGN(KVALU.IVAL+ALIGNMENT)
                                  END
                            END
                        ELSE
                           BEGIN
                              LSP := NIL;
                              IF LSP2 = INT4PTR
                                 THEN ERROR(203)
                                 ELSE ERROR(15)
                           END;
                        IF SY = RBRACK THEN
                           INSYMBOL
                        ELSE
                           ERROR(12)
                     END
                   ELSE
       (* ARRAY *)     IF SY = ARRAYSY THEN
                     BEGIN INSYMBOL;
                       IF SY = LBRACK THEN INSYMBOL ELSE ERROR(11);
                       LSP1 := NIL;
                       REPEAT NEW(LSP,ARRAYS);
                         WITH LSP@ DO
                           BEGIN AELTYPE := LSP1; INXTYPE := NIL;
                                 FORM:=ARRAYS END;
                         LSP1 := LSP;
                         SIMPLETYPE(FSYS + (.COMMA,RBRACK,OFSY.),LSP2);
                         IF LSP2 <> NIL THEN
                           IF LSP2@.FORM <= SUBRANGE THEN
                             BEGIN
                               IF LSP2 = REALPTR THEN
                                 BEGIN ERROR(109); LSP2 := NIL END
                               ELSE
                                 IF LSP2 = INT4PTR THEN
                                   BEGIN ERROR(149); LSP2 := NIL END;
                               LSP@.INXTYPE := LSP2
                             END
                           ELSE BEGIN ERROR(113); LSP2 := NIL END;
                         TEST := SY <> COMMA;
                         IF NOT TEST THEN INSYMBOL
                       UNTIL TEST;
                       IF SY = RBRACK THEN INSYMBOL ELSE ERROR(12);
                       IF SY = OFSY THEN INSYMBOL ELSE ERROR(8);
                        TYP(FSYS,LSP,LSIZE);
                       REPEAT
                         WITH LSP1@ DO
                           BEGIN LSP2 := AELTYPE; AELTYPE := LSP;
                             IF INXTYPE <> NIL THEN
                                BEGIN
                                   GETBOUNDS (INXTYPE, LNGMIN, LNGMAX);
                                   LMIN := MAKESHORT (LNGMIN);
                                   LMAX := MAKESHORT (LNGMAX);
                                   LSIZE := LSIZE * (LMAX - LMIN + 1);
                                   SIZE := LSIZE;
                                END
                           END;
                         LSP := LSP1; LSP1 := LSP2
                       UNTIL LSP1 = NIL
                     END
                   ELSE
       (* RECORD *)      IF SY = RECORDSY THEN
                       BEGIN INSYMBOL;
                         OLDTOP := TOP;
                         IF TOP < DISPLIMIT THEN
                           BEGIN TOP := TOP + 1;
                             WITH DISPLAY(.TOP.) DO
                               BEGIN FNAME := NIL;
                                 FLABEL := NIL;
                                     OCCUR := REC
                               END
                           END
                         ELSE ERROR(250);
                         DISPL := 0;
                         FIELDLIST(FSYS-(.SEMICOLON.)+(.ENDSY.),LSP1);
                         NEW(LSP,RECORDS);
                         WITH LSP@ DO
                           BEGIN FSTFLD := DISPLAY(.TOP.).FNAME;
                             RECVAR := LSP1; SIZE := ALIGN (DISPL);
                             FORM := RECORDS ;
                           END;
                         TOP := OLDTOP;
                         IF SY = ENDSY THEN INSYMBOL ELSE ERROR(13)
                       END
                     ELSE
       (* SET *)           IF SY = SETSY THEN
                         BEGIN INSYMBOL;
                           IF SY = OFSY THEN INSYMBOL ELSE ERROR(8);
                           SIMPLETYPE(FSYS,LSP1(* ,LSIZE *));
                           IF LSP1 <> NIL THEN
                             IF LSP1@.FORM > SUBRANGE THEN
                               BEGIN ERROR(115); LSP1 := NIL END
                             ELSE
                               IF LSP1 = REALPTR THEN ERROR(114);
                           NEW(LSP,POWER);
                           WITH LSP@ DO
                             BEGIN ELSET:=LSP1;
                             SIZE:=SETSIZE;  FORM:=POWER
                             END;
                         END
                       ELSE
       (* FILE *)          IF SY = FILESY THEN
                           BEGIN  INSYMBOL ;
                           IF SY = OFSY THEN INSYMBOL ELSE ERROR(8) ;
                           SIMPLETYPE(FSYS,LSP1(* ,LSIZE *)) ;
                           IF LSP1 = NIL THEN
                              BEGIN
                                 ERROR(398);
                                 LSP := NIL;
                              END
                           ELSE  IF LSP1@.FORM = FILES THEN
                                    BEGIN
                                       ERROR (398);
                                       LSP  := NIL
                                    END (*THEN*)
                           ELSE  IF LSP1 = CHARPTR THEN LSP := TEXTPTR
                                 ELSE BEGIN NEW(LSP,FILES);
                                        WITH LSP@ DO BEGIN
                                          FORM := FILES;
                                          SIZE := 2*ADDRSIZE;
                                          FILTYPE := LSP1 END
                                      END
                           END ;
                   FSP := LSP
                 END;
             IF NOT (SY IN FSYS) THEN
               BEGIN ERROR(6); SKIP(FSYS) END
           END
         ELSE FSP := NIL;
         IF FSP = NIL THEN FSIZE := 1 ELSE FSIZE := FSP@.SIZE
       END (* TYP *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE LABELDECLARATION
     ------------------------------------------------------------------------- *
)
       PROCEDURE LABELDECLARATION;
         VAR LLP: LBP; REDEF: BOOLEAN; LBNAME: LABELRNG ;
             LCP: CTP;
       BEGIN
         REPEAT
           IF (SY = INT2CONST) OR (SY = IDENT) THEN
             WITH DISPLAY(.TOP.) DO
               BEGIN LLP := FLABEL; REDEF := FALSE;
                 WHILE (LLP <> NIL) AND NOT REDEF DO
                   IF NOT SAMELABEL(SY, LLP) THEN
                     LLP := LLP@.NEXTLAB
                   ELSE BEGIN REDEF := TRUE; ERROR(166) END;
                 IF NOT REDEF THEN
                   BEGIN NEW(LLP);
                     WITH LLP@ DO BEGIN
                       LABNO := 0;
                       DEFINED := FALSE; NEXTLAB := FLABEL;
                       IF SY = INT2CONST
                           THEN BEGIN  ALF := FALSE; LABVAL  := VAL.IVAL END
                           ELSE BEGIN  ALF := TRUE;  LABNAME := ID;
                                       NEW(LCP,LABELS);  (* ALPHA LABEL *)
                                       WITH LCP@ DO
                                       BEGIN NAME := ID;
                                           KLASS  := LABELS;
                                           NEXT   := NIL;
                                           IDTYPE := NIL;
                                           END;
                                       ENTERID(LCP);    (* PUT IN SYMBOL TABLE *
)                                      IF STANDARD THEN WARNING(501) END
                       END;
                     FLABEL := LLP
                   END;
                 INSYMBOL
               END
           ELSE ERROR(404);
           IF NOT ( SY IN FSYS + (.COMMA, SEMICOLON.) ) THEN
             BEGIN ERROR(6); SKIP(FSYS+(.COMMA,SEMICOLON.)) END;
           TEST := SY <> COMMA;
           IF NOT TEST THEN INSYMBOL
         UNTIL TEST;
         IF SY = SEMICOLON THEN INSYMBOL ELSE ERROR(14)
       END (*  LABELDECLARATION  *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE CONSTDECLARATION
     ------------------------------------------------------------------------- *
)
       PROCEDURE CONSTDECLARATION;
         VAR LCP: CTP; LSP: STP; LVALU: VALU;
       BEGIN
         IF SY <> IDENT THEN
           BEGIN ERROR(2); SKIP(FSYS + (.IDENT.)) END;
         WHILE SY = IDENT DO
           BEGIN NEW(LCP,KONST);
             WITH LCP@ DO
               BEGIN NAME := ID; IDTYPE := NIL; NEXT := NIL; KLASS:=KONST END;
             INSYMBOL;
             IF (SY = RELOP) AND (OP = EQOP) THEN INSYMBOL ELSE ERROR(16);
             CONSTANT(FSYS + (.SEMICOLON.),LSP,LVALU);
             ENTERID(LCP);
             LCP@.IDTYPE := LSP; LCP@.VALUES := LVALU;
             IF LSP = REALPTR THEN
                BEGIN
                   NEW(LCP@.VALUES.VALP);
                   LCP@.VALUES.VALP@.RVAL := LVALU.VALP@.RVAL;
                END
             ELSE IF LSP = INT4PTR THEN
                     BEGIN
                        NEW (LCP@.VALUES.VALP);
                        LCP@.VALUES.VALP@.LINTVAL  := LVALU.VALP@.LINTVAL
                     END (*THEN*)
             ELSE IF LSP <> NIL THEN
                IF LSP@.FORM = STRINGS THEN
                   BEGIN
                      NEW(LCP@.VALUES.VALP);
                      LCP@.VALUES.VALP@.SLNGTH := LVALU.VALP@.SLNGTH;
                      NEW(LCP@.VALUES.VALP@.SVAL);
                      LCP@.VALUES.VALP@.SVAL@ := LVALU.VALP@.SVAL@;
                   END;
             IF SY = SEMICOLON THEN
               BEGIN INSYMBOL;
                 IF NOT (SY IN FSYS + (.IDENT.)) THEN
                   BEGIN ERROR(6); SKIP(FSYS + (.IDENT.)) END
               END
             ELSE ERROR(14)
           END
       END (* CONSTDECLARATION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE TYPEDECLARATION
     ------------------------------------------------------------------------- *
)
       PROCEDURE TYPEDECLARATION;
         VAR LCP,LCP1,LCP2: CTP; LSP: STP; LSIZE: ADDRRANGE;
       BEGIN
         IF SY <> IDENT THEN
           BEGIN ERROR(2); SKIP(FSYS + (.IDENT.)) END;
         WHILE SY = IDENT DO
           BEGIN NEW(LCP,TYPES);
             WITH LCP@ DO
               BEGIN NAME := ID; IDTYPE := NIL; KLASS := TYPES END;
             INSYMBOL;
             IF (SY = RELOP) AND (OP = EQOP) THEN INSYMBOL ELSE ERROR(16);
             TYP(FSYS + (.SEMICOLON.),LSP,LSIZE);
             ENTERID(LCP);
             LCP@.IDTYPE := LSP;
             (* HAS ANY FORWARD REFERENCE BEEN SATISFIED: *)
             LCP1 := FWPTR;
             WHILE LCP1 <> NIL DO
               BEGIN
                 IF LCP1@.NAME = LCP@.NAME THEN
                   BEGIN LCP1@.IDTYPE@.ELTYPE := LCP@.IDTYPE;
                     IF LCP1 <> FWPTR THEN
                       LCP2@.NEXT := LCP1@.NEXT
                     ELSE FWPTR := LCP1@.NEXT;
                   END;
                 LCP2 := LCP1; LCP1 := LCP1@.NEXT
               END;
             IF SY = SEMICOLON THEN
               BEGIN INSYMBOL;
                 IF NOT (SY IN FSYS + (.IDENT.)) THEN
                   BEGIN ERROR(6); SKIP(FSYS + (.IDENT.)) END
               END
             ELSE ERROR(14)
           END;
       END (* TYPEDECLARATION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE VARDECLARATION
     ------------------------------------------------------------------------- *
)
       PROCEDURE VARDECLARATION;
          VAR LCP,NXT,TNEXT: CTP; LSP: STP; LSIZE: ADDRRANGE; COUNT: 0..100 ;
              KFILE: EXTFILEP;      (* TEMP PTR INTO CHAIN OF EXTERNAL FILES *)
       BEGIN NXT := NIL;
          REPEAT   COUNT := 0 ;
           REPEAT
             IF SY = IDENT THEN
               BEGIN NEW(LCP,VARS);    COUNT := COUNT+1 ;
                 WITH LCP@ DO
                  BEGIN NAME := ID; NEXT := NXT; KLASS := VARS;
                     EXTRNL := FALSE;
                     IDTYPE := NIL; VKIND := ACTUAL; VLEV := LEVEL
                   END;
                 ENTERID(LCP);
                 NXT := LCP;
                 INSYMBOL;
               END
             ELSE ERROR(2);
                  (*CODE FOR ORIGIN*)
                   IF SY = LBRACK THEN BEGIN
                           INSYMBOL;
                           IF SY <> ORIGINSY THEN ERROR(415)
                                             ELSE BEGIN LCP@.VKIND := ORIGINED;
                                                        IF STANDARD THEN
                                                             WARNING(504) END;
                           LONGONLY  := TRUE;
                           INSYMBOL;
                           LONGONLY  := FALSE;
                           IF SY <> INT4CONST THEN ERROR(416)
                           ELSE
                              WITH VAL.VALP@ DO
                                 IF     (MACHINE = M6809)
                                    AND (   (LINTVAL(.4.) <> 0)
                                         OR (LINTVAL(.3.) <> 0))
                                    THEN  ERROR (203)
                                    ELSE  LCP@.VADDR  := LINTVAL;
                           INSYMBOL;
                           IF SY <> RBRACK THEN ERROR(417);
                           INSYMBOL
                      END;
                                                  (*END OF ORIGIN CODE *)
             IF NOT (SY IN FSYS + (.COMMA,COLON.) + TYPEDELS) THEN
               BEGIN ERROR(6); SKIP(FSYS+(.COMMA,COLON,SEMICOLON.)+TYPEDELS) END
;            TEST := SY <> COMMA;
             IF NOT TEST THEN INSYMBOL
           UNTIL TEST;
           IF SY = COLON THEN INSYMBOL ELSE ERROR(5);
           TYP(FSYS + (.SEMICOLON.) + TYPEDELS,LSP,LSIZE);

           WHILE NXT <> NIL DO
             WITH  NXT@ DO
               BEGIN   IDTYPE := LSP;
                  IF VKIND <> ORIGINED THEN  (*NO LOCAL ALLOC FOR ORIGIN*)
                        BEGIN   LOCN := LOCN - LSIZE;
                                IF LSIZE > 1 THEN LOCN := ALIGN(LOCN);
                                VADDR(.1.) := LOCN  END ;
                  IF (LOCN < MINADDR) OR (LOCN > MAXADDR) THEN
                        BEGIN  ERROR(504) ;  (*LOCAL DATA AREA TOO LARGE*)
                               LOCN :=  0 ;
                        END;

                     (*CODE TO CHECK IF FILE WAS MENTIONED IN FILE HEADER*)
                     (*ALSO TO CHAIN FILE DECL'S TOGETHER FOR LATER OPENS, ETC*)
                   IF LSP <> NIL THEN IF LSP@.FORM = FILES THEN
                           BEGIN (*MARK AS DEFINED ON LIST OF EXTERNAL FILES*)
                           IF (LEVEL = 0) AND (FEXTFILEP <> NIL) THEN
                                BEGIN KFILE := FEXTFILEP;
                                   WHILE KFILE <> NIL DO BEGIN
                                      IF KFILE@.FILENAME = NAME THEN
                                           BEGIN EXTRNL     := TRUE;
                                                 KFILE@.DEF := TRUE
                                           END;
                                      KFILE := KFILE@.NEXTFILE
                                      END
                                END;
                           TNEXT:=NEXT;
                           NEXT := LOCFILELIST;   (*ADD TO LOCAL FILE LIST*)
                           LOCFILELIST := NXT;
                           NXT := TNEXT ;
                           END
                   ELSE NXT := NEXT
                 ELSE NXT := NEXT
               END;

           IF SY = SEMICOLON THEN
             BEGIN INSYMBOL;
               IF NOT (SY IN FSYS + (.IDENT.)) THEN
                 BEGIN ERROR(6); SKIP(FSYS + (.IDENT.)) END
             END
           ELSE ERROR(14)
         UNTIL (SY <> IDENT) AND NOT (SY IN TYPEDELS);
       END (* VARDECLARATION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE PROCDECLARATION
     ------------------------------------------------------------------------- *
)
       PROCEDURE PROCDECLARATION(FSY: SYMBOL);
         VAR OLDLEV: LEVRANGE; LCP,LCP1: CTP; LSP: STP;
             FORW, NEWDEF: BOOLEAN; OLDTOP: DISPRANGE;
             LLC: ADDRRANGE;
             OLDLABEL: LABELRNG;
             MARKP:  @INTEGER;

   (* -------------------------------------------------------------------------
      PROCEDURE PARAMETERLIST
     ------------------------------------------------------------------------- *
)

         PROCEDURE PARAMETERLIST(FSY: SETOFSYS; VAR FPAR: CTP);
           VAR LCP,LCP1,LCP2,LCP3: CTP; LSP: STP; LKIND: IDKIND;
             LLC,LEN : ADDRRANGE; COUNT : INTEGER;
         BEGIN   LCP1 := NIL;    PARMLEN := 0;
           IF NOT (SY IN FSY + (.LPARENT.)) THEN
             BEGIN ERROR(7); SKIP(FSYS + FSY + (.LPARENT.)) END;
           IF SY = LPARENT THEN
             BEGIN IF FORW THEN ERROR(119);
               INSYMBOL;
               IF NOT (SY IN (.IDENT,VARSY,PROCSY,FUNCSY.)) THEN
                 BEGIN ERROR(7); SKIP(FSYS + (.IDENT,RPARENT.)) END;
               WHILE SY IN (.IDENT,VARSY,PROCSY,FUNCSY.) DO
                 BEGIN
                   IF SY = PROCSY THEN
                     BEGIN ERROR(398);
                       REPEAT INSYMBOL;
                         IF SY = IDENT THEN
                         BEGIN NEW(LCP,PROC,DECLARED,FORMAL);
                             WITH LCP@ DO
                               BEGIN NAME := ID; IDTYPE := NIL; NEXT := LCP1;
                                 PFLEV := LEVEL;
                                     (* BEWARE OF PARAMETER PROCEDURES *)
                                 KLASS:=PROC;PFDECKIND:=DECLARED;PFKIND:=FORMAL
                               END;
                             ENTERID(LCP);
                             LCP1 := LCP;
                             PARMLEN := PARMLEN + ADDRSIZE;
                             INSYMBOL
                           END
                         ELSE ERROR(2);
                         IF NOT (SY IN FSYS + (.COMMA,SEMICOLON,RPARENT.)) THEN
                           BEGIN ERROR(7);
                                 SKIP(FSYS+(.COMMA,SEMICOLON,RPARENT.)) END
                       UNTIL SY <> COMMA
                     END
                   ELSE
                     BEGIN
                       IF SY = FUNCSY THEN
                         BEGIN ERROR(398); LCP2 := NIL;
                           REPEAT INSYMBOL;
                             IF SY = IDENT THEN
                               BEGIN NEW(LCP,FUNC,DECLARED,FORMAL);
                                 WITH LCP@ DO
                                   BEGIN NAME := ID; IDTYPE := NIL; NEXT := LCP2
;                                    PFLEV := LEVEL (* BEWARE PARAM FUNCS *);
                                     KLASS:=FUNC;PFDECKIND:=DECLARED;
                                     PFKIND:=FORMAL
                                   END;
                                 ENTERID(LCP);
                                 LCP2 := LCP;
                                 PARMLEN := PARMLEN + ADDRSIZE;
                                 INSYMBOL;
                               END;
                             IF NOT (SY IN (.COMMA,COLON.) + FSYS) THEN
                              BEGIN ERROR(7);
                                    SKIP(FSYS+(.COMMA,SEMICOLON,RPARENT.))
                              END
                           UNTIL SY <> COMMA;
                           IF SY = COLON THEN
                             BEGIN INSYMBOL;
                               IF SY = IDENT THEN
                                 BEGIN SEARCHID((.TYPES.),LCP);
                                   LSP := LCP@.IDTYPE;
                                   IF LSP <> NIL THEN
                                    IF NOT(LSP@.FORM IN
                                           (.SCALAR,SUBRANGE,POINTER.))
                                       THEN BEGIN ERROR(120); LSP := NIL END;
                                   LCP3 := LCP2;
                                   WHILE LCP2 <> NIL DO
                                     BEGIN LCP2@.IDTYPE := LSP; LCP := LCP2;
                                       LCP2 := LCP2@.NEXT
                                     END;
                                   LCP@.NEXT := LCP1; LCP1 := LCP3;
                                   INSYMBOL
                                 END
                               ELSE ERROR(2);
                               IF NOT (SY IN FSYS + (.SEMICOLON,RPARENT.)) THEN
                                 BEGIN ERROR(7);
                                       SKIP(FSYS+(.SEMICOLON,RPARENT.)) END
                             END
                           ELSE ERROR(5)
                         END
                       ELSE
                         BEGIN
                           IF SY = VARSY THEN
                             BEGIN LKIND := FORMAL; INSYMBOL END
                           ELSE LKIND := ACTUAL;
                           LCP2 := NIL;
                           COUNT := 0;
                           REPEAT
                             IF SY = IDENT THEN
                               BEGIN NEW(LCP,VARS);
                                 WITH LCP@ DO
                                   BEGIN NAME:=ID; IDTYPE:=NIL; KLASS:=VARS;
                                     VKIND := LKIND; NEXT := LCP2; VLEV := LEVEL
;                                  END;
                                 ENTERID(LCP);
                                 LCP2 := LCP; COUNT := COUNT+1;
                                 INSYMBOL;
                               END;
                             IF NOT (SY IN (.COMMA,COLON.) + FSYS) THEN
                              BEGIN ERROR(7);
                                    SKIP(FSYS+(.COMMA,SEMICOLON,RPARENT.))
                               END;
                             TEST := SY <> COMMA;
                             IF NOT TEST THEN INSYMBOL
                           UNTIL TEST;
                           IF SY = COLON THEN
                             BEGIN INSYMBOL;
                               IF SY = IDENT THEN
                                 BEGIN  SEARCHID((.TYPES.),LCP); LEN := ADDRSIZE
;                                   LSP := LCP@.IDTYPE;
                                   IF LSP <> NIL THEN
                                     IF (LKIND=ACTUAL) THEN  BEGIN
                                      LEN := LSP@.SIZE    ;
                                      IF LSP@.FORM = FILES
                                            THEN ERROR(121);  END;
                                   (*IF LEN   > 1 THEN PARMLEN := ALIGN(PARMLEN)
;*)                                (*IF COUNT > 1 THEN LEN     := ALIGN(LEN);*)
                                   LEN := ALIGN(LEN);
                                      (*THE ABOVE IS SLIGHTLY LESS EFFICIENT
                                       THAN ABSOLUTELY NECESSARY (BYTE SIZE
                                       OBJECTS TAKE A WHOLE WORD ON WORD-ALIGNED
                                       MACHINES) *)
                                   PARMLEN := PARMLEN + COUNT * LEN;
                                   LCP3 := LCP2 ;
                                   LLC := PARMLEN;
                                   WHILE LCP2 <> NIL DO
                                     BEGIN LCP := LCP2;
                                       WITH LCP2@ DO
                                         BEGIN IDTYPE := LSP;
                                           VADDR(.1.) := LLC;
                                           LLC:=LLC - LEN;
                                         END;
                                       LCP2 := LCP2@.NEXT
                                     END;
                                   LCP@.NEXT := LCP1; LCP1 := LCP3;
                                   INSYMBOL
                                 END
                               ELSE ERROR(2);
                               IF NOT (SY IN FSYS + (.SEMICOLON,RPARENT.)) THEN
                                 BEGIN ERROR(7);
                                       SKIP(FSYS+(.SEMICOLON,RPARENT.)) END
                             END
                           ELSE ERROR(5);
                         END;
                     END;
                   IF SY = SEMICOLON THEN
                     BEGIN INSYMBOL;
                       IF NOT (SY IN FSYS + (.IDENT,VARSY,PROCSY,FUNCSY.)) THEN
                         BEGIN ERROR(7); SKIP(FSYS + (.IDENT,RPARENT.)) END
                     END
                 END (* WHILE *) ;
               IF SY = RPARENT THEN
                 BEGIN INSYMBOL;
                   IF NOT (SY IN FSY + FSYS) THEN
                     BEGIN ERROR(6); SKIP(FSY + FSYS) END
                 END
               ELSE ERROR(4);
               LCP3 := NIL;
               (* REVERSE POINTERS *)
               WHILE LCP1 <> NIL DO
                 WITH LCP1@ DO
                   BEGIN LCP2 := NEXT; NEXT := LCP3;
                         LCP3 := LCP1; LCP1 := LCP2
                   END;
               FPAR := LCP3
             END     (*  IF SY = LPAREN  *)
           ELSE FPAR := NIL  ;
       END (* PARAMETERLIST *) ;

       BEGIN (* **START** PROCDECLARATION *)
         LLC := LOCN;
         LOCN := 0;
         LCP := UPRCPTR ;            (*  TO INITIALIZE LCP IN CASE (.  *)
         IF SY = IDENT THEN
           BEGIN SEARCHSECTION(DISPLAY(.TOP.).FNAME,LCP);
                                          (* DECIDE WHETHER FORW. *)
             FORW := FALSE;
             IF LCP <> NIL THEN
                IF (LCP@.KLASS <> PROC) AND (LCP@.KLASS <> FUNC) THEN
                   LCP := NIL
                ELSE IF LCP@.PFDECKIND <> BUILTIN THEN
             BEGIN
               IF LCP@.KLASS = PROC THEN
                   FORW:=LCP@.FORWDECL AND(FSY=PROCSY)AND(LCP@.PFKIND=ACTUAL)
               ELSE
                 IF LCP@.KLASS = FUNC THEN
                   FORW:=LCP@.FORWDECL AND(FSY=FUNCSY)AND(LCP@.PFKIND=ACTUAL);
               IF NOT FORW THEN ERROR(160)
             END;
             IF NOT FORW THEN
               BEGIN
                 NEWDEF := LCP = NIL;
                      (*NEWDEF = FALSE IF REDEFINING BUILTIN PROC/FUNC*)
                 IF NEWDEF THEN
                     IF FSY = PROCSY THEN NEW(LCP,PROC,DECLARED,ACTUAL)
                                     ELSE NEW(LCP,FUNC,DECLARED,ACTUAL);
                 WITH LCP@ DO
                    BEGIN   NAME := ID ;  IDTYPE := NIL;
                      (*EXTERN := FALSE;*) PFLEV := LEVEL;
                      PFDECKIND := DECLARED; PFKIND := ACTUAL;
                      PROCLAB := PROCLAB+1;  PFNAME := PROCLAB;
                     IF FSY = PROCSY THEN KLASS := PROC
                     ELSE KLASS := FUNC
                   END;
                 IF NEWDEF THEN ENTERID(LCP)
               END
             ELSE BEGIN (*TAKE OFF LIST OF UNDECL'D FORWARD PROC/FUNCS*)
                IF FWDLIST <> NIL THEN
                        IF FWDLIST@.PF = LCP THEN
                                FWDLIST := FWDLIST@.NEXTPF
                        ELSE BEGIN KFWD :=FWDLIST;
                                WHILE KFWD@.NEXTPF <> NIL DO
                                IF KFWD@.NEXTPF@.PF = LCP
                                    THEN KFWD@.NEXTPF:=
                                            KFWD@.NEXTPF@.NEXTPF
                                ELSE KFWD := KFWD@.NEXTPF;
                             END;
                  END;
             INSYMBOL
           END
         ELSE ERROR(2);
         OLDLEV   := LEVEL;      OLDTOP   := TOP;
       (* OLDLABEL := INTLABEL ;  INTLABEL := 0 ;  UNIQUE LABELS *)
         IF LEVEL < MAXLEVEL THEN LEVEL := LEVEL + 1 ELSE ERROR(251);
         IF TOP < DISPLIMIT THEN
           BEGIN TOP := TOP + 1;
             WITH DISPLAY(.TOP.) DO
               BEGIN
                 IF FORW THEN FNAME := LCP@.NEXT
                 ELSE FNAME := NIL;
                 FLABEL := NIL;
                 OCCUR := BLCK
               END
           END
         ELSE ERROR(250);
         IF FSY = PROCSY THEN
           BEGIN PARAMETERLIST((.SEMICOLON.),LCP1);
             IF NOT FORW THEN LCP@.NEXT := LCP1;
           END
         ELSE
           BEGIN PARAMETERLIST((.SEMICOLON,COLON.),LCP1);
             IF NOT FORW THEN LCP@.NEXT := LCP1;
             IF SY = COLON THEN
               BEGIN INSYMBOL;
                 IF SY = IDENT THEN
                   BEGIN IF FORW THEN ERROR(122);
                     SEARCHID((.TYPES.),LCP1);
                     LSP := LCP1@.IDTYPE;
                     LCP@.IDTYPE := LSP;
                     IF (LSP <> NIL) AND STANDARD THEN
                          IF NOT (LSP@.FORM IN (.SCALAR,SUBRANGE,POINTER,POWER.)
)                         THEN WARNING(509);
                     INSYMBOL
                   END
                 ELSE BEGIN ERROR(2);
                            LCP@.IDTYPE := NIL;
                            SKIP(FSYS + (.SEMICOLON.))
                      END
               END
             ELSE
               IF NOT FORW THEN ERROR(123)
           END;

         IF FORW THEN
           PARMLEN := LCP@.PFADDR
         ELSE
           BEGIN
             LCP1 := LCP@.NEXT;
             WHILE LCP1 <> NIL DO
               BEGIN
                 WITH LCP1@ DO
                   IF KLASS = VARS THEN VADDR(.1.) := PARMLEN - VADDR(.1.);
                 LCP1 := LCP1@.NEXT
               END;
             LCP@.PFADDR := PARMLEN
           END;

         IF SY = SEMICOLON THEN INSYMBOL ELSE ERROR(14);
         IF SY = FORWARDSY THEN
           BEGIN
             IF FORW THEN ERROR(161)
             ELSE BEGIN LCP@.FORWDECL := TRUE;
                        (*PUT ON LIST OF FORWARD PROC/FUNCS*)
                        KFWD := FWDLIST;
                        NEW(FWDLIST);
                        FWDLIST@.NEXTPF := KFWD;
                        FWDLIST@.PF     := LCP  END;
             INSYMBOL;
             IF SY = SEMICOLON THEN INSYMBOL ELSE ERROR(14);
             IF NOT (SY IN FSYS+(.PERIOD.)) THEN
               BEGIN ERROR(6); SKIP(FSYS+(.PERIOD.)) END
           END
         ELSE
           BEGIN LCP@.FORWDECL := FALSE;    MARK (MARKP);
             REPEAT BLOCK(FSYS,SEMICOLON,LCP);
                    GENLI(77(* RET *),LEVEL,ALIGN(PARMLEN));
               IF SY = SEMICOLON THEN
                 BEGIN  INSYMBOL;
                   IF NOT (SY IN (.BEGINSY,PROCSY,FUNCSY.)) THEN
                     BEGIN ERROR(6); SKIP(FSYS) END
                 END
               ELSE IF NOT(SUBPROG AND (LEVEL=1)) THEN ERROR(14)
             UNTIL SY IN (.BEGINSY,PROCSY,FUNCSY,PERIOD.);
            RELEASE (MARKP); (* RELEASE LOCAL ENTRIES FROM RUNTIME HEAP *)
           END;
         LEVEL := OLDLEV; TOP := OLDTOP; LOCN := LLC;
        (*INTLABEL := OLDLABEL ;  SEE ABOVE: TO MAKE LABELS UNIQ ONLY INTRA-PROC
*)     END (* PROCDECLARATION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE BODY
     ------------------------------------------------------------------------- *
)
       PROCEDURE BODY(FSYS: SETOFSYS);
          CONST   CIXMAX = 1000;

       VAR
             SEGSIZE: LABELRNG;
             KLOCFILELIST: CTP;
             KFILE: EXTFILEP;      (* TEMP PTR INTO CHAIN OF EXTERNAL FILES *)
             STDFILE:BOOLEAN;
             LLCP:CTP;
             CSTPTR:  CSP;
               (* ALLOWS REFERENCING OF NONINTEGER CONSTANTS BY AN INDEX
                 (INSTEAD OF A POINTER), WHICH CAN BE STORED IN THE P2-FIELD
                 OF THE INSTRUCTION RECORD UNTIL WRITEOUT.
                 --> PROCEDURE LOAD, PROCEDURE WRITEOUT, NOT NEEDED IN P_COMP*)
             STATUS, ENTNAME, K: INTEGER;
             LCMIN, LLC1: ADDRRANGE; LCP: CTP;
             LLP: LBP;  PROCNAME : ALPHA ;

          FUNCTION GETTYPE(OPERAND: STP): CHAR;
            BEGIN      (* THE FOLLOWING COME IN FREQUENCY ORDER *)
              IF OPERAND = NIL THEN
                BEGIN
                  IF ERRORCOUNT = 0 THEN ERROR(500);
                  GETTYPE := 'I'
                END (*THEN*)
              ELSE IF (OPERAND = INT2PTR)
                      OR ((OPERAND@.FORM = SCALAR) AND (OPERAND@.SIZE = INT2SIZE
))            THEN
                GETTYPE := 'I'
              ELSE IF OPERAND@.FORM = POINTER THEN
                GETTYPE := 'A'
              ELSE IF OPERAND = CHARPTR THEN
                GETTYPE := 'C'
              ELSE IF OPERAND = BOOLPTR THEN
                GETTYPE := 'B'
              ELSE IF    (OPERAND = INT1PTR)
                      OR ((OPERAND@.FORM = SCALAR) AND (OPERAND@.SIZE = INT1SIZE
))            THEN
                GETTYPE  := 'H'
              ELSE IF OPERAND@.FORM = SUBRANGE THEN
                GETTYPE := GETTYPE(OPERAND@.RANGETYPE)
              ELSE IF OPERAND = INT4PTR THEN
                GETTYPE  := 'J'
              ELSE IF OPERAND@.FORM = STRINGS THEN
                GETTYPE := 'S'
              ELSE IF OPERAND@.FORM > STRINGS THEN
                GETTYPE := 'V'
              ELSE IF OPERAND@.FORM = POWER THEN
                GETTYPE := 'P'
              ELSE IF OPERAND = REALPTR THEN
                GETTYPE := 'R'
              ELSE
                GETTYPE := 'I'          (* DEFAULT TO INTEGER TYPE *)
            END (* GETTYPE *) ;




   (* -------------------------------------------------------------------------
      CODE GENERATION PROCEDURES
     ------------------------------------------------------------------------- *
)
           PROCEDURE GEN   (FOP:MNRANGE);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GEN*)


           PROCEDURE GENT  (FOP:MNRANGE; OPTYPE:CHAR);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENT*)


           PROCEDURE GEN2T (FOP:MNRANGE; OPTYPE1:CHAR; OPTYPE2:CHAR);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE1:3, OPTYPE2:3);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GEN2T*)


           PROCEDURE GENTI (FOP:MNRANGE; OPTYPE:CHAR; OPERAND:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    IF (FOP <> 45(*LDC*)) OR (OPTYPE <> 'C') THEN
                       WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, ' ', OPERAND)
                    ELSE BEGIN
                         WRITE(PCODE, MN(.FOP.):5, OPTYPE:3, ' ''', CHR(OPERAND)
);                       IF CHR(OPERAND)='''' THEN WRITE(PCODE,'''');
                         WRITELN(PCODE,'''') END;
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENTI*)


           PROCEDURE  GENTJ (FOP: MNRANGE;  OPTYPE: CHAR;  OPERAND: LNGINT);
              BEGIN (*GENTJ*)
                 IF PRCODE THEN
                    BEGIN
                       WRITE (PCODE,MN(.FOP.):5,OPTYPE:3,' ');
                       WRITELONG (PCODE,OPERAND);
                       WRITELN (PCODE,' ')
                    END (*THEN*)
              END; (*GENTJ*)


           PROCEDURE GENT2I(FOP:MNRANGE; OPTYPE:CHAR; OPERAND1:INTEGER;
                                                      OPERAND2:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, ' ', OPERAND1, ' ',
                                   OPERAND2);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENT2I*)


           PROCEDURE  GENT2J (FOP: MNRANGE;  OPTYPE: CHAR;
                              OPERAND1,OPERAND2: LNGINT);
              BEGIN (*GENT2J*)
                 IF PRCODE THEN
                    BEGIN
                       WRITE (PCODE,MN(.FOP.):5,OPTYPE:3,' ');
                       WRITELONG (PCODE,OPERAND1);
                       WRITE (PCODE,' ');
                       WRITELONG (PCODE,OPERAND2);
                       WRITELN (PCODE);

                       IC  := IC + 1
                    END (*THEN*)
              END; (*GENT2J*)



           PROCEDURE GEN2TI(FOP:MNRANGE; OPTYPE1:CHAR; OPTYPE2:CHAR;
                                                       OPERAND:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE1:3, OPTYPE2:3, ' ',
                                   OPERAND);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GEN2TI*)


           PROCEDURE GENI  (FOP:MNRANGE; OPERAND:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, ' ',  OPERAND);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENI*)


           PROCEDURE GENTLI(FOP:MNRANGE; OPTYPE:CHAR; LEVEL:LEVRANGE;
                                                     OPERAND:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, LEVEL:3, ' ', OPERAND)
;                   IC := IC + 1
                 END (*THEN*)
           END; (*GENTLI*)


           PROCEDURE GENTL2I(FOP:MNRANGE; OPTYPE:CHAR; LEVEL:LEVRANGE;
                                             OPERAND1,OPERAND2:INTEGER);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                   WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, LEVEL:3, ' ',
                                  OPERAND1,OPERAND2);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENTL2I*)


           PROCEDURE GENTL  (FOP:MNRANGE; OPTYPE:CHAR; LAB:LABELRNG);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, LAB:4);
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENTL*)


           PROCEDURE GENENT(ENTNM:INTEGER; FOP:MNRANGE; LEVEL:LEVRANGE;
                              LAB:LABELRNG; NAME:ALPHA);
           BEGIN
              IF PRCODE THEN
                 BEGIN
                    IF ENTNM = 0 THEN WRITE(PCODE,'    ')
                                 ELSE WRITE(PCODE,'$',ENTNM:3);
                    WRITELN(PCODE,MN(.FOP.):5,LEVEL:3,' ',
                                        LAB:4,' ''OPTIONS'' ''',NAME,'''');
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENENT*)


           PROCEDURE GENTV (FOP:MNRANGE; OPTYPE:CHAR; LVP:CSP);
           VAR I,J,K:INTEGER;
               TCHAR:CHAR;
           BEGIN
              IF PRCODE THEN
                 BEGIN
                       IF OPTYPE = 'R' THEN  (*OUTPUT REAL VALUE*)
                            WRITELN(PCODE, MN(.FOP.):5, OPTYPE:3, ' ', LVP@.RVAL
)                      ELSE IF OPTYPE = 'S' THEN   (*OUTPUT STRING VALUE*)
                          WITH LVP@ DO
                            BEGIN WRITE(PCODE, MN(.FOP.):5, OPTYPE:3,' ''');
                                  FOR I := 1 TO SLNGTH DO BEGIN
                                       TCHAR:=SVAL@(.I.);
                                       WRITE(PCODE,TCHAR);
                                       IF TCHAR='''' THEN WRITE(PCODE,TCHAR);
                                  END;
                                  WRITELN(PCODE,'''')
                            END
                       ELSE IF OPTYPE = 'P' THEN   (*OUTPUT SET VALUE*)
                            BEGIN WRITE(PCODE, MN(.FOP.):5, OPTYPE:3,' ');
                              FOR I := 0 TO 7 DO
                                BEGIN  J := 0 ;  K := SETRANGE-I*8 ;
                                FOR K := K DOWNTO K-7 DO
                                  BEGIN  J := J*2 ;
                                  IF K IN LVP@.PVAL THEN J := J+1 ;
                                  END ;
                                IF I > 0 THEN  WRITE(PCODE,',') ;
                                WRITE(PCODE, J:4) ;
                                END (*  FOR I := 0 TO 7  *) ;
                              WRITELN(PCODE)
                             END;
                    IC := IC + 1
                 END (*THEN*)
           END; (*GENTV*)


          PROCEDURE GENDEF(L1: LABELRNG; L2: ADDRRANGE ) ;
            BEGIN
               IF PRCODE THEN
                  WRITELN(PCODE,'L', L1:3,MN(.17(* DEF *).):5, L2:7);
            END (* GENDEF *) ;


          PROCEDURE GENKOUNT(PORK:BOOLEAN);

             BEGIN (* GENKOUNT *)
                IF (KOUNTERS OR (PORK AND PKOUNTERS)) AND PRCODE THEN
                   BEGIN
                      IF LABELEDKOUNT THEN
                         BEGIN
                            WRITELN(PCODE, MN(. 50 (*LSC*).):5, KOUNT);
                            LABELEDKOUNT := FALSE;
                         END
                      ELSE
                         WRITELN(PCODE, MN(. 40 (*ISC*).):5);
                      IC := IC + 1;
                   END;
                KOUNT := KOUNT + 1;
                PRINTKOUNT := TRUE;
             END (* GENKOUNT *);


   (* -------------------------------------------------------------------------
      PROCEDURE LOAD
     ------------------------------------------------------------------------- *
)
         PROCEDURE LOAD;
         VAR TIPE:CHAR;
         BEGIN
           WITH GATTR DO
             IF TYPTR <> NIL THEN
               BEGIN
                 TIPE:=GETTYPE(TYPTR);
                 CASE KIND OF
                   CST:   IF (TYPTR@.FORM = SCALAR) AND (TYPTR <> REALPTR) THEN
                            IF TYPTR = BOOLPTR THEN GENTI(45(*LDC*),'B',CVAL.IVA
L)                          ELSE
                             IF TIPE = 'C' THEN
                                     GENTI(45(*LDC*),'C',CVAL.IVAL)
                              ELSE IF TIPE = 'I' THEN
                                GENTI (45(*LDC*),'I',CVAL.IVAL)    (* INTEGER *)
                              ELSE IF TIPE = 'H' THEN
                                GENTI (45(*LDC*),'H',CVAL.IVAL)    (* SHORT INT
*)                            ELSE GENTJ (45(*LDC*),'J',CVAL.VALP@.LINTVAL)
                          ELSE
                            IF TYPTR = NILPTR THEN GENTJ(45(*LDC*),'A',LONGZERO)
                            ELSE
                                 BEGIN
                                  CSTPTR  := CVAL.VALP;
                                  IF TYPTR = REALPTR THEN
                                     GENTV(45(*LDC*),'R',CSTPTR)
                                  ELSE IF TYPTR@.FORM = STRINGS THEN
                                       GENTV(45(*LDC*),'S',CSTPTR)
                                  ELSE GENTV(45(*LDC*),'P',CSTPTR)
                                END;
                   VARBL: BEGIN
                            CASE ACCESS OF
                              DRCT:   IF TIPE = 'V'
                                        THEN GENTL2I(48(*LOD*),TIPE,VLEVEL,
                                                   DPLMT,TYPTR@.SIZE)
                                        ELSE GENTLI(48(*LOD*),TIPE,VLEVEL,DPLMT)
;                             INDRCT: IF TIPE = 'V'
                                        THEN GENT2I(35(*IND*),TIPE,
                                                   IDPLMT,TYPTR@.SIZE)
                                        ELSE GENTI (35(*IND*),TIPE,IDPLMT)
                          END END;
                   FILEPTR: BEGIN
                              GENI(112 (* MST *), 0 (* BUILTIN *));
                              IF ACCESS = DRCT THEN
                                 BEGIN ACCESS := INDRCT;
                                 GENLI(44(*LDA*),VLEVEL,DPLMT);
                                 END;
                                  GENTI(116 (*ARG*), 'A', 0);
                                  GEN(65(*PEE*));
                                  IF TIPE = 'V'
                                        THEN GENT2I(35(*IND*),TIPE,0,TYPTR@.SIZE
)                                       ELSE GENTI (35(*IND*),TIPE,0)
                            END;
                   EXPR:
                 END;
                 KIND := EXPR
               END
         END (* LOAD *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE STORE
     ------------------------------------------------------------------------- *
)
         PROCEDURE STORE(VAR FATTR: ATTR);
         VAR TIPE:CHAR;
         BEGIN
           WITH FATTR DO
             IF TYPTR <> NIL THEN
               BEGIN TIPE := GETTYPE(TYPTR);
               CASE ACCESS OF
                 DRCT:   IF (TIPE = 'V') OR (TIPE = 'S')
                           THEN GENTL2I(96(*STR*),TIPE,VLEVEL,DPLMT,TYPTR@.SIZE)
                           ELSE GENTLI (96(*STR*),TIPE,VLEVEL,DPLMT);
                 INDRCT: IF IDPLMT <> 0 THEN ERROR(400)
                         ELSE  IF (TIPE = 'V') OR (TIPE = 'S')
                           THEN GENTI(94(*STO*),TIPE,TYPTR@.SIZE)
                           ELSE GENT (94(*STO*),TIPE)
               END END
         END (* STORE *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE LOADADDRESS
     ------------------------------------------------------------------------- *
)
         PROCEDURE LOADADDRESS;
         BEGIN
           WITH GATTR DO
             IF TYPTR <> NIL THEN
               BEGIN
                 CASE KIND OF
                   CST:   IF CHARARRAY(TYPTR) THEN
                             BEGIN
                             CSTPTR := CVAL.VALP ;
                             GENTV(43(*LCA*),'S',CSTPTR);
                             END
                          ELSE ERROR(400);
                   VARBL: CASE ACCESS OF
                            DRCT:   GENLI(44(*LDA*),VLEVEL,DPLMT);
                            INDRCT: IF IDPLMT <> 0 THEN
                                       GENTI(34(*INC*),'A',IDPLMT)
                          END;
                   FILEPTR: IF ACCESS = DRCT
                               THEN GENTLI(48(*LOD*),'A',VLEVEL,DPLMT)
                               ELSE GENTI (35(*IND*),'A',0);
                   EXPR:  ERROR(400)
                 END;
                 KIND := VARBL; ACCESS := INDRCT; IDPLMT := 0
               END
         END (* LOADADDRESS *) ;


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  CHKBNDS (LHSP,RHSP,ERR)                          *)
   (*                                                                    *)
   (*        THIS PROCEDURE FIRST CHECKS TO MAKE SURE THAT THE TYPES     *)
   (*        POINTED TO BY 'RHSP' AND 'LHSP' ARE ASSIGNMENT              *)
   (*        COMPATABLE (IE. THEIR RANGES INTERSECT SOMEWHERE).  IF      *)
   (*        THEY ARE NOT, THE ERROR INDICATED BY 'ERR' IS GENERATED.    *)
   (*        IF THEY ARE, AND DEBUGGING IS ON, A CHK INSTRUCTION IS      *)
   (*        GENERATED TO CHECK AT RUNTIME IF THE VALUE ON THE TOP OF    *)
   (*        THE STACK IS WITHIN THE RANGE INDICATED BY 'LHSP'.          *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  CHKBNDS (LHSP,RHSP: STP;  ERR: INTEGER);

      VAR
         LHSMIN,LHSMAX,
         RHSMIN,RHSMAX,
         LMIN,LMAX:         LNGINT;
         IMIN,IMAX:         INTEGER;
         K:                 CHAR;

      BEGIN (*CHKBNDS*)
         IF (LHSP <> NIL) AND (RHSP <> NIL) THEN
            IF     (LHSP <> BOOLPTR) AND (LHSP <> INT4PTR)
               AND (LHSP <> REALPTR) AND (LHSP@.FORM < POINTER) THEN
               BEGIN
                  GETBOUNDS (LHSP,LHSMIN,LHSMAX);
                  GETBOUNDS (RHSP,RHSMIN,RHSMAX);

                  IF COMPLONGS(LHSMIN,RHSMIN) = LNGGREATER
                     THEN  LMIN  := LHSMIN
                     ELSE  LMIN  := RHSMIN;

                  IF COMPLONGS(LHSMAX,RHSMAX) = LNGLESS
                     THEN  LMAX  := LHSMAX
                     ELSE  LMAX  := RHSMAX;

                  IF COMPLONGS(LMIN,LMAX) = LNGGREATER
                     THEN  ERROR(ERR)
                     ELSE

                  IF DEBUG THEN
                     BEGIN                 (* GENERATE THE CHK INSTRUCTION *)
                        K  := GETTYPE (RHSP);

                        IF K = 'J'
                           THEN  GENT2J (6 (*CHK*),K,LMIN,LMAX)
                           ELSE  BEGIN
                                    IMIN  := MAKESHORT(LMIN);
                                    IMAX  := MAKESHORT(LMAX);
                                    GENT2I (6 (*CHK*),K,IMIN,IMAX)
                                 END (*ELSE*)
                     END (*THEN*)

               END (*THEN*)

      END; (*CHKBNDS*)


   (* -------------------------------------------------------------------------
      PROCEDURE PUTLABEL
     ------------------------------------------------------------------------- *
)
         PROCEDURE PUTLABEL(LABNUM: LABELRNG);
         BEGIN
            IF PRCODE THEN
               BEGIN
                  WRITELN(PCODE, 'L', LABNUM:3,' LAB');
                  LABELEDKOUNT := TRUE;
               END (*THEN*)
         END (* PUTLABEL *);


   (* -------------------------------------------------------------------------
      PROCEDURE STATEMENT
     ------------------------------------------------------------------------- *
)
         PROCEDURE STATEMENT(FSYS: SETOFSYS);
           VAR LCP: CTP;   LLP: LBP;
               FOUND, INLOOP: BOOLEAN;
               TTOP: DISPRANGE ;


   (* -------------------------------------------------------------------------
      PROCEDURE EXPRESSION
     ------------------------------------------------------------------------- *
)
           PROCEDURE EXPRESSION(FSYS: SETOFSYS); FORWARD;


   (*$E------------------------------------------------------------------*)
   (*                    PROCEDURE CNVRTTOLHS                          *)
   (*                                                                    *)
   (*      CNVRTTOLHS STANDS FOR CONVERT TO LEFT HAND SIDE.            *)
   (* IF THE TYPE OF THE RIGHT HAND SIDE IS NOT THE SAME AS THE LEFT     *)
   (* HAND SIDE THE A CONVERT INSTRUCTION IS GENERATED TO CONVERT THE    *)
   (* RIGHT TO THE SAME SIDE AS THE LEFT.                                *)
   (*--------------------------------------------------------------------*)

           PROCEDURE CNVRTTOLHS (LEFTSIDE: STP; VAR RIGHTSIDE: STP);

              VAR
                 LEFTKIND,
                 RIGHTKIND: CHAR;   (* INTERNAL TYPE OF OPERANDS *)

              BEGIN
                 IF LEFTSIDE <> NIL THEN
                    IF LEFTSIDE@.FORM = SUBRANGE THEN
                       LEFTSIDE := LEFTSIDE@.RANGETYPE;

                 LEFTKIND := GETTYPE (LEFTSIDE);
                 RIGHTKIND := GETTYPE (RIGHTSIDE);

                 IF LEFTKIND <> RIGHTKIND THEN
                    BEGIN
                       GEN2T (13 (*CVT*), RIGHTKIND, LEFTKIND);
                       RIGHTSIDE := LEFTSIDE;
                    END;
              END   (* CNVRTTOLHS *);


   (*$E------------------------------------------------------------------------
      PROCEDURE SELECTOR
     ------------------------------------------------------------------------- *
)
           PROCEDURE SELECTOR(FSYS: SETOFSYS; FCP: CTP);
             VAR
                LATTR:    ATTR;
                LCP:      CTP;
                LMIN,
                LMAX:     INTEGER;
                K:        CHAR;
                I:        INTEGER;
                LNGMIN,
                LNGMAX:   LNGINT;
           BEGIN
             WITH FCP@, GATTR DO
               BEGIN TYPTR := IDTYPE; KIND := VARBL;
                 CASE KLASS OF
                   TYPES:  ;
                   KONST:  ;
                   VARS:
                     IF VKIND = ACTUAL THEN
                       BEGIN ACCESS := DRCT; VLEVEL := VLEV;
                         DPLMT := VADDR(.1.)
                       END
                     ELSE (*VKIND = FORMAL OR ORIGINED*)
                       BEGIN
                         IF VKIND = ORIGINED
                            THEN GENTJ(45 (*LDC*), 'A', VADDR)
                            ELSE GENTLI(48 (*LOD*), 'A', VLEV, VADDR(.1.));
                         ACCESS := INDRCT; IDPLMT := 0
                       END;
                   FIELD:
                     WITH DISPLAY(.DISX.) DO
                       IF OCCUR = CREC THEN
                         BEGIN ACCESS := DRCT; VLEVEL := CLEV;
                           DPLMT := CDSPL + FLDADDR
                         END
                       ELSE
                         BEGIN
                           GENTLI(48(*LOD*),'A',LEVEL,VDSPL)  ;
                           ACCESS := INDRCT; IDPLMT := FLDADDR
                         END;
                   PROC:  ;
                   FUNC:
                     IF PFDECKIND = BUILTIN THEN ERROR(150)
                       ELSE
                         IF PFKIND = FORMAL THEN ERROR(151)
                         ELSE
                            IF (FPROCP <> FCP) THEN  ERROR(177)
                            ELSE
                             BEGIN ACCESS := DRCT; VLEVEL := PFLEV + 1;
                              DPLMT := PFADDR;
                             END
                 END (* CASE *) ;
               END (* WITH *);
             IF NOT (SY IN SELECTSYS + FSYS) THEN
               BEGIN ERROR(59); SKIP(SELECTSYS + FSYS) END;
             WHILE SY IN SELECTSYS DO
               BEGIN
           (* (. *)   IF SY = LBRACK THEN
                   BEGIN
                     IF GATTR.TYPTR = NIL THEN
                        BEGIN
                           ERROR(138);
                           INSYMBOL;
                           SKIP((.RBRACK.)+SELECTSYS+FSYS)
                        END
                     ELSE
                     BEGIN
                       IF GATTR.TYPTR@.FORM = ARRAYS THEN
                           REPEAT LATTR := GATTR;
                             WITH LATTR DO
                               IF TYPTR <> NIL THEN
                                 IF TYPTR@.FORM <> ARRAYS THEN
                                   BEGIN ERROR(138); TYPTR := NIL END;
                             LOADADDRESS;
                             INSYMBOL; EXPRESSION(FSYS + (.COMMA,RBRACK.));
                             LOAD;
                             IF GATTR.TYPTR <> NIL THEN
                               IF GATTR.TYPTR@.FORM <> SCALAR THEN ERROR(113);
                             IF LATTR.TYPTR <> NIL THEN
                               WITH LATTR.TYPTR@ DO
                                 BEGIN
                                   IF COMPTYPES(INXTYPE,GATTR.TYPTR) THEN
                                     BEGIN
                                      IF INXTYPE <> NIL THEN
                                         BEGIN
                                            CHKBNDS (INXTYPE, GATTR.TYPTR, 139);
                                            K := GETTYPE (GATTR.TYPTR);
                                            IF K <> 'I' THEN
                                               GEN2T (13 (*CVT*), K, 'I');
                                            GETBOUNDS (INXTYPE, LNGMIN, LNGMAX);
                                            LMIN := MAKESHORT (LNGMIN);
                                            IF LMIN > 0 THEN
                                               GENTI (16 (*DEC*), 'I', LMIN)
                                            ELSE IF LMIN < 0 THEN
                                               GENTI (34 (*INC*), 'I', ABS (LMIN
));                                      END
                                     END
                                   ELSE ERROR(139);
                                   WITH GATTR DO
                                     BEGIN TYPTR := AELTYPE; KIND := VARBL;
                                       ACCESS := INDRCT; IDPLMT := 0 ;
                                       IF GATTR.TYPTR <> NIL THEN
                                          BEGIN  LMIN := TYPTR@.SIZE ;
                                          GENI(41(*IXA*),LMIN)
                                          END (* TYPTR <> NIL *) ;
                                     END (* WITH GATTR DO *) ;
                                 END
                           UNTIL SY <> COMMA
                       ELSE IF GATTR.TYPTR@.FORM = STRINGS THEN
                          BEGIN
                            LOADADDRESS;
                            INSYMBOL;
                            EXPRESSION(FSYS + (.RBRACK.));
                            LOAD;
                            IF GATTR.TYPTR <> NIL THEN
                               IF COMPTYPES(GATTR.TYPTR,INT2PTR)
                                  THEN  CNVRTTOLHS (INT2PTR,GATTR.TYPTR)
                                  ELSE  ERROR (139);
                            WITH GATTR DO
                                BEGIN
                                TYPTR := CHARPTR;
                                KIND  := VARBL;
                                ACCESS:= INDRCT;
                                IDPLMT:= ALIGNMENT - 1;
                                END;
                            GENI(41(*IXA*),1);
                          END
                       ELSE
                          BEGIN
                             ERROR(138);
                             INSYMBOL;
                             SKIP((. RBRACK .)+SELECTSYS+FSYS)
                          END
                     END; (* IF GATTR.TYPTR = NIL *)
                  IF SY = RBRACK THEN INSYMBOL ELSE ERROR(12)
                END (* IF SY = LBRACK *)
              ELSE
           (* . *) IF SY = PERIOD THEN
                     BEGIN
                       WITH GATTR DO
                         BEGIN
                           IF TYPTR <> NIL THEN
                             IF TYPTR@.FORM <> RECORDS THEN
                               BEGIN ERROR(140); TYPTR := NIL END;
                           INSYMBOL;
                           IF SY = IDENT THEN
                             BEGIN
                               IF TYPTR <> NIL THEN
                                 BEGIN SEARCHSECTION(TYPTR@.FSTFLD,LCP);
                                   IF LCP = NIL THEN
                                     BEGIN ERROR(152); TYPTR := NIL END
                                   ELSE
                                     WITH LCP@ DO
                                       BEGIN TYPTR := IDTYPE;
                                         CASE ACCESS OF
                                           DRCT:   DPLMT := DPLMT + FLDADDR;
                                           INDRCT: IDPLMT := IDPLMT + FLDADDR
                                         END
                                       END
                                 END;
                               INSYMBOL
                             END (* SY = IDENT *)
                           ELSE ERROR(2)
                         END (* WITH GATTR *)
                     END (* IF SY = PERIOD *)
                   ELSE
           (* @ *)       BEGIN
                       IF GATTR.TYPTR <> NIL THEN
                         WITH GATTR,TYPTR@ DO
                           IF (FORM = POINTER) THEN
                             BEGIN
                                LOAD ;
                                IF DEBUG THEN GENT2I (6 (*CHK*), 'A', 0, 0);
                                TYPTR := ELTYPE;
                                WITH GATTR DO
                                   BEGIN KIND   := VARBL;
                                         ACCESS := INDRCT;
                                         IDPLMT := 0
                                   END
                             END
                           ELSE IF FORM = FILES THEN BEGIN
                                   TYPTR:=FILTYPE;
                                   GATTR.KIND := FILEPTR
                                END
                           ELSE ERROR(141);
                       INSYMBOL
                     END;
                 IF NOT (SY IN FSYS + SELECTSYS) THEN
                   BEGIN ERROR(6); SKIP(FSYS + SELECTSYS) END ;
               END (* WHILE *) ;
           END (* SELECTOR *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE CALL
     ------------------------------------------------------------------------- *
)
           PROCEDURE CALL(FSYS: SETOFSYS; FCP: CTP);
             VAR LKEY: STDNAMES;


   (* -------------------------------------------------------------------------
      PROCEDURE VARIABLE
     ------------------------------------------------------------------------- *
)
             PROCEDURE VARIABLE(FSYS: SETOFSYS);
               VAR LCP: CTP;
             BEGIN
               IF SY = IDENT THEN
                 BEGIN SEARCHID((.VARS,FIELD.),LCP); INSYMBOL END
               ELSE BEGIN ERROR(2); LCP := UVARPTR END;
               SELECTOR(FSYS,LCP)
             END (* VARIABLE *) ;




   (* -------------------------------------------------------------------------
     STANDARD PROCEDURE CALL HANDLERS
     ------------------------------------------------------------------------- *
)
      PROCEDURE IFNOTINTEGERTHENERROR (ERR: INTEGER);

         BEGIN
            IF GATTR.TYPTR <> NIL THEN
               IF INTTYPE(GATTR.TYPTR) THEN
                  BEGIN
                     IF GATTR.TYPTR <> INT2PTR THEN
                        GEN2T(13 (*CVT*), GETTYPE(GATTR.TYPTR), 'I');
                     GENTI(116 (*ARG*), 'I', SYSTEM);
                  END
               ELSE
                  ERROR(ERR);
         END (* IFNOTINTEGERTHENERROR *);

            PROCEDURE RWSETUP(DEFAULTFILE: CTP; VAR ACTUAL:CTP;
                              RD: BOOLEAN; VAR TEXTF: BOOLEAN; DELAY:BOOLEAN);
                  (*  TO SET UP FILE ADDRESS PARAMETER FOR READ/WRITE  *)
              VAR LCP: CTP; SAVED: BOOLEAN; TEMPSY: SYMBOL;

              BEGIN  SAVED := TRUE ;
              IF SY = IDENT THEN
                  BEGIN  SEARCHID((.VARS,FIELD,FUNC,KONST.),LCP) ;
                       IF LCP@.IDTYPE <> NIL THEN
                           IF LCP@.IDTYPE@.FORM = FILES THEN SAVED := FALSE;
                  END  (*SY = IDENT*) ;
              IF SAVED THEN BEGIN IF DEFAULTFILE <> NIL THEN LCP := DEFAULTFILE
                                                        ELSE BEGIN IF RD
                                                                 THEN ERROR(175)
                                                                 ELSE ERROR(176)
;                                                              LCP := UVARPTR
                                                             END;
                                  TEMPSY := SY; SY := COMMA
                            END
                       ELSE  INSYMBOL ;
              TEXTF := LCP@.IDTYPE = TEXTPTR;
              IF TEXTF OR NOT DELAY THEN BEGIN
                    GENI(112 (*MST*),0 (*BUILTIN CALL*));
                    SELECTOR(FSYS+(.COMMA,RPARENT.),LCP) ;
                    LOADADDRESS; (*GET FILE ADR*)
                    GENTI(116 (*ARG*), 'A', 0);
                  END;
              ACTUAL := LCP;
              IF SAVED THEN SY := TEMPSY;
              END (* RWSETUP *) ;


           PROCEDURE GETPUTPAGE;
           VAR MKEY: MNRANGE;
               TFILE: CTP;
               TEXTF,PARAMS,RD: BOOLEAN;
           BEGIN
             IF SY = LPARENT THEN BEGIN PARAMS := TRUE; INSYMBOL END
                             ELSE       PARAMS := FALSE;
             IF LKEY = XGET THEN BEGIN TFILE := STDINPUT(*GET*);
                                         RD := TRUE  END
                         ELSE BEGIN TFILE := STDOUTPUT(*PUT,PAGE*);RD := FALSE E
ND;          RWSETUP(TFILE,TFILE,RD,TEXTF,FALSE); (*DEFAULT IS IN 'TFILE'*)
             IF GATTR.TYPTR <> NIL THEN
               IF GATTR.TYPTR@.FORM <> FILES THEN ERROR(116);
             IF      LKEY = XGET THEN MKEY := 31(*GET *)
             ELSE IF LKEY = XPUT THEN MKEY := 68(*PUT *)
                                   ELSE MKEY :=64(*PAGE*);
             GEN(MKEY(* GET,PUT *)) ;
             IF PARAMS THEN IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
           END (* GETPUTPAGE *) ;

      PROCEDURE CHECKFORCHAR;

         BEGIN
            IF GATTR.TYPTR = CHARPTR THEN
               BEGIN
                  GEN2T(13 (*CVT*), 'C', 'S');
                  GATTR.TYPTR := SINGLECHARSTRING;
               END;
         END (* CHECKFORCHAR *);

           PROCEDURE RESETREWRITE;
           VAR MKEY: MNRANGE;
               TFILE: CTP;
               TEXTF,PARAMS,RD: BOOLEAN;
           BEGIN
               IF SY = LPARENT THEN BEGIN PARAMS := TRUE; INSYMBOL END
                               ELSE       PARAMS := FALSE;
               IF LKEY = XRESET THEN BEGIN TFILE := STDINPUT(*RST*);
                                             RD := TRUE  END
                            ELSE BEGIN TFILE := STDOUTPUT(*RWT*);RD := FALSE END
;              RWSETUP(TFILE,TFILE,RD,TEXTF,FALSE); (*DEFAULT IS IN 'TFILE'*)
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR@.FORM <> FILES THEN ERROR(116);
               IF SY = COMMA THEN BEGIN
                   IF STANDARD THEN WARNING(508);
                   LOADADDRESS;  (*OF FILE DESCRIPTOR FOR 'AFI'*)
                   INSYMBOL;
                   EXPRESSION(FSYS + (.RPARENT.)); LOAD;
                   CHECKFORCHAR;
                   IF GATTR.TYPTR <> NIL THEN
                          IF (GATTR.TYPTR@.FORM <> STRINGS) THEN
                             ERROR(116)
                          ELSE
                             GENT2I(116 (*ARG*), 'S', 0, GATTR.TYPTR@.SIZE);
                   (*IF NOT CHARARRAY(GATTR.TYPTR) THEN ERROR(116); *)
                   GEN(2 (* AFI *))
                 END;
               IF LKEY = XRESET THEN MKEY := 80(*RST*)
                                 (*AFI LEAVES DESCRIPTOR ON STK*)
                           ELSE MKEY := 81(*RWT*);
               GEN(MKEY (* RST,RWT *)) ;
               IF PARAMS THEN IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END (* RESETREWRITE *) ;


             PROCEDURE READ1;
              VAR PARAMS,TEXTF: BOOLEAN;
                  K:CHAR; FSP:STP;
                  ACTUALFILE: CTP;
            BEGIN
             IF SY = LPARENT THEN BEGIN PARAMS := TRUE; INSYMBOL END
                             ELSE       PARAMS := FALSE;
             RWSETUP(STDINPUT,ACTUALFILE,TRUE,TEXTF,TRUE); (*DEFAULT IS 'INPUT'*
)            IF PARAMS THEN
               BEGIN
                  IF ACTUALFILE@.IDTYPE <> NIL THEN
                     FSP := ACTUALFILE@.IDTYPE@.FILTYPE
                  ELSE
                     FSP := NIL;
               K := GETTYPE(FSP);
               IF (SY = RPARENT) AND (LKEY = XREAD) THEN ERROR(116);
                                  (*'6' IS 'READ'; IT'S REQ'D TO HAVE AT LEAST
                                    ONE PARAM; CAREFUL IF PROC #'S CHANGE *)
               IF SY = COMMA THEN  INSYMBOL;
               IF SY = IDENT THEN
                 REPEAT  VARIABLE(FSYS + (.COMMA,RPARENT.));
                  LOADADDRESS;
                  IF TEXTF THEN BEGIN
                   GENTI(116 (*ARG*), 'A', 0);
                   IF GATTR.TYPTR <> NIL THEN
                      IF CHARARRAY(GATTR.TYPTR) THEN
                        BEGIN
                        GENTI(45(*LDC*),'I',GATTR.TYPTR@.SIZE DIV CHARSIZE);
                        GENTI(116 (*ARG*), 'I', 0);
                        GEN  (114 (*RDV*));
                        END
                     ELSE
                      IF GATTR.TYPTR@.FORM = STRINGS THEN
                        BEGIN
                        GENTI(45(*LDC*),'I',GATTR.TYPTR@.SIZE(*STRSZ*));
                        GENTI(116 (*ARG*), 'I', 0);
                        GEN(76 (*RDS*))
                        END
                     ELSE
                      BEGIN
                       K  := GETTYPE (GATTR.TYPTR);
                       IF K = 'J' THEN
                         GEN(73 (*RDJ*))
                       ELSE
                         IF K = 'H' THEN
                           GEN(117 (*RDH*))
                         ELSE
                           IF K = 'I' THEN
                             GEN(72 (*RDI*))
                           ELSE
                             IF K = 'R' THEN
                               GEN(75 (*RDR*))
                             ELSE
                               IF K = 'C' THEN
                                 GEN(70 (*RDC*))
                                ELSE
                                  IF K = 'B' THEN
                                    GEN(69 (*RDB*))
                                  ELSE  ERROR(116) ;
                        END ;
                   END ELSE (*NONTEXT FILE*)
                         IF COMPTYPES(FSP,GATTR.TYPTR) THEN
                         BEGIN
                           GENI (112(*MST*),0);
                           WITH ACTUALFILE@ DO IF VKIND = ACTUAL
                                   THEN GENLI (44 (*LDA*),VLEV,VADDR(.1.))
                                   ELSE GENTLI(48 (*LOD*),'A',VLEV,VADDR(.1.));
                           GENTI(116 (*ARG*),  'A', 0);
                           GEN  (65 (*PEE*));
                           IF K = 'V' THEN BEGIN
                               GENT2I(35 (*IND*),K,0,FSP@.SIZE);
                               GENTI (94 (*STO*),K,FSP@.SIZE);
                           END
                           ELSE BEGIN
                               GENTI(35 (*IND*),K,0);
                               GENT (94 (*STO*),K);
                           END;
                           GENI (112(*MST*),0);
                           WITH ACTUALFILE@ DO IF VKIND = ACTUAL
                                   THEN GENLI (44 (*LDA*),VLEV,VADDR(.1.))
                                   ELSE GENTLI(48 (*LOD*),'A',VLEV,VADDR(.1.));
                           GENTI(116 (*ARG*), 'A', 0);
                           GEN(31(*GET*));
                         END
                         ELSE ERROR(127);
                   TEST := SY <> COMMA;
                   IF NOT TEST THEN INSYMBOL
                 UNTIL TEST ;
               IF TEXTF THEN
                 IF LKEY = XREADLN THEN GEN(78(*RLN*)) ELSE GEN(111(*EIO*));
               IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
               END
            ELSE IF LKEY = XREADLN THEN GEN(78 (*RLN*)) ELSE ERROR(9);
          END (* READ1 *) ;



             PROCEDURE WRITE1;
               VAR LSP: STP; DEFAULT : BOOLEAN;
                   PARAMS,TEXTF: BOOLEAN;
                   K:CHAR; FSP:STP;
                   ACTUALFILE: CTP;
            BEGIN
             IF SY = LPARENT THEN BEGIN PARAMS := TRUE; INSYMBOL END
                             ELSE       PARAMS := FALSE;
               RWSETUP(STDOUTPUT,ACTUALFILE,FALSE,TEXTF,TRUE);
                                            (*DEFAULT IS 'OUTPUT'*)
             IF PARAMS THEN
                BEGIN
                   IF ACTUALFILE@.IDTYPE <> NIL THEN
                      FSP := ACTUALFILE@.IDTYPE@.FILTYPE
                   ELSE
                      FSP := NIL;
                K := GETTYPE(FSP);
                TEST := FALSE ;
                IF (SY = RPARENT) THEN
                  BEGIN  TEST := TRUE ;
                         IF LKEY = XWRITE THEN ERROR(116) ; END ;
                                  (*'7' IS 'WRITE'; IT'S REQ'D TO HAVE AT LEAST
                                    ONE PARAM; CAREFUL IF PROC #'S CHANGE *)
                IF SY = COMMA THEN  INSYMBOL ;
                IF NOT TEST THEN
                  REPEAT IF TEXTF THEN BEGIN
                   EXPRESSION(FSYS+(.COMMA,COLON,RPARENT.)) ;
                   LSP := GATTR.TYPTR;
                   IF LSP <> NIL THEN
                      BEGIN
                         K := GETTYPE(LSP);
                         LOAD;
                         IF (K = 'S') OR (K = 'V') THEN
                            GENT2I(116 (*ARG*), K, 0, LSP@.SIZE)
                         ELSE
                            GENTI(116 (*ARG*), K, 0);
                      END;
                   IF SY = COLON THEN
                     BEGIN INSYMBOL; EXPRESSION(FSYS + (.COMMA,COLON,RPARENT.));
                       LOAD; DEFAULT := FALSE;
                       IFNOTINTEGERTHENERROR (116)
                     END
                   ELSE DEFAULT := TRUE;
                   IF SY = COLON THEN
                     BEGIN  INSYMBOL;  EXPRESSION(FSYS + (.COMMA,RPARENT.));
                       IF LSP <> REALPTR THEN ERROR(124);
                       LOAD; ERROR(398);
                       IFNOTINTEGERTHENERROR (116)
                     END
                   ELSE
                     IF LSP = INT4PTR THEN
                        BEGIN
                           IF DEFAULT THEN
                              BEGIN
                                 GENTI(45 (*LDC*),'I',12);
                                 GENTI(116(*ARG*),'I',SYSTEM)
                              END; (*THEN*)
                           GEN(105 (*WRJ*))
                        END (*THEN*)
                     ELSE IF LSP = INT1PTR THEN
                             BEGIN
                                IF DEFAULT THEN
                                   BEGIN
                                      GENTI(45 (*LDC*),'I',5);
                                      GENTI(116(*ARG*),'I',SYSTEM)
                                   END; (*THEN*)
                                GEN(118 (*WRH*))
                             END (*THEN*)
                     ELSE IF LSP = INT2PTR THEN
                            BEGIN
                              IF DEFAULT THEN
                                 BEGIN
                                    GENTI(45 (*LDC*), 'I', 7);
                                    GENTI(116 (*ARG*), 'I', SYSTEM);
                                 END;
                              GEN(104 (*WRI*))
                            END
                     ELSE
                       IF LSP = REALPTR THEN
                         BEGIN
                           IF DEFAULT THEN
                              BEGIN
                                 GENTI(45 (*LDC*), 'I', 14);
                                 GENTI(116 (*ARG*), 'I', 0);
                              END;
                           GEN(107 (*WRR*))
                         END
                       ELSE
                         IF LSP = CHARPTR THEN
                           BEGIN
                             IF DEFAULT THEN
                                BEGIN
                                   GENTI(45 (*LDC*), 'I', 1);
                                   GENTI(116 (*ARG*), 'I', 0);
                                END;
                             GEN(102 (*WRC*))
                           END
                         ELSE
                          IF LSP = BOOLPTR THEN
                            BEGIN
                              IF DEFAULT THEN
                                 BEGIN
                                    GENTI(45 (*LDC*), 'I', 5);
                                    GENTI(116 (*ARG*), 'I', 0);
                                 END;
                              GEN(101 (*WRB*))
                            END
                          ELSE
                           IF LSP <> NIL THEN
                             BEGIN
                               IF LSP@.FORM = SCALAR THEN ERROR(398)
                               ELSE
                                 IF CHARARRAY(LSP) THEN
                                   BEGIN
                                     IF DEFAULT THEN
                                        BEGIN
                                           GENTI(45 (*LDC*), 'I', LSP@.SIZE);
                                           GENTI(116 (*ARG*), 'I', 0);
                                        END;
                                     GENTI(45(*LDC*),'I',LSP@.SIZE);  (*VAR SIZE
*)                                   GENTI(116 (*ARG*), 'I', 0);
                                     GEN  (115 (*WRV*))
                                   END
                               ELSE
                                 IF LSP@.FORM = STRINGS THEN
                                   BEGIN
                                     IF DEFAULT THEN
                                        BEGIN
                                           GENTI(45 (*LDC*), 'I', 0);
                                           GENTI(116 (*ARG*), 'I', 0);
                                        END;
                                     GEN(108 (*WRS*))
                                   END
                                 ELSE ERROR(116)
                             END;
                   END ELSE (*NONTEXT FILE*)
                   BEGIN WITH ACTUALFILE@ DO IF VKIND = ACTUAL
                                   THEN   GENTLI(48 (*LOD*),'A',VLEV,VADDR(.1.))
                                   ELSE BEGIN
                                          GENTLI(48 (*LOD*),'A',VLEV,VADDR(.1.))
;                                         GENTI (35 (*IND*),'A',0);
                                        END;
                           EXPRESSION(FSYS+(.COMMA,COLON,RPARENT.)) ;
                           LSP := GATTR.TYPTR;
                           IF LSP <> NIL THEN LOAD;
                           IF NOT COMPTYPES(FSP,LSP) THEN ERROR(127);
                           IF K = 'V'
                                THEN GENTI (94 (*STO*),K,FSP@.SIZE)
                                ELSE GENT (94 (*STO*),K);
                           GENI (112(*MST*),0);
                           WITH ACTUALFILE@ DO IF VKIND = ACTUAL
                                   THEN GENLI (44 (*LDA*),VLEV,VADDR(.1.))
                                   ELSE GENTLI(48 (*LOD*),'A',VLEV,VADDR(.1.));
                           GENTI(116 (*ARG*), 'A', 0);
               GENTI(116 (*ARG*), 'A', 0);
                           GEN(68(*PUT*));
                   END;
                   TEST := SY <> COMMA;
                   IF NOT TEST THEN INSYMBOL;
                  UNTIL TEST;

              IF TEXTF THEN
                IF LKEY = XWRITELN THEN GEN(100 (*WLN*)) ELSE GEN(111(*EIO*));

               IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
               END (*SY = LPARENT*)
             ELSE IF LKEY = XWRITELN THEN GEN(100 (*WLN*)) ELSE ERROR(9);
             END (* WRITE1 *) ;

      (*       PROCEDURE PACK1;
               VAR LSP,LSP1: STP;
             BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
               ERROR(398); VARIABLE(FSYS + (.COMMA,RPARENT.));
               LSP := NIL; LSP1 := NIL;
               IF GATTR.TYPTR <> NIL THEN
                 WITH GATTR.TYPTR@ DO
                   IF FORM = ARRAYS THEN
                     BEGIN LSP := INXTYPE; LSP1 := AELTYPE END
                   ELSE ERROR(116);
               IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
               EXPRESSION(FSYS + (.COMMA,RPARENT.));
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR@.FORM <> SCALAR THEN ERROR(116)
                 ELSE
                   IF NOT COMPTYPES(LSP,GATTR.TYPTR) THEN ERROR(116);
               IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
               VARIABLE(FSYS + (.RPARENT.));
               IF GATTR.TYPTR <> NIL THEN
                 WITH GATTR.TYPTR@ DO
                   IF FORM = ARRAYS THEN
                     BEGIN
                       IF NOT COMPTYPES(AELTYPE,LSP1)
                         OR NOT COMPTYPES(INXTYPE,LSP) THEN
                         ERROR(116)
                     END
                   ELSE ERROR(116);
               IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END;*) (* PACK *)

      (*       PROCEDURE UNPACK1;
               VAR LSP,LSP1: STP;
             BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
               ERROR(398); VARIABLE(FSYS + (.COMMA,RPARENT.));
               LSP := NIL; LSP1 := NIL;
               IF GATTR.TYPTR <> NIL THEN
                 WITH GATTR.TYPTR@ DO
                   IF FORM = ARRAYS THEN
                     BEGIN LSP := INXTYPE; LSP1 := AELTYPE END
                   ELSE ERROR(116);
               IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
               VARIABLE(FSYS + (.COMMA,RPARENT.));
               IF GATTR.TYPTR <> NIL THEN
                 WITH GATTR.TYPTR@ DO
                   IF FORM = ARRAYS THEN
                     BEGIN
                       IF NOT COMPTYPES(AELTYPE,LSP1)
                         OR NOT COMPTYPES(INXTYPE,LSP) THEN
                         ERROR(116)
                     END
                   ELSE ERROR(116);
               IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
               EXPRESSION(FSYS + (.RPARENT.));
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR@.FORM <> SCALAR THEN ERROR(116)
                 ELSE
                   IF NOT COMPTYPES(LSP,GATTR.TYPTR) THEN ERROR(116);
               IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END;*) (* UNPACK *)

             PROCEDURE NEWDISPOSE;
               VAR LSP,LSP1: STP; VARTS: INTEGER;
                   LSIZE: ADDRRANGE; LVAL: VALU;
                   FOUND: BOOLEAN;
             BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
               GENI(112 (*MST*),0 (*BUILTIN CALL*));
               VARIABLE(FSYS + (.COMMA,RPARENT.)); LOADADDRESS;
               LSP := NIL; VARTS := 0; LSIZE := 0;
               IF GATTR.TYPTR <> NIL THEN
                 WITH GATTR.TYPTR@ DO
                   IF FORM = POINTER THEN
                     BEGIN
                       IF ELTYPE <> NIL THEN
                         BEGIN LSIZE := ELTYPE@.SIZE;
                           IF ELTYPE@.FORM = RECORDS THEN LSP := ELTYPE@.RECVAR
                         END
                     END
                   ELSE ERROR(116);
               WHILE SY = COMMA DO
                 BEGIN FOUND := FALSE;
                   INSYMBOL;CONSTANT(FSYS + (.COMMA,RPARENT.),LSP1,LVAL);
                   VARTS := VARTS + 1;
                   (* CHECK TO INSERT HERE: IS CONSTANT IN TAGFIELDTYPE RANGE *)
                   IF LSP = NIL THEN ERROR(158)
                   ELSE
                     IF LSP@.FORM <> TAGFLD THEN ERROR(162)
                     ELSE
                       IF LSP@.TAGFIELDP <> NIL THEN
                         IF CHARARRAY(LSP1) OR (LSP1 = REALPTR) THEN ERROR(159)
                         ELSE
                           IF COMPTYPES(LSP@.TAGFIELDP@.IDTYPE,LSP1) THEN
                             BEGIN
                               LSP1  := LSP@.FSTVAR;
                               LSIZE := LSP@.SIZE; LSP := NIL;
                               WHILE NOT FOUND AND (LSP1 <> NIL) DO
                                 WITH LSP1@ DO
                                   IF VARVAL.IVAL = LVAL.IVAL THEN
                                     BEGIN LSIZE := SIZE; LSP := SUBVAR;
                                         FOUND := TRUE
                                     END
                                   ELSE LSP1 := NXTVAR;
                             END
                           ELSE ERROR(116);
                 END (* WHILE *) ;
                IF LKEY = XNEW THEN GENI(60(* NEW *),LSIZE)
                             ELSE GENI(19(* DIS *),LSIZE);
                IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END (* NEW *) ;

             PROCEDURE MARK1;
             BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
                GENI(112 (*MST*),0 (*BUILTIN CALL*));
                VARIABLE(FSYS+(.RPARENT.));
                IF GATTR.TYPTR <> NIL THEN
                  IF GATTR.TYPTR@.FORM = POINTER THEN
                    BEGIN
                       LOADADDRESS;
                       GENTI(116 (*ARG*), 'A', 0);
                       GEN(58 (*MRK*));
                    END
                  ELSE ERROR(125);
                IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END(* MARK1 *);

             PROCEDURE RELEASE1;
             BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
                   GENI(112 (*MST*),0 (*BUILTIN CALL*));
                   VARIABLE(FSYS+(.RPARENT.));
                   IF GATTR.TYPTR <> NIL THEN
                      IF GATTR.TYPTR@.FORM = POINTER THEN
                         BEGIN
                            LOAD;
                            GENTI(116 (*ARG*), 'A', 0);
                            GEN(79 (*RLS*));
                         END
                      ELSE ERROR(125);
                   IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
             END (* RELEASE1 *);


           PROCEDURE HALT1 ;
             (* *THIS PROCEDURE IS TO FACILITATE COMMUNICATION WITH THE OUTSIDE
               * WORLD AND PROVIDE BREAK POINTS IN THE PASCAL PROGRAM.
               * 'HALT(I, R)'  RETURNS THE INTEGER CONSTANT I TO THE OPERATING
               * SYSTEM. THIS PARAMETER IS INTENDED TO BE USED AS A
               * 'FUNCTION NUMBER' *)

              BEGIN IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
                GENI(112 (*MST*),0 (*BUILTIN CALL*));
                EXPRESSION(FSYS+(.RPARENT,COMMA.)) ;
                LOAD;
                IFNOTINTEGERTHENERROR (116);
                GENI(26 (*EXI*), 1) ;
                IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
                END;  (*  HALT1  *)

             PROCEDURE ABS1;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                  IF INTTYPE(GATTR.TYPTR) OR (GATTR.TYPTR = REALPTR)
                     THEN  GENT(0 (*AB*),GETTYPE(GATTR.TYPTR))
                     ELSE BEGIN ERROR(125); GATTR.TYPTR := INT4PTR END
             END (* ABS *) ;

             PROCEDURE SQR1;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF INTTYPE(GATTR.TYPTR) OR (GATTR.TYPTR = REALPTR) THEN
                    GENT(92 (*SQR*), GETTYPE(GATTR.TYPTR))
                 ELSE
                    BEGIN
                       ERROR(125);
                       GATTR.TYPTR := INT4PTR;
                    END;
             END (* SQR *);

   (*        PROCEDURE ROUND1;

             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR <> REALPTR THEN ERROR(125);
               GENT(110  RND  ,'R');
               GATTR.TYPTR := INT4PTR
             END;*)

      (*       PROCEDURE TRUNC1;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR <> REALPTR THEN ERROR(125);
               GENT(97  TRC  ,'R');
               GATTR.TYPTR := INT4PTR
             END;*) (* TRUNC *)

             PROCEDURE ODD1;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF (NOT INTTYPE(GATTR.TYPTR))
                    THEN  ERROR(125)
                    ELSE  GENT(63(* ODD *),GETTYPE(GATTR.TYPTR));
               GATTR.TYPTR := BOOLPTR
             END (* ODD *) ;

             PROCEDURE ORD1;
             VAR K:CHAR;
             BEGIN

               WITH GATTR DO
                  IF TYPTR = NIL
                     THEN  TYPTR  := INT2PTR
                     ELSE
                        IF TYPTR@.FORM <> SCALAR
                           THEN  BEGIN
                                    ERROR(125);
                                    TYPTR  := INT2PTR
                                 END (*THEN*)
                           ELSE

                        IF INTTYPE(TYPTR) OR (TYPTR = REALPTR)
                           THEN  BEGIN
                                    ERROR(125);
                                    TYPTR  := INT2PTR
                                 END (*THEN*)
                           ELSE

                        BEGIN
                           K  := GETTYPE(TYPTR);
                           IF (K = 'C') OR (K = 'B')
                              THEN  GEN2T(13 (*CVT*),K,'H');

                           CASE TYPTR@.SIZE OF
                              1:   TYPTR  := INT1PTR;
                              2:   TYPTR  := INT2PTR;
                              4:   TYPTR  := INT4PTR
                           END (*CASE*)

                        END (*ELSE*)

             END (* ORD1 *) ;

             PROCEDURE CHR1;
             VAR K: CHAR;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                  BEGIN
                     IF INTTYPE(GATTR.TYPTR)
                        THEN  K  := GETTYPE(GATTR.TYPTR)
                        ELSE  BEGIN
                                 ERROR(125);
                                 K  := 'I'
                              END; (*ELSE*)

                     IF DEBUG THEN
                        IF K = 'J'
                           THEN  GENT2J(6 (*CHK*),K,LONGZERO,LONGORDMAXCHAR)
                           ELSE  GENT2I(6 (*CHK*),K,0,ORDMAXCHAR);

                     GEN2T(13 (*CVT*),K,'C');
                     GATTR.TYPTR  := CHARPTR
                  END (*THEN*)
             END (* CHR *) ;

             PROCEDURE PREDSUCC;
             BEGIN (* ERROR(398); *) (* TRANSLATES INTO 'DEC' AND 'INC' *)
               IF GATTR.TYPTR <> NIL THEN
                 IF (GATTR.TYPTR = REALPTR) OR (GATTR.TYPTR@.FORM <> SCALAR) THE
N                  ERROR(125) ;
               IF LKEY = XPRED THEN  GENTI(16(*DEC*),GETTYPE(GATTR.TYPTR),1)
               ELSE  IF LKEY = XSUCC THEN
                               GENTI(34(*INC*),GETTYPE(GATTR.TYPTR),1)
             END (* PREDSUCC *) ;

             PROCEDURE EOF1;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR@.FORM <> FILES THEN ERROR(125);
                 GENTI(116 (*ARG*), 'A', 0);
                IF LKEY = XEOF THEN GEN(23(*EOF*))
                                  ELSE GEN(24(*EOL*));
               GATTR.TYPTR := BOOLPTR
             END (* EOF1 *) ;


      (*    PROCEDURE SINCOSEXPLOG;
             VAR MKEY: MNRANGE;
             BEGIN
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR <> REALPTR THEN ERROR(125);
                 CASE LKEY OF
                    XSIN:     MKEY  := 88  SIN ;
                    XCOS:     MKEY  :=  8  COS ;
                    XEXP:     MKEY  := 27  EXP ;
                    XSQRT:    MKEY  := 93  SQT ;
                    XLN:      MKEY  := 49  LOG ;
                    XARCTAN:  MKEY  :=  5  ATN
                 END  ;
                 GEN(MKEY) ;
             END;*) (* SINCOSEXPLOG *)

      PROCEDURE ERRORIFNOTSTRING;

         BEGIN
            IF GATTR.TYPTR <> NIL THEN
               IF GATTR.TYPTR@.FORM = STRINGS THEN
                  GENT2I(116 (*ARG*), 'S', SYSTEM, GATTR.TYPTR@.SIZE)
               ELSE
                  ERROR(125);
         END (* ERRORIFNOTSTRING *);

      PROCEDURE STRCONCAT;

         BEGIN
            ERRORIFNOTSTRING;

            IF SY <> COMMA THEN
               ERROR(20)
            ELSE
               WHILE SY = COMMA DO
                  BEGIN
                     INSYMBOL;
                     EXPRESSION(FSYS + (. RPARENT, COMMA .));
                     LOAD;
                     CHECKFORCHAR;
                     ERRORIFNOTSTRING;
                     GEN(83 (*SCON*));
                  END;
         END (* STRCONCAT *);

      PROCEDURE STRDELETEORCOPY(OPKIND: STDNAMES);

         VAR
            STRPTR: STP;

         BEGIN
            ERRORIFNOTSTRING;

            STRPTR := GATTR.TYPTR;

            IF SY = COMMA THEN
               INSYMBOL
            ELSE
               ERROR(20);

            EXPRESSION(FSYS + (. COMMA .));
            LOAD;

            IFNOTINTEGERTHENERROR (125);

            IF SY = COMMA THEN
               INSYMBOL
            ELSE
               ERROR(20);

            EXPRESSION(FSYS + (. RPARENT .));
            LOAD;

            IFNOTINTEGERTHENERROR (125);

            IF OPKIND = XDELETE THEN
               GEN(85 (*SDEL*))
            ELSE
               GEN(84 (*SCOP*));

            GATTR.TYPTR := STRPTR;
         END (* STRDELETEORCOPY *);

      PROCEDURE STRINSERT;

         VAR
            STRPTR: STP;

         BEGIN
            CHECKFORCHAR;
            ERRORIFNOTSTRING;

            IF SY = COMMA THEN
               INSYMBOL
            ELSE
               ERROR(20);

            EXPRESSION (FSYS + (.RPARENT, COMMA.));
            LOAD;

            ERRORIFNOTSTRING;
            STRPTR := GATTR.TYPTR;

            IF SY = COMMA THEN
               INSYMBOL
            ELSE
               ERROR(20);

            EXPRESSION (FSYS + (. RPARENT .));
            LOAD;

            IFNOTINTEGERTHENERROR (125);

            GEN(89 (*SINS*));
            GATTR.TYPTR := STRPTR;
         END (* STRINSERT *);

      PROCEDURE STRPOS;

         BEGIN
            ERRORIFNOTSTRING;

            IF SY = COMMA THEN
               INSYMBOL
            ELSE
               ERROR(20);

            EXPRESSION (FSYS + (. RPARENT .));
            LOAD;

            CHECKFORCHAR;
            ERRORIFNOTSTRING;

            GEN(91 (*SPOS*));
            GATTR.TYPTR := INT2PTR;
         END (* STRPOS *);

      PROCEDURE STRLENGTH;

         BEGIN
            ERRORIFNOTSTRING;

            GEN(90 (*SLEN*));

            GATTR.TYPTR := INT2PTR;
         END (* STRLENGTH *);

   (* -------------------------------------------------------------------------
      PROCEDURE CALLNONSTANDARD
     ------------------------------------------------------------------------- *
)
             PROCEDURE CALLNONSTANDARD;
               VAR NXT,LCP: CTP; LSP: STP; LKIND: IDKIND; LB: BOOLEAN;
                   LLC: ADDRRANGE; K: CHAR;
             BEGIN
               GENI(112 (*MST*),1 (*USER CALL*));
               WITH FCP@ DO
                 BEGIN NXT := NEXT; LKIND := PFKIND;
                   IF (KLASS = FUNC) AND (IDTYPE <> NIL) THEN
                                     GENTI(4 (*AST*),GETTYPE(IDTYPE),IDTYPE@.SIZ
E);                (*AST ALLOCATES SPACE ON RUNTIME STK FOR FUNCTION RESULT*)
                 END;
               IF SY = LPARENT THEN
                 BEGIN LLC := LOCN;
                   REPEAT LB := FALSE; (*DECIDE IF PROC/FUNC MUST BE PASSED*)
                     IF LKIND = ACTUAL THEN
                       BEGIN
                         IF NXT = NIL THEN ERROR(126)
                         ELSE LB := NXT@.KLASS IN (.PROC,FUNC.)
                       END ELSE ERROR(398);
                     (*FOR FORMAL PROC/FUNC LB IS FALSE AND EXPRESSION
                     WILL BE CALLED, WHICH WILL ALLWAYS INTERPRET A PROC/FUNC ID
                     AT ITS BEGINNING AS A CALL RATHER THAN A PARAMETER PASSING.
                     IN THIS IMPLEMENTATION, PARAMETER PROC/FUNCS ARE THEREFORE
                     NOT ALLOWED TO HAVE PROC/FUNC PARAMETERS *)
                     INSYMBOL;
                     IF LB THEN   (* PASS FUNCTION OR PROCEDURE *)
                       BEGIN ERROR(398);
                         IF SY <> IDENT THEN
                           BEGIN ERROR(2); SKIP(FSYS + (.COMMA,RPARENT.)) END
                         ELSE
                           BEGIN
                             IF NXT@.KLASS = PROC THEN SEARCHID((.PROC.),LCP)
                             ELSE
                               BEGIN SEARCHID((.FUNC.),LCP);
                                 IF NOT COMPTYPES(LCP@.IDTYPE,NXT@.IDTYPE) THEN
                                   ERROR(128)
                               END;
                             INSYMBOL;
                             IF NOT (SY IN FSYS + (.COMMA,RPARENT.)) THEN
                               BEGIN ERROR(6); SKIP(FSYS + (.COMMA,RPARENT.)) EN
D                          END
                       END (* IF LB *)
                     ELSE
                       BEGIN EXPRESSION(FSYS + (.COMMA,RPARENT.));
                         IF GATTR.TYPTR <> NIL THEN
                           IF LKIND = ACTUAL THEN
                             BEGIN
                               IF NXT <> NIL THEN
                                 BEGIN LSP := NXT@.IDTYPE;
                                   IF LSP <> NIL THEN
                                     BEGIN
                                       IF (NXT@.VKIND = ACTUAL) THEN
                                          IF LSP@.FORM <= POWER THEN
                                            BEGIN
                                               LOAD;
                                               IF COMPTYPES (LSP, GATTR.TYPTR) T
HEN                                               CHKBNDS (LSP, GATTR.TYPTR, 142
);
                                               IF INTTYPE (GATTR.TYPTR) THEN
                                                  CNVRTTOLHS (LSP, GATTR.TYPTR);
                                            END
                                         ELSE
                                           BEGIN
                                           LOAD; (*****LOADADDRESS;*****)
                                           IF LSP@.FORM = STRINGS THEN
                                       GEN2TI(13(*CVT*),'S','U',LSP@.SIZE(*STRSZ
*))                                           (*CONVERTS NORMALIZED STRING TO
                                               FULL SIZE STRING FOR PARAM PASS*)
                                           ELSE IF CHARARRAY(LSP) AND
                                              (GATTR.TYPTR@.FORM=STRINGS) THEN
                                              BEGIN
                                               GEN2TI(13(*CVT*),'S','V',LSP@.SIZ
E);                                            GATTR.TYPTR := LSP
                                              END
                                           END
                                       ELSE
                                         IF (GATTR.KIND = VARBL) OR
                                            (GATTR.KIND = FILEPTR) THEN
                                           BEGIN LOADADDRESS;
                                           IF GATTR.TYPTR@.SIZE <> LSP@.SIZE THE
N                                            ERROR(142) ;
                                           END
                                         ELSE ERROR(154);
                                       IF NOT COMPTYPES(LSP,GATTR.TYPTR) THEN
                                         ERROR(142);
                                       WITH GATTR DO
                                          IF (KIND = VARBL) OR (KIND = FILEPTR)
                                          THEN
                                             K := 'A'
                                          ELSE
                                             K := GETTYPE(LSP);
                                       IF (K = 'S') OR (K = 'V') THEN
                                          GENT2I(116 (*ARG*), K, 1, LSP@.SIZE)
                                       ELSE
                                          GENTI(116 (*ARG*), K, 1);
                                     END
                                 END
                             END
                         ELSE (* LKIND = FORMAL *)
                           BEGIN (* PASS FORMAL PARAM *)
                           END
                       END;
                     IF (LKIND = ACTUAL) AND (NXT <> NIL) THEN NXT := NXT@.NEXT
                   UNTIL SY <> COMMA;
                   LOCN := LLC;
                 IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
               END (* IF LPARENT *);
               IF LKIND = ACTUAL THEN
                 BEGIN IF NXT <> NIL THEN ERROR(126);
                       GENTL(11(*CUP*),'$',FCP@.PFNAME);
                       KOUNT  := KOUNT - 1;
                       LABELEDKOUNT  := TRUE;
                       GENKOUNT (FALSE);
                 END;
               IF (FCP@.KLASS = FUNC) AND (FCP@.IDTYPE <> NIL) THEN
                   WITH FCP@.IDTYPE@ DO
                  IF  (FORM = STRINGS) THEN GEN2TI(13 (*CVT*),'U','S',SIZE);
                                             (*NORMALIZE STRING FUNCTION RESULT*
)              GATTR.TYPTR := FCP@.IDTYPE ;
             END (* CALLNONSTANDARD *) ;

           BEGIN (* **START** CALL *)
             IF FCP@.PFDECKIND = BUILTIN THEN
               BEGIN
                 LKEY := FCP@.KEY;
                 IF FCP@.KLASS = PROC THEN
                   CASE LKEY OF
                      XNEW,
                      XDISPOSE:        NEWDISPOSE;

                      XGET,
                      XPUT,
                      XPAGE:           GETPUTPAGE;

                      XRESET,
                      XREWRITE:        RESETREWRITE;

                      XREAD,
                      XREADLN:         READ1;

                      XWRITE,
                      XWRITELN:        WRITE1;

                      XPACK:           (*PACK1; *)
                                       BEGIN
                                          ERROR (398);
                                          SKIP (FSYS + (.RPARENT.))
                                       END;

                      XUNPACK:         (*UNPACK1; *)
                                       BEGIN
                                          ERROR (398);
                                          SKIP (FSYS + (.RPARENT.))
                                       END;

                      XRELEASE:        RELEASE1;

                      XMARK:           MARK1;

                      XHALT:           HALT1
                   END
                 ELSE
                   BEGIN IF LKEY IN (.XROUND,XTRUNC,XEOF,XEOLN,XSIN,XCOS,
                                      XEXP,XSQRT,XLN,XARCTAN,XCONCAT,XCOPY,
                                      XDELETE,XINSERT,XPOS,XLENGTH,XPOSITION.)
                            THEN  GENI (112 (* MST *), 0);
                       IF SY = LPARENT THEN INSYMBOL ELSE ERROR(9);
                       IF LKEY IN (.XCONCAT, XCOPY, XDELETE, XINSERT, XPOS .)
                          THEN
                             EXPRESSION (FSYS + (. COMMA .))
                          ELSE
                             EXPRESSION (FSYS + (.RPARENT .));
                       IF (LKEY = XEOF) OR (LKEY = XEOLN) THEN
                                                        LOADADDRESS ELSE LOAD;
                     CASE LKEY OF
                        XROUND:      (*ROUND1; *)
                                     BEGIN
                                        ERROR (398);
                                        SKIP (FSYS + (.RPARENT.))
                                     END;

                        XABS:        ABS1;

                        XSQR:        SQR1;

                        XTRUNC:      (*TRUNC1; *)
                                     BEGIN
                                        ERROR (398);
                                        SKIP (FSYS + (.RPARENT.))
                                     END;

                        XODD:        ODD1;

                        XORD:        ORD1;

                        XCHR:        CHR1;

                        XPRED,
                        XSUCC:       PREDSUCC;

                        XCLOCK:      (*CLOCK; *)
                                     BEGIN
                                        ERROR (398);
                                        SKIP (FSYS + (.RPARENT.))
                                     END;

                        XEOF,
                        XEOLN:       EOF1;

                        XSIN,
                        XCOS,
                        XEXP,
                        XSQRT,
                        XLN,
                        XARCTAN:     (*SINCOSEXPLOG; *)
                                     BEGIN
                                        ERROR (398);
                                        SKIP (FSYS + (.RPARENT.))
                                     END;

                        XCONCAT:     STRCONCAT;
                        XCOPY,
                        XDELETE:     STRDELETEORCOPY(LKEY);
                        XINSERT:     STRINSERT;
                        XPOS:        STRPOS;
                        XLENGTH:     STRLENGTH;
                        XPOSITION:   (*STRING FUNCTIONS*)
                                     BEGIN
                                        ERROR (398);
                                        SKIP (FSYS + (.RPARENT.))
                                     END

                     END (* CASE LKEY OF *) ;
                     IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
                   END;
               END (* STANDARD PROCEDURES AND FUNCTIONS *)
             ELSE CALLNONSTANDARD
           END (* CALL *) ;

               PROCEDURE CONVERTTOLIKEINTEGERS (VAR LEFTSIDE, RIGHTSIDE: STP);

                  VAR
                     LEFTKIND,
                     RIGHTKIND,
                     RESULTKIND: CHAR;
                     RESULTTYPE: STP;


                  FUNCTION MAX (ARG1, ARG2: CHAR): CHAR;

                     BEGIN (*MAX*)
                        IF ARG1 > ARG2 THEN
                           MAX := ARG1
                        ELSE
                           MAX := ARG2;
                     END   (*MAX*);
                  BEGIN (* CONVERTTOLIKEINTEGERS *)

                     LEFTKIND  := GETTYPE (LEFTSIDE);
                     RIGHTKIND := GETTYPE (RIGHTSIDE);

                     RESULTKIND := MAX (ARITHMETICSIZE, MAX (LEFTKIND, RIGHTKIND
));
                     IF RESULTKIND = 'H' THEN
                        RESULTTYPE := INT1PTR
                     ELSE IF RESULTKIND = 'I' THEN
                        RESULTTYPE := INT2PTR
                     ELSE
                        RESULTTYPE := INT4PTR;

                     IF LEFTKIND < RESULTKIND THEN
                        BEGIN
                           GEN2T (14 (*CVB*), LEFTKIND, RESULTKIND);
                           LEFTSIDE := RESULTTYPE;
                        END;

                     IF RIGHTKIND < RESULTKIND THEN
                        BEGIN
                           GEN2T (13 (*CVT*), RIGHTKIND, RESULTKIND);
                           RIGHTSIDE := RESULTTYPE;
                        END;

                  END   (* CONVERTTOLIKEINTEGERS *);

               PROCEDURE ILLEGALOPERANDS;

                  BEGIN (* ILLEGALOPERANDS *)

                     ERROR (134);
                     GATTR.TYPTR := NIL;

                  END   (* ILLEGALOPERANDS *);

               FUNCTION COMPATABLESETS (TYP1, TYP2: STP): BOOLEAN;

                  BEGIN (* COMPATABLESETS *)

                     COMPATABLESETS := FALSE;
                     IF TYP1 <> NIL THEN
                        COMPATABLESETS := (TYP1@.FORM = POWER)
                                          AND COMPTYPES (TYP1, TYP2);

                  END   (* COMPATABLESETS *);


   (*$E------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  CONSTFACTOR (TYP,VAL)                            *)
   (*                                                                    *)
   (*        THIS PROCEDURE HANDLES A FACTOR WHICH IS A CONSTANT.        *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  CONSTFACTOR (TYP: STP;  VAL: VALU);

      BEGIN (*CONSTFACTOR*)

         WITH GATTR DO
            BEGIN
                KIND  := CST;

                IF INTTYPE(TYP) AND (ARITHMETICSIZE > GETTYPE(TYP))
                   THEN
                      IF ARITHMETICSIZE = 'J'
                         THEN
                            BEGIN              (*CONVERT UP TO A LONG INTEGER*)
                               NEW (CVAL.VALP,LINT);
                               MAKELONG (VAL.IVAL,CVAL.VALP@.LINTVAL);
                               TYPTR  := INT4PTR
                            END (*THEN*)
                         ELSE
                            BEGIN
                               TYPTR      := INT2PTR;
                               CVAL.IVAL  := VAL.IVAL
                            END (*ELSE*)
                   ELSE
                      BEGIN
                        TYPTR  := TYP;
                        CVAL   := VAL
                      END (*ELSE*)

            END (*WITH*)

      END; (*CONSTFACTOR*)


               PROCEDURE TERM(FSYS: SETOFSYS);
                 VAR
                    LATTR:    ATTR;
                    LOP:      OPERATOR;
                    INTEGERS: BOOLEAN;

                 PROCEDURE FACTOR(FSYS: SETOFSYS);
                   VAR LCP: CTP;  VARPART: BOOLEAN;
                       C : CHAR;
                       CSTPART: SETCONST; LSP: STP; I: 0..64;
                       RNGTYPE: STP;
                       CSTVAL,CSTVAL2: INTEGER;
                       RANGED,CONSTEL: BOOLEAN;


                 BEGIN (* **START** FACTOR *)
                   IF NOT (SY IN FACBEGSYS) THEN
                     BEGIN ERROR(58); SKIP(FSYS + FACBEGSYS);
                       GATTR.TYPTR := NIL
                     END;
                   WHILE SY IN FACBEGSYS DO
                     BEGIN
                       CASE SY OF
          (* ID *)    IDENT:
                           BEGIN SEARCHID((.KONST,VARS,FIELD,FUNC.),LCP);
                             INSYMBOL;
                             IF LCP@.KLASS = FUNC THEN
                                BEGIN CALL(FSYS,LCP);
                                  WITH GATTR DO
                                    BEGIN KIND := EXPR;
                                      IF TYPTR <> NIL THEN
                                        IF TYPTR@.FORM=SUBRANGE THEN
                                          TYPTR := TYPTR@.RANGETYPE
                                    END
                                END
                             ELSE
                               IF LCP@.KLASS = KONST THEN
                                 WITH LCP@ DO
                                    CONSTFACTOR (IDTYPE,VALUES)
                               ELSE
                                 BEGIN SELECTOR(FSYS,LCP);
                                   IF GATTR.TYPTR<>NIL THEN
                           (* ELIM.SUBR.TYPES TO SIMPLIFY LATER TESTS *)
                                     WITH GATTR,TYPTR@ DO
                                       IF FORM = SUBRANGE THEN
                                         TYPTR := RANGETYPE
                                 END
                           END;
          (* CST *)   INT1CONST:
                           BEGIN
                              CONSTFACTOR (INT1PTR,VAL);
                              INSYMBOL
                           END; (*INT1CONST*)

                      INT2CONST:
                           BEGIN
                              CONSTFACTOR (INT2PTR,VAL);
                              INSYMBOL
                           END; (*INT2CONST*)

                      INT4CONST:
                           BEGIN
                              CONSTFACTOR (INT4PTR,VAL);
                              INSYMBOL
                           END; (*INT4CONST*)

                   REALCONST:
                           BEGIN
                             WITH GATTR DO
                               BEGIN TYPTR := REALPTR; KIND := CST;
                               (*  CVAL := VAL ; *)  CVAL.VALP := VAL.VALP ;
                               END;
                             INSYMBOL
                           END;
         (* STRG *) STRINGCONST:
                           BEGIN
                             WITH GATTR DO
                               BEGIN
                                 IF LNGTH = 1 THEN TYPTR := CHARPTR
                                 ELSE
                                   BEGIN NEW(LSP,STRINGS);
                                     WITH LSP@ DO
                                       BEGIN FORM:=STRINGS;
                                             SIZE := LNGTH+ALIGNMENT
                                       END;
                                     TYPTR := LSP
                                   END;
                                 KIND := CST ;  CVAL := VAL ;
                               END;
                             INSYMBOL
                           END;
          (* (  *)   LPARENT:
                           BEGIN INSYMBOL; EXPRESSION(FSYS + (.RPARENT.));
                             IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
                           END;
            (* NOT *)  NOTSY:
                           BEGIN INSYMBOL; FACTOR(FSYS);
                             LOAD; GEN(62(* NOT *));
                             IF GATTR.TYPTR <> NIL THEN
                               IF GATTR.TYPTR <> BOOLPTR THEN
                                 BEGIN ERROR(135); GATTR.TYPTR := NIL END;
                           END;
           (* (. *)    LBRACK:
                           BEGIN INSYMBOL; CSTPART := (. .); VARPART := FALSE;
                             CONSTEL := FALSE;
                             RANGED := FALSE;
                             NEW(LSP,POWER);
                             WITH LSP@ DO
                               BEGIN ELSET:=NIL;SIZE:=SETSIZE;FORM:=POWER END;
                             IF SY = RBRACK THEN
                               BEGIN
                                 WITH GATTR DO
                                   BEGIN TYPTR := LSP; KIND := CST END;
                                 INSYMBOL
                               END
                             ELSE
                               BEGIN
                                 REPEAT
   (*CF      <---------------------               *)
             EXPRESSION(FSYS + (. COMMA, RANGE, RBRACK .));
             WITH GATTR DO
               BEGIN
                 IF TYPTR <> NIL THEN
                   IF TYPTR@.FORM <> SCALAR THEN
                     BEGIN ERROR(136); TYPTR := NIL END
                   ELSE
                     IF COMPTYPES(LSP@.ELSET,TYPTR) THEN
                       BEGIN
                         IF KIND = CST THEN
                           BEGIN
                             IF COMPTYPES(TYPTR,CHARPTR) THEN
                               CSTVAL := ASCII(. CHR(CVAL.IVAL) .) - 32
                             ELSE
                               CSTVAL := CVAL.IVAL;
                             IF ((CSTVAL < 0) OR (CSTVAL > SETRANGE)) THEN
                               ERROR(304)
                             ELSE
                               IF RANGED THEN
                                 IF TYPTR <> RNGTYPE THEN
                                   ERROR(137)
                                 ELSE
                                   IF NOT CONSTEL THEN
                                     CSTPART := CSTPART + (. CSTVAL .)
                                   ELSE
                                     IF CSTVAL < CSTVAL2 THEN
                                       CSTPART := CSTPART - (. CSTVAL2 .)
                                     ELSE
                                       FOR I := CSTVAL2 + 1 TO CSTVAL DO
                                         CSTPART := CSTPART + (. I .)
                               ELSE
                                 CSTPART := CSTPART + (. CSTVAL .);
                             CONSTEL := TRUE;
                             IF SY = RANGE THEN (* RANGE GIVEN *)
                               BEGIN
                                 RNGTYPE := TYPTR;
                                 CSTVAL2 := CSTVAL
                               END
                           END
                         ELSE
                           BEGIN
                             LOAD;
                             IF RANGED AND CONSTEL THEN ERROR(398);
                             IF NOT COMPTYPES(TYPTR,INT2PTR) THEN
                               BEGIN
                                 C := GETTYPE(TYPTR);
                                 IF C <> 'I' THEN
                                   BEGIN
                                     GEN2T(13 (*CVT*),C,'I');
                                     IF C = 'C' THEN GENTI(16(*DEC*), 'I', 32)
                                   END
                               END (*THEN*)
                             ELSE  CNVRTTOLHS (INT2PTR,TYPTR);
                             IF DEBUG THEN GENT2I(6 (*CHK*),'I',0,SETRANGE);
                             GEN(87(*SGS*));
                             IF VARPART THEN GEN(99(*UNI*))
                             ELSE VARPART := TRUE;
                             CONSTEL := FALSE
                           END;
                         LSP@.ELSET := TYPTR;
                         TYPTR := LSP
                       END
                     ELSE
                       ERROR(137);
                 RANGED := ((SY = RANGE) AND (NOT RANGED));
                 IF (RANGED AND (NOT CONSTEL)) THEN ERROR(398);
                 TEST := ((SY <> COMMA) AND (NOT RANGED));
                 IF NOT TEST THEN INSYMBOL
               END (* WITH GATTR DO *)
   (*CF        --------------------->              *)
                                 UNTIL TEST;
                                 IF SY = RBRACK THEN INSYMBOL ELSE ERROR(12)
                               END;

                              CNSTVALPTR@.PVAL := CSTPART ;
                             IF VARPART THEN
                               BEGIN
                                 IF CSTPART <> (. .) THEN
                                   BEGIN
                                    (* NEW(LVP,PSET); LVP@.PVAL := CSTPART;*)
                                      CSTPTR := (* LVP *)  CNSTVALPTR ;
                                     GENTV(45(* LDC *),'P',CSTPTR);
                                     GEN(99(* UNI *)); GATTR.KIND := EXPR
                                   END
                               END
                             ELSE
                               BEGIN (* NEW(LVP,PSET); LVP@.PVAL := CSTPART;  *)
                                (* LVP@.CCLASS := PSET; *)
                                 GATTR.CVAL.VALP := (* LVP *) CNSTVALPTR ;
                               END
                           END
                 END (* CASE *) ;
                       IF NOT (SY IN FSYS) THEN
                         BEGIN ERROR(6); SKIP(FSYS + FACBEGSYS) END
                     END (* WHILE *)
                 END (* FACTOR *) ;

               BEGIN (* **START** TERM *)
                 FACTOR(FSYS + (.MULOP.));
                 WHILE SY = MULOP DO
                         BEGIN LOAD; LATTR := GATTR; LOP := OP;
                     INSYMBOL; FACTOR(FSYS + (.MULOP.)); LOAD;
                     IF (LATTR.TYPTR <> NIL) AND (GATTR.TYPTR <> NIL) THEN
                        BEGIN
                           INTEGERS := INTTYPE (LATTR.TYPTR)
                                       AND INTTYPE (GATTR.TYPTR);

                           IF INTEGERS THEN
                              CONVERTTOLIKEINTEGERS (LATTR.TYPTR, GATTR.TYPTR);

                           CASE LOP OF

                              MUL:
                                 BEGIN
                                    IF INTEGERS THEN
                                       GENT (57 (*MP*), GETTYPE (GATTR.TYPTR))
                                    ELSE IF COMPATABLESETS (LATTR.TYPTR,
                                                            GATTR.TYPTR)
                                    THEN
                                       GEN (38 (*INT*))
                                    ELSE
                                       ILLEGALOPERANDS;
                                 END (* MUL *);

                              RDIV:
                                 BEGIN
                                    ERROR (398);
                                    GATTR.TYPTR := NIL;
                                 END (*RDIV*);

                              IDIV:
                                 BEGIN
                                    IF INTEGERS THEN
                                       GENT (20 (*DV*), GETTYPE (GATTR.TYPTR))
                                    ELSE
                                       ILLEGALOPERANDS;
                                 END (*IDIV*);

                              IMOD:
                                 BEGIN
                                    IF INTEGERS THEN
                                       GENT (54 (*MOD*), GETTYPE (GATTR.TYPTR))
                                    ELSE
                                       ILLEGALOPERANDS;
                                 END (*IMOD*);

                              ANDOP:
                                 BEGIN
                                    IF (LATTR.TYPTR = BOOLPTR)
                                       AND (GATTR.TYPTR = BOOLPTR)
                                    THEN
                                       GEN (3 (*AND*))
                                    ELSE
                                       ILLEGALOPERANDS;
                                 END (*ANDOP*);

                           END (* CASE LOP OF *);
                        END (* IF (LATTR.TYPTR <> NIL) ... *)
                     ELSE
                        GATTR.TYPTR := NIL
                   END (* WHILE *)
               END (* TERM *) ;




   (* -------------------------------------------------------------------------
      PROCEDURE EXPRESSION
     ------------------------------------------------------------------------- *
)
           PROCEDURE EXPRESSION;
             VAR LATTR: ATTR; KOP: MNRANGE;
                 C : CHAR;
                 LOP: OPERATOR; TYPIND: CHAR; LSIZE: ADDRRANGE;

             PROCEDURE SIMPLEEXPRESSION(FSYS: SETOFSYS);

                VAR
                   LATTR:      ATTR;
                   LOP:        OPERATOR;
                   SIGNED:     BOOLEAN;
                   INTEGERS:   BOOLEAN;

             BEGIN (* SIMPLEEXPRESSION *)

                SIGNED := FALSE;
                IF (SY = ADDOP) AND ((OP = PLUS) OR (OP = MINUS)) THEN
                   BEGIN
                      SIGNED := OP = MINUS;
                      INSYMBOL;
                   END;

                TERM (FSYS + (. ADDOP .));

                IF SIGNED THEN
                   BEGIN
                      LOAD;
                      IF INTTYPE (GATTR.TYPTR) THEN
                         GENT (61 (*NG*), GETTYPE (GATTR.TYPTR))
                      ELSE
                         ILLEGALOPERANDS;
                   END;

                WHILE SY = ADDOP DO
                   BEGIN
                      LOAD;
                      LATTR := GATTR;
                      LOP := OP;
                      INSYMBOL;
                      TERM (FSYS + (. ADDOP .));
                      LOAD;

                      IF (LATTR.TYPTR <> NIL) AND (GATTR.TYPTR <> NIL) THEN
                         BEGIN
                            INTEGERS := INTTYPE (LATTR.TYPTR)
                                        AND INTTYPE (GATTR.TYPTR);

                            IF INTEGERS THEN
                               CONVERTTOLIKEINTEGERS (LATTR.TYPTR, GATTR.TYPTR);

                            CASE LOP OF

                               PLUS:
                                  BEGIN
                                     IF INTEGERS THEN
                                        GENT (1 (*AD*), GETTYPE (GATTR.TYPTR))
                                     ELSE IF COMPATABLESETS (LATTR.TYPTR,
                                                             GATTR.TYPTR)
                                     THEN
                                        GEN (99 (*UNI*))
                                     ELSE
                                        ILLEGALOPERANDS;
                                  END (* PLUS *);

                               MINUS:
                                  BEGIN
                                     IF INTEGERS THEN
                                        GENT (82 (*SB*), GETTYPE (GATTR.TYPTR))
                                     ELSE IF COMPATABLESETS (LATTR.TYPTR,
                                                             GATTR.TYPTR)
                                     THEN
                                        GEN (18 (*DIF*))
                                     ELSE
                                        ILLEGALOPERANDS;
                                  END (* MINUS *);

                               OROP:
                                  BEGIN
                                     IF (LATTR.TYPTR = BOOLPTR)
                                        AND (GATTR.TYPTR = BOOLPTR)
                                     THEN
                                        GEN (39 (*IOR*))
                                     ELSE
                                        ILLEGALOPERANDS;
                                  END (*OROP*);

                            END (*CASE LOP OF*);
                         END (* IF (LATTR.TYPTR <> NIL) ... *)
                      ELSE
                         GATTR.TYPTR := NIL;
                   END (* WHILE SY = ADDOP *);
             END (* SIMPLEEXPRESSION *) ;

           BEGIN (* **START** EXPRESSION *)
             SIMPLEEXPRESSION(FSYS + (.RELOP.));
             IF SY = RELOP THEN
               BEGIN
                 IF GATTR.TYPTR <> NIL THEN
                   LOAD;             (*******)
                   (******IF GATTR.TYPTR@.FORM <= POWER THEN LOAD
                   ELSE LOADADDRESS; ******)
                 LATTR := GATTR; LOP := OP;
                  IF LOP = INOP THEN
                    BEGIN
                    IF NOT COMPTYPES(GATTR.TYPTR,INT2PTR) THEN
                              BEGIN C := GETTYPE(LATTR.TYPTR);
                                    IF C <> 'I' THEN GEN2T(13 (*CVT*), C, 'I');
                                    IF C = 'C' THEN GENTI(16(*DEC*), 'I', 32)
                              END (*THEN*)
                    ELSE      CNVRTTOLHS (INT2PTR,GATTR.TYPTR);
                    IF DEBUG THEN GENT2I(6(* CHK *),'I',0,SETRANGE) ;
                    END ;
                 INSYMBOL; SIMPLEEXPRESSION(FSYS);
                 IF GATTR.TYPTR <> NIL THEN
                   LOAD;             (*******)
                   (****** IF GATTR.TYPTR@.FORM <= POWER THEN LOAD
                   ELSE LOADADDRESS;  ******)
                 IF (LATTR.TYPTR <> NIL) AND (GATTR.TYPTR <> NIL) THEN
       (* IN *)      IF LOP = INOP THEN
                     IF GATTR.TYPTR@.FORM = POWER THEN
                       BEGIN
                       IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR@.ELSET) THEN
                         GEN(36(* INN *))
                       ELSE BEGIN ERROR(129); GATTR.TYPTR := NIL END
                       END
                     ELSE BEGIN ERROR(130); GATTR.TYPTR := NIL END
                   ELSE
                     BEGIN
                       IF LATTR.TYPTR <> GATTR.TYPTR THEN
                          IF INTTYPE (LATTR.TYPTR) AND INTTYPE (GATTR.TYPTR) THE
N                            CONVERTTOLIKEINTEGERS (LATTR.TYPTR, GATTR.TYPTR)
                          ELSE IF CHARARRAY(LATTR.TYPTR) AND
                               (GATTR.TYPTR@.FORM = STRINGS) THEN
                               BEGIN GEN2TI(13(* CVT *),'S','V',LATTR.TYPTR@.SIZ
E);                                  GATTR.TYPTR := LATTR.TYPTR
                               END
                          ELSE IF CHARARRAY(GATTR.TYPTR) AND
                               (LATTR.TYPTR@.FORM = STRINGS) THEN
                               BEGIN GEN2TI(14(* CVB *),'S','V',GATTR.TYPTR@.SIZ
E);                                  LATTR.TYPTR := GATTR.TYPTR
                               END;
                       IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR) THEN
                         BEGIN LSIZE := LATTR.TYPTR@.SIZE;
                           CASE LATTR.TYPTR@.FORM OF
                             SCALAR:
                               TYPIND := GETTYPE (LATTR.TYPTR);
                             POINTER:
                               BEGIN
                                 IF LOP IN (.LTOP,LEOP,GTOP,GEOP.)
                                     THEN ERROR(131);
                                 TYPIND := 'A'
                               END;
                             POWER:
                               BEGIN IF LOP IN (.LTOP,GTOP.) THEN ERROR(132);
                                 TYPIND := 'P'
                             END;
                             STRINGS:
                                 TYPIND := 'S';
                             ARRAYS:
                               BEGIN
                                 IF NOT CHARARRAY(LATTR.TYPTR)
                                    AND(LOP IN(.LTOP,LEOP,GTOP,GEOP.))
                                      THEN ERROR(131);
                                 TYPIND := 'V'
                               END;
                             RECORDS:
                               BEGIN
                                 IF LOP IN (.LTOP,LEOP,GTOP,GEOP.)
                                      THEN ERROR(131);
                                 TYPIND := 'V'
                               END;
                             FILES:
                               BEGIN ERROR(133); TYPIND := 'F' END;
                             SUBRANGE:  ;
                             TAGFLD:  ;
                             VARIANT:
                           END;
                           CASE LOP OF
       (* <  *)                LTOP: KOP := 47(* LES *);
       (* <= *)                LEOP: KOP := 46(* LEQ *);
       (* >  *)                GTOP: KOP := 32(* GRT *);
       (* >= *)                GEOP: KOP := 30(* GEQ *);
       (* <> *)                NEOP: KOP := 59(* NEQ *);
       (* =  *)                EQOP: KOP := 25(* EQU *)
                           END;
                           IF (TYPIND = 'V') OR (TYPIND = 'S')
                                  THEN GENTI(KOP, TYPIND,LSIZE)
                                  ELSE GENT (KOP, TYPIND)
                         END
                       ELSE ERROR(129)
                     END;
                 GATTR.TYPTR := BOOLPTR; GATTR.KIND := EXPR
               END (* SY = RELOP *)
           END (* EXPRESSION *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE ASSIGNMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE ASSIGNMENT(FCP: CTP);
             VAR LATTR: ATTR;
           BEGIN
             SELECTOR(FSYS+(.BECOMES.), FCP) ;
             IF SY = BECOMES THEN
               BEGIN
                 WITH GATTR DO
                   IF TYPTR <> NIL THEN
                   IF (ACCESS<>DRCT) OR (TYPTR@.FORM>STRINGS)
                                     OR (KIND=FILEPTR) THEN
                        BEGIN
                        LOADADDRESS ;
                        END ;
                 LATTR := GATTR;
                 INSYMBOL; EXPRESSION(FSYS);
                 IF GATTR.TYPTR <> NIL THEN
                   IF     (GATTR.TYPTR@.FORM <= STRINGS)
                       OR (GATTR.KIND <> VARBL)             (*******)
                                                 THEN LOAD
                                                 ELSE LOADADDRESS;
                 IF (LATTR.TYPTR <> NIL) AND (GATTR.TYPTR <> NIL) THEN
                   BEGIN
                 (*  IF COMPTYPES(REALPTR,LATTR.TYPTR)AND(GATTR.TYPTR=INT2PTR)TH
EN                     BEGIN GEN2T(13(  CVT  ),'I','R');
                         GATTR.TYPTR := REALPTR
                       END
                 ELSE  *) IF (GATTR.TYPTR@.FORM=STRINGS) AND CHARARRAY(LATTR.TYP
TR)                    THEN BEGIN GEN2TI(13(* CVT *),'S','V',LATTR.TYPTR@.SIZE);
                                  GATTR.TYPTR := LATTR.TYPTR
                            END
                     ELSE IF (LATTR.TYPTR@.FORM = STRINGS)
                             AND (GATTR.TYPTR = CHARPTR)
                          THEN
                             BEGIN
                                GEN2T(13 (*CVT*), 'C', 'S');
                                GATTR.TYPTR := LATTR.TYPTR
                             END;
                     IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR) THEN
                       BEGIN

                          CHKBNDS (LATTR.TYPTR, GATTR.TYPTR, 129);

                          IF INTTYPE (GATTR.TYPTR) THEN
                             CNVRTTOLHS (LATTR.TYPTR, GATTR.TYPTR);

                         CASE LATTR.TYPTR@.FORM OF
                           SCALAR,
                           SUBRANGE,
                           POINTER,
                           POWER,
                           STRINGS: STORE(LATTR);
                           ARRAYS,
                           RECORDS: BEGIN IF GATTR.KIND = VARBL   (*******)
                                      THEN GENI (55(*MOV*),LATTR.TYPTR@.SIZE)
                                      ELSE GENTI(94(*STO*),'V',LATTR.TYPTR@.SIZE
);                                  END ;
                           FILES: ERROR(146);
                           TAGFLD: ;
                           VARIANT:
                         END  (* CASE LATTR... *)
                        END
                     ELSE ERROR(129)
                   END
               END (* SY = BECOMES *)
             ELSE ERROR(51)
           END (* ASSIGNMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE GOTOSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE GOTOSTATEMENT;
             VAR LLP: LBP; FOUND: BOOLEAN; TTOP,TTOP1: DISPRANGE;
           BEGIN
             IF (SY = INT2CONST) OR (SY = IDENT) THEN
               BEGIN                       (* ALPHA LABELS ALLOWED *)
                 FOUND := FALSE;  TTOP := TOP;
                  WHILE DISPLAY(.TTOP.).OCCUR <> BLCK DO TTOP := TTOP - 1;
                  TTOP1 := TTOP;
                  REPEAT
                   LLP := DISPLAY(.TTOP.).FLABEL;
                   WHILE (LLP <> NIL) AND NOT FOUND DO
                     WITH LLP@ DO
                       IF SAMELABEL(SY, LLP)  THEN
                         BEGIN FOUND := TRUE;
                           IF TTOP = TTOP1 THEN
                              BEGIN
                                 IF LABNO = 0 THEN
                                    GENLABEL(LABNO);
                                 GENTL(98 (*UJP*), 'L', LABNO);
                              END
                           ELSE (* GOTO LEADS OUT OF PROCEDURE *) ERROR(398)
                         END
                       ELSE LLP := NEXTLAB;
                   IF TTOP > 0 THEN TTOP := TTOP - 1
                 UNTIL FOUND OR (TTOP <= 0);
                 IF NOT FOUND THEN ERROR(167);
                 INSYMBOL
               END
             ELSE ERROR(404)
           END (* GOTOSTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE COMPOUNDSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE COMPOUNDSTATEMENT;
           BEGIN
             REPEAT
               REPEAT STATEMENT(FSYS + (.SEMICOLON,ENDSY.))
               UNTIL NOT (SY IN STATBEGSYS);
               TEST := SY <> SEMICOLON;
               IF NOT TEST THEN INSYMBOL
             UNTIL TEST;
             IF SY = ENDSY THEN
                BEGIN
                   BLEV := UPRED(BLEV);
                   EBLOCK := TRUE;
                   INSYMBOL
                END
             ELSE
                ERROR(13)
           END (* COMPOUNDSTATEMENET *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE IFSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE IFSTATEMENT;
             VAR LCIX1,LCIX2: LABELRNG;
           BEGIN EXPRESSION(FSYS + (.THENSY.));
             GENLABEL(LCIX1);
             LOAD;
             IF GATTR.TYPTR <> NIL THEN
               IF GATTR.TYPTR <> BOOLPTR THEN ERROR(144);
             GENTL(29(* FJP *),'L',LCIX1);

             IF SY = THENSY THEN INSYMBOL ELSE ERROR(52);

             STATEMENT(FSYS + (.ELSESY.));
             IF SY = ELSESY THEN
               BEGIN GENLABEL(LCIX2); GENTL(98(* UJP *),'L',LCIX2);
                 PUTLABEL(LCIX1);
                 INSYMBOL; STATEMENT(FSYS);
                 PUTLABEL(LCIX2)
               END
             ELSE PUTLABEL(LCIX1)
           END (* IFSTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE CASESTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE CASESTATEMENT;
                                        (* CHANGED TO ACCEPT OTHERWISE CLAUSE  *
)                                       (* CODE GEN'D IS:                      *
)                                       (*          LOAD CASE INDEX VALUE      *
)                                       (*          XJP LBND                   *
)                                       (*          UJP LOTHERWZ               *
)                                       (*  LCIX1A: <CODE FOR FIRST ALT>       *
)                                       (*          UJP LFINISH                *
)                                       (*  LCIX1B: <CODE FOR NEXT ALT>        *
)                                       (*          UJP LFINISH                *
)                                       (*             .                       *
)                                       (*             .                       *
)                                       (*             .                       *
)                                       (*  LCIX1I: <CODE FOR LAST ALT>        *
)                                       (*          UJP LFINISH                *
)                                       (*  LOTHERWZ:<CODE FOR OTHERWISE>      *
)                                       (*          UJP LFINISH                *
)                                       (*  LBND:   DEF 'LEAST ALTERNATE VAL'  *
)                                       (*  UBND:   DEF 'BIG   ALTERNATE VAL'  *
)                                       (*  LCIX:   VJP LOTHERWZ               *
)                                       (*          VJP LCIX1I                 *
)                                       (*             .                       *
)                                       (*             .                       *
)                                       (*             .                       *
)                                       (*  LFINISH: . . .                     *
)                                       (*(WHERE VJP IS UJP WITHOUT SHORT DISP)*
)
             TYPE CIP = @CASEINFO;
                  CASEINFO = PACKED
                             RECORD NEXT: CIP;
                               CSSTART: LABELRNG;
                               CSLAB: INTEGER
                             END;
             VAR LSP,LSP1: STP; FSTPTR,LPT1,LPT2,LPT3: CIP; LVAL: VALU;
                 LMIN, LMAX: ADDRRANGE ;
                 LOTHERWZ, LFINISH, LCIX, LCIX1, UBND, LBND: LABELRNG ;
                 C: CHAR;
                 OTHERWZ, FOUND: BOOLEAN;
           BEGIN EXPRESSION(FSYS + (.OFSY,COMMA,COLON.));
              LOAD ;
              LSP := GATTR.TYPTR;
              IF LSP <> NIL THEN
                IF (LSP@.FORM <> SCALAR) OR (LSP = REALPTR) THEN
                  BEGIN  ERROR(144); LSP := NIL END
                ELSE IF COMPTYPES(LSP,INT2PTR) THEN
                   CNVRTTOLHS (INT2PTR, LSP)
                ELSE
                   BEGIN
                      C := GETTYPE (LSP);
                      IF C <> 'I' THEN GEN2T (13 (*CVT*), C, 'I');
                   END;
             IF SY = OFSY THEN INSYMBOL ELSE ERROR(8);
              FSTPTR := NIL ;  GENLABEL(LBND) ;  GENLABEL(UBND) ;
              GENLABEL(LCIX) ;  GENLABEL(LOTHERWZ); GENLABEL(LFINISH);
              (*  WE MUST HAVE:  LCIX = UBND+1 = LBND+2 FOR THE 'XJP' TO WORK *)
              GENTL(109(* XJP *),'L', LBND) ;
              GENTL(98 (* UJP *),'L', LOTHERWZ) ;
               (*'XJP' WILL FALL THRU TO 'UJP' IF EXPR NOT IN RANGE OF ALTS*)
             OTHERWZ := FALSE;
             REPEAT
               LPT3 := NIL; GENLABEL(LCIX1);
                IF NOT(SY IN (.SEMICOLON,ENDSY.)) THEN
               BEGIN
                IF SY <> OTHERWZSY THEN
                 BEGIN
                 REPEAT CONSTANT(FSYS + (.COMMA,COLON.),LSP1,LVAL);
                   IF LSP <> NIL THEN
                     BEGIN
                     IF LSP = CHARPTR THEN LVAL.IVAL := ASCII(.CHR(LVAL.IVAL).);
                     IF COMPTYPES(LSP,LSP1) THEN
                       BEGIN LPT1 := FSTPTR; LPT2 := NIL;
                         FOUND := FALSE;
                         WHILE NOT FOUND AND (LPT1 <> NIL) DO
                           WITH LPT1@ DO
                             BEGIN
                               IF CSLAB <= LVAL.IVAL THEN
                                 BEGIN IF CSLAB = LVAL.IVAL THEN ERROR(156);
                                   FOUND := TRUE
                                 END
                               ELSE BEGIN LPT2 := LPT1; LPT1 := NEXT END
                             END;
                         NEW(LPT3);
                         WITH LPT3@ DO
                           BEGIN NEXT := LPT1; CSLAB := LVAL.IVAL;
                             CSSTART := LCIX1
                           END;
                         IF LPT2 = NIL THEN FSTPTR := LPT3
                         ELSE LPT2@.NEXT := LPT3
                       END
                     ELSE ERROR(147);
                     END (*  LSP <> NIL  *) ;
                   TEST := SY <> COMMA;
                   IF NOT TEST THEN INSYMBOL
                 UNTIL TEST;
                 IF SY = COLON THEN INSYMBOL ELSE ERROR(5);
                 PUTLABEL(LCIX1)
                 END
                ELSE BEGIN OTHERWZ := TRUE;
                           IF STANDARD THEN WARNING(506);
                           INSYMBOL;
                           PUTLABEL(LOTHERWZ)
                     END;
                 REPEAT STATEMENT(FSYS + (.SEMICOLON.))
                 UNTIL NOT (SY IN STATBEGSYS);
                 IF (LPT3 <> NIL) OR OTHERWZ THEN
                   GENTL(98(* UJP *),'L',LFINISH);
                END ;
               TEST := SY <> SEMICOLON;
               IF NOT TEST THEN INSYMBOL
             UNTIL TEST OR OTHERWZ;
             IF FSTPTR <> NIL THEN
               BEGIN LMAX := FSTPTR@.CSLAB;
                 (* REVERSE POINTERS *)
                 LPT1 := FSTPTR; FSTPTR := NIL;
                 REPEAT LPT2 := LPT1@.NEXT; LPT1@.NEXT := FSTPTR;
                   FSTPTR := LPT1; LPT1 := LPT2
                 UNTIL LPT1 = NIL;
                 LMIN := FSTPTR@.CSLAB;
                  GENDEF(LBND,LMIN);
                  GENDEF(UBND,LMAX);
                  PUTLABEL(LCIX);
                 IF LMAX - LMIN < CIXMAX THEN
                    BEGIN
                     REPEAT
                       WITH FSTPTR@ DO
                         BEGIN
                           WHILE CSLAB > LMIN DO
                             BEGIN GENTL(113(* VJP *),'L',LOTHERWZ);
                                   LMIN:=LMIN+1 END;
                           GENTL(113(* VJP *),'L',CSSTART);
                           FSTPTR := NEXT; LMIN := LMIN + 1
                         END
                     UNTIL FSTPTR = NIL;
                     IF NOT OTHERWZ THEN BEGIN PUTLABEL(LOTHERWZ);
                                               GENI (112(*MST*),SYSTEM);
                                               GENTI(45 (*LDC*),'I',1);
                                               GENTI(116(*ARG*),'I',SYSTEM);
                                               GENI (26 (*EXI*), 0) END;
                     PUTLABEL(LFINISH) ;
                   END
                 ELSE ERROR(157)
               END;
               IF SY = ENDSY THEN
                  BEGIN
                     BLEV := UPRED(BLEV);
                     EBLOCK := TRUE;
                     INSYMBOL
                  END
               ELSE
                  ERROR(13)
           END (* CASESTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE REPEATSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE REPEATSTATEMENT;
             VAR LADDR: LABELRNG;
           BEGIN GENLABEL(LADDR); PUTLABEL(LADDR);
             REPEAT
               REPEAT STATEMENT(FSYS + (.SEMICOLON,UNTILSY.))
               UNTIL NOT (SY IN STATBEGSYS);
               TEST := SY <> SEMICOLON;
               IF NOT TEST THEN INSYMBOL
             UNTIL TEST;
             IF SY = UNTILSY THEN
               BEGIN
                  BLEV := UPRED(BLEV);
                  EBLOCK := TRUE;
                  GENKOUNT(FALSE);
                  INSYMBOL;
                  EXPRESSION(FSYS);
                  LOAD;
                  IF GATTR.TYPTR <> NIL THEN
                     IF GATTR.TYPTR <> BOOLPTR THEN
                        ERROR(144);
                  GENTL(29 (* FJP *), 'L', LADDR)
               END
             ELSE ERROR(53)
           END (* REPEATSTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE WHILESTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE WHILESTATEMENT;
             VAR LADDR, LCIX: LABELRNG;
           BEGIN GENLABEL(LADDR); PUTLABEL(LADDR);
             EXPRESSION(FSYS + (.DOSY.)); GENLABEL(LCIX);
             LOAD;
             IF GATTR.TYPTR <> NIL THEN
               IF GATTR.TYPTR <> BOOLPTR THEN ERROR(144);
             GENTL(29(* FJP *),'L',LCIX);
             IF SY = DOSY THEN INSYMBOL ELSE ERROR(54);
             STATEMENT(FSYS); GENTL(98(* UJP *),'L',LADDR); PUTLABEL(LCIX)
           END (* WHILESTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE FORSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE FORSTATEMENT;
             VAR LATTR: ATTR; K: CHAR;    LSY: SYMBOL;
                 LCIX, LADDR: LABELRNG ;  LLC : ADDRRANGE ;
                 INDEXVARSIZE:  INTEGER;
                 LCP:           CTP;

           BEGIN
             INDEXVARSIZE  := 0;

             IF SY = IDENT
                THEN  SEARCHID((.VARS.),LCP)
                ELSE  BEGIN
                         ERROR (2);
                         LCP  := UVARPTR
                      END; (*ELSE*)

             WITH LCP@,LATTR DO
                BEGIN
                   TYPTR  := IDTYPE;
                   KIND   := VARBL;
                   IF VKIND = ACTUAL
                      THEN  BEGIN
                               ACCESS  := DRCT;
                               VLEVEL  := VLEV;
                               DPLMT   := VADDR(.1.)
                            END (*THEN*)
                      ELSE  BEGIN
                               ERROR (155);
                               TYPTR  := NIL
                            END (*ELSE*)
                END; (*WITH*)

             IF LATTR.TYPTR <> NIL THEN
                IF (LATTR.TYPTR@.FORM > SUBRANGE) OR (LATTR.TYPTR = REALPTR) THE
N                  BEGIN
                      ERROR (143);
                      LATTR.TYPTR  := NIL
                   END; (*THEN*)

             K  := GETTYPE(LATTR.TYPTR);
             IF SY = IDENT
                THEN  INSYMBOL
                ELSE  SKIP(FSYS + (.BECOMES,TOSY,DOWNTOSY,DOSY.));

             IF SY = BECOMES THEN
               BEGIN INSYMBOL; EXPRESSION(FSYS + (.TOSY,DOWNTOSY,DOSY.));
                 IF (GATTR.TYPTR <> NIL) AND (LATTR.TYPTR <> NIL) THEN
                     IF GATTR.TYPTR@.FORM <> SCALAR THEN ERROR(144)
                     ELSE
                       IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR) THEN
                          BEGIN
                             LOAD;
                             CHKBNDS (LATTR.TYPTR, GATTR.TYPTR, 145);
                             IF INTTYPE (GATTR.TYPTR) THEN
                                CNVRTTOLHS (LATTR.TYPTR, GATTR.TYPTR);
                             STORE (LATTR);
                          END
                       ELSE ERROR(145)
               END
             ELSE
               BEGIN ERROR(51); SKIP(FSYS + (.TOSY,DOWNTOSY,DOSY.)) END;
             IF SY IN (.TOSY,DOWNTOSY.) THEN
               BEGIN LSY := SY; INSYMBOL; EXPRESSION(FSYS + (.DOSY.));
                 IF (GATTR.TYPTR <> NIL) AND (LATTR.TYPTR <> NIL) THEN
                 IF GATTR.TYPTR@.FORM <> SCALAR THEN ERROR(144)
                   ELSE
                     IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR) THEN
                        BEGIN
                           LOAD;
                           CHKBNDS (LATTR.TYPTR, GATTR.TYPTR, 145);
                           IF INTTYPE (GATTR.TYPTR) THEN
                              CNVRTTOLHS (LATTR.TYPTR, GATTR.TYPTR);
                          INDEXVARSIZE  := LATTR.TYPTR@.SIZE;
                          LOCN := LOCN - INDEXVARSIZE;
                          IF INDEXVARSIZE > 1 THEN LOCN := ALIGN(LOCN);
                          LLC := LOCN ;
                          GENTLI(96(* STR *),K,LEVEL,LLC);
                          GATTR := LATTR; LOAD;
                          GENTLI(48(* LOD *),K,LEVEL,LLC);
                           IF LOCN < LCMIN THEN LCMIN := LOCN;
                          IF LSY = TOSY THEN GENT(46(* LEQ *),K)
                          ELSE GENT(30(* GEQ *),K);
                        END
                     ELSE ERROR(145)
               END
             ELSE BEGIN ERROR(55); SKIP(FSYS + (.DOSY.)) END;
              GENLABEL(LADDR) ;  GENLABEL(LCIX);  GENTL(29(* FJP *),'L',LCIX);
              PUTLABEL(LADDR) ;  (* BEGINNING OF THE FOR 'LOOP' *)
             IF SY = DOSY THEN INSYMBOL ELSE ERROR(54);
             STATEMENT(FSYS);
              GATTR := LATTR ;  LOAD ;
              GENTLI(48(* LOD *),K,LEVEL,LLC) ;
              GENT(59(* NEQ *),K) ;  GENTL(29(* FJP *),'L',LCIX) ;
              GATTR := LATTR; LOAD;
              IF LSY = TOSY THEN  GENTI(34(* INC *),K,1)
                            ELSE  GENTI(16(* DEC *),K,1);
              CHKBNDS (LATTR.TYPTR, GATTR.TYPTR, 145);
             STORE(LATTR); GENTL(98(* UJP *),'L',LADDR); PUTLABEL(LCIX);
             LOCN := LLC + INDEXVARSIZE ;
           END (* FORSTATEMENT *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE WITHSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE WITHSTATEMENT;
              VAR LCP: CTP; LCNT: DISPRANGE; LLC: ADDRRANGE;
           BEGIN LCNT := TOP ; LLC := LOCN ;
             REPEAT
               IF SY = IDENT
                 THEN BEGIN SEARCHID((.VARS,FIELD.),LCP); INSYMBOL END
                 ELSE BEGIN ERROR(2); LCP := UVARPTR END;
               SELECTOR(FSYS + (.COMMA,DOSY.),LCP);
               IF GATTR.TYPTR <> NIL THEN
                 IF GATTR.TYPTR@.FORM = RECORDS THEN
                   IF TOP < DISPLIMIT THEN
                     BEGIN  TOP := TOP + 1;
                     WITH DISPLAY(.TOP.) DO BEGIN
                         FNAME  := GATTR.TYPTR@.FSTFLD;
                         FLABEL := NIL
                         END;
                       IF GATTR.ACCESS = DRCT THEN
                         WITH DISPLAY(.TOP.) DO
                          BEGIN OCCUR := CREC;
                                CLEV  := GATTR.VLEVEL;
                                CDSPL := GATTR.DPLMT
                          END
                       ELSE
                         BEGIN  LOADADDRESS;
                           LOCN := LOCN - ADDRSIZE;
                           LOCN := ALIGN(LOCN);
                           GENTLI(96(* STR *),'A',LEVEL,LOCN);
                           WITH DISPLAY(.TOP.) DO
                           BEGIN OCCUR := VREC; VDSPL := LOCN END;
                           IF LOCN < LCMIN THEN LCMIN := LOCN
                         END
                     END
                   ELSE ERROR(250)
                 ELSE ERROR(140);
               TEST := SY <> COMMA;
               IF NOT TEST THEN INSYMBOL
             UNTIL TEST;
             IF SY = DOSY THEN INSYMBOL ELSE ERROR(54);
             STATEMENT(FSYS);
             TOP := LCNT ; LOCN := LLC ;
           END (* WITHSTATEMENT *) ;



   (* -------------------------------------------------------------------------
      PROCEDURE EXITSTATEMENT
     ------------------------------------------------------------------------- *
)
           PROCEDURE EXITSTATEMENT;          (*TAKES LABEL OR NULL.  IF NULL   *
)          VAR FOUND: BOOLEAN;               (*THEN EXIT CURRENT LOOP CONSTRUCT*
)              LPTR: LOOPPTR;                (*(WHILE,REPEAT,OR FOR) IF LABEL  *
)                                            (*THEN EXIT LOOP WITH THAT LABEL  *
)                                            (*'LOOPENTRY' AND 'LOOPEXIT' KEEP *
)                                            (*A STACK OF THE CURRENT EXIT LABS*
)                                            (*EITHER USE THE TOP ITEM OR SCAN *
)                                            (*BACK UNTIL FIND ONE POINTING TO *
)                                            (*TO SPECIFIED ACTUAL LABEL       *
)          BEGIN
           IF STANDARD THEN WARNING(505);
           IF (SY = INT2CONST) OR (SY = IDENT) THEN
                   BEGIN FOUND := FALSE;
                      LPTR := LOOPLISTPTR;
                      WHILE NOT FOUND AND (LPTR <> NIL) DO
                           IF SAMELABEL(SY,LPTR@.ASSOCLAB) THEN
                              BEGIN
                                 FOUND := TRUE;
                                 IF LPTR@.LABNO = 0 THEN
                                    GENLABEL(LPTR@.LABNO);
                                 GENTL(98 (*UJP*), 'L', LPTR@.LABNO);
                                 LPTR@.USED := TRUE;
                              END
                           ELSE LPTR := LPTR@.NEXTLOOP;
                      IF NOT FOUND THEN ERROR(411);
                      INSYMBOL
                   END
           ELSE BEGIN
                 IF NOT (SY IN (.SEMICOLON,ENDSY,ELSESY,UNTILSY.)) THEN ERROR(41
0)               ELSE IF LOOPLISTPTR <> NIL THEN
                      BEGIN
                         IF LOOPLISTPTR@.LABNO = 0 THEN
                            GENLABEL(LOOPLISTPTR@.LABNO);
                         GENTL(98 (*UJP*), 'L', LOOPLISTPTR@.LABNO);
                         LOOPLISTPTR@.USED := TRUE;
                      END
                      ELSE ERROR(412)
                END
           END;   (*EXITSTATEMENT*)



         PROCEDURE LOOPENTRY;      (*DEFINE AN EXIT LABEL FOR THIS LOOP STMNT *)
           VAR
               LPTR: LOOPPTR;

           BEGIN
              NEW(LPTR);                   (*CREATE NEW LOOP EXIT LABEL*)
              WITH LPTR@ DO BEGIN
                   LABNO   := 0;
                   ASSOCLAB:= LLP;    (*POINT TO ACTUAL LABEL OF LOOP IF ANY*)
                               (*THIS CODE ASSUMES THAT LLP IS NIL IF
                                THE CURRENT STATEMENT IS NOT LABELLED*)
                   NEXTLOOP:= LOOPLISTPTR; (*PUT ON STACK OF LOOP EXIT LABELS*)
                   USED    := FALSE        (*NOT REFERENCED YET*)
              END;
              LOOPLISTPTR := LPTR
           END;   (*LOOPENTRY*)


           PROCEDURE LOOPEXIT;                  (*PROCESS AND REMOVE THE EXIT
                                                 LABEL FOR THIS LOOP*)
           BEGIN WITH LOOPLISTPTR@ DO BEGIN
                   IF USED THEN PUTLABEL(LABNO); (*INSERT EXIT LABEL INTO OBJECT
                                                  IF IT WAS REFERENCED*)
                   LOOPLISTPTR := NEXTLOOP       (*REMOVE FROM STACK*)
                   END
           END;   (*LOOPEXIT*)



         BEGIN (* *START** STATEMENT *)
           LLP := NIL;      (*NEEDED FOR EXIT LOOPS*)
           IF (SY = INT2CONST) OR (SY = IDENT) THEN (* LABEL *)
             BEGIN  TTOP := TOP ;
              WHILE DISPLAY(.TTOP.).OCCUR <> BLCK DO  TTOP := TTOP-1 ;
              LLP := DISPLAY(.TTOP.).FLABEL;
              FOUND := FALSE;
               WHILE NOT FOUND AND (LLP <> NIL) DO
                 WITH LLP@ DO
                   IF SAMELABEL(SY, LLP) THEN
                     BEGIN
                        IF DEFINED THEN ERROR(165);
                        IF LABNO = 0 THEN
                           GENLABEL(LABNO);
                        PUTLABEL(LABNO);
                        DEFINED := TRUE;
                        FOUND := TRUE;
                     END
                   ELSE LLP := NEXTLAB;
               IF SY = INT2CONST THEN BEGIN
                   IF NOT FOUND THEN ERROR(167);
                   INSYMBOL; IF SY = COLON THEN INSYMBOL ELSE ERROR(5)
                   END
               ELSE IF FOUND THEN    (* ALPHA LABEL *)
                  BEGIN INSYMBOL; IF SY = COLON THEN INSYMBOL ELSE ERROR(5) END;
             END;
           IF NOT (SY IN FSYS + (.IDENT.)) THEN
             BEGIN ERROR(6); SKIP(FSYS) END;
           IF SY IN STATBEGSYS + (.IDENT.) THEN
             BEGIN

               IF SY IN LOOPBEGSYS THEN BEGIN LOOPENTRY;  (*SET UP EXIT LABEL*)
                                              INLOOP := TRUE END
                                   ELSE INLOOP := FALSE;

               CASE SY OF
                 IDENT:    BEGIN SEARCHID((.VARS,FIELD,FUNC,PROC.),LCP);
                             GENKOUNT(FALSE); INSYMBOL;
                             IF LCP@.KLASS = PROC THEN CALL(FSYS,LCP)
                             ELSE ASSIGNMENT(LCP)
                           END;
                 BEGINSY:  BEGIN
                              BLEV := USUCC(BLEV);
                              SBLOCK := TRUE;
                              INSYMBOL;
                              COMPOUNDSTATEMENT
                           END;
                 GOTOSY:   BEGIN GENKOUNT(FALSE); INSYMBOL; GOTOSTATEMENT   END;
                 IFSY:     BEGIN GENKOUNT(FALSE); INSYMBOL; IFSTATEMENT     END;
                 CASESY:   BEGIN
                              BLEV := USUCC(BLEV);
                              SBLOCK := TRUE;
                              GENKOUNT(FALSE);
                              INSYMBOL;
                              CASESTATEMENT
                           END;
                 WHILESY:  BEGIN GENKOUNT(FALSE); INSYMBOL; WHILESTATEMENT  END;
                 REPEATSY: BEGIN
                              BLEV := USUCC(BLEV);
                              SBLOCK := TRUE;
                              INSYMBOL;
                              REPEATSTATEMENT
                           END;
                               (* GENKOUNT(FALSE) WHEN 'UNTIL' ENCOUNTERED *)
                 FORSY:    BEGIN GENKOUNT(FALSE); INSYMBOL; FORSTATEMENT    END;
                 EXITSY:   BEGIN GENKOUNT(FALSE); INSYMBOL; EXITSTATEMENT   END;
                 WITHSY:   BEGIN                  INSYMBOL; WITHSTATEMENT   END
               END;

               IF INLOOP THEN LOOPEXIT;

               IF NOT (SY IN (.SEMICOLON,ENDSY,ELSESY,UNTILSY.)) THEN
                 BEGIN ERROR(6); SKIP(FSYS) END
             END
         END (* STATEMENT *) ;

      BEGIN  (***START** BODY *)
          IF FPROCP <> NIL THEN
            BEGIN ENTNAME := FPROCP@.PFNAME; PROCNAME := FPROCP@.NAME  END
          ELSE
            BEGIN ENTNAME := 0; PROCNAME := PROGNAME; PARMLEN := 0 END;

          GENLABEL(SEGSIZE) ;
          GENENT(ENTNAME,21(* ENT *),LEVEL,SEGSIZE,PROCNAME) ;
          LABELEDKOUNT := TRUE;
          GENKOUNT(TRUE);
          PRINTKOUNT := FALSE;
          MINKOUNT := KOUNT;

         LCMIN := LOCN;

         (*OPEN LOCAL FILES*)
           KLOCFILELIST := LOCFILELIST;
           WHILE KLOCFILELIST <> NIL DO BEGIN
                   WITH KLOCFILELIST@ DO BEGIN
                           GENI(112 (*MST*), 0);
                           GENLI(44(*LDA*),VLEV,VADDR(.1.));(*PUSH ADDR(FILE PTR
)*)                        GENTI(116 (*ARG*), 'A', 0);
                                        (*GET POSITION IN PROGRAM HEADER LIST*)
                           K := 0;
                           IF (LEVEL = 0) AND (FEXTFILEP <> NIL) THEN
                                BEGIN KFILE := FEXTFILEP;
                                   WHILE KFILE <> NIL DO BEGIN
                                      IF KFILE@.FILENAME = NAME THEN
                                           K := KFILE@.POS;
                                      KFILE := KFILE@.NEXTFILE
                                      END
                                END;
                           GENTI(45(*LDC*),'I',K);        (*PUSH FILE POSITION*)
                           GENTI(116 (*ARG*), 'I', 0);
                                                        (*BUILD FILE STATUS*)
                           IF IDTYPE = TEXTPTR THEN STATUS := 4 ELSE STATUS := 0
;                          IF NOT EXTRNL THEN STATUS := STATUS + 8;
                           STDFILE := FALSE;
                           IF KLOCFILELIST = STDINPUT THEN
                                BEGIN STDFILE := TRUE;
                                STATUS := STATUS + 2  END
                             ELSE IF KLOCFILELIST = STDOUTPUT THEN
                                BEGIN STDFILE := TRUE;
                                STATUS := STATUS + 1 END;
                           GENTI(45(*LDC*),'I',STATUS);   (*PUSH FILE STATUS*)
                           GENTI(116 (*ARG*), 'I', 0);
                           GENTI(45(*LDC*),'I',IDTYPE@.FILTYPE@.SIZE);
                                                        (*PUSH COMPONENT SIZE*)
                           GENTI(116 (*ARG*), 'I', 0);
                           GEN(33(*IFD*)) ;

                           IF STDFILE THEN BEGIN
                                GENI(112 (*MST*), 0);
                                (*PUSH ADDR(FILE PTR)*)
                                GENLI(44(*LDA*),VLEV,VADDR(.1.));
                                GENTI(116 (*ARG*), 'A', 0);
                                IF KLOCFILELIST = STDINPUT THEN K := 80(*RST*)
                                                           ELSE K := 81(*RWT*);
                                GEN(K (*RST,RWT*))
                                END;

                   KLOCFILELIST := (*KLOCFILELIST@.*)NEXT END
                   END;
         LOOPLISTPTR := NIL;
         REPEAT
           REPEAT STATEMENT(FSYS + (.SEMICOLON,ENDSY.))
           UNTIL NOT (SY IN STATBEGSYS);
           TEST := SY <> SEMICOLON;
           IF NOT TEST THEN INSYMBOL
         UNTIL TEST;
         IF SY = ENDSY THEN
            BEGIN
               EBLOCK := TRUE;
               BLEV := UPRED(BLEV);
               INSYMBOL
            END
         ELSE
            ERROR(13);

         (*CLOSE LOCAL FILES*)
           KLOCFILELIST := LOCFILELIST;
           WHILE KLOCFILELIST <> NIL DO BEGIN
                   WITH KLOCFILELIST@ DO BEGIN
                           GENI(112 (*MST*), 0);
                           GENLI(44(*LDA*),VLEV,VADDR(.1.));(*PUSH ADDR(FILE PTR
)*)                        GENTI(116 (*ARG*), 'A', 0);
                           GEN(7(*CLO*)) END;
                   KLOCFILELIST := KLOCFILELIST@.NEXT END;

         LLP := DISPLAY(.TOP.).FLABEL; (* TEST FOR UNDEFINED LABELS *)
         WHILE LLP <> NIL DO
           WITH LLP@ DO
             BEGIN
               IF NOT DEFINED THEN
                 BEGIN
                    IF PAGEPOS > PAGEEND THEN NEWPAGE;
                    ERRORCOUNT := ERRORCOUNT + 1;
                    WRITE(LISTING, ERRMES:11,LASTERR:6,'** 168 ');
                    IF ALF THEN WRITELN(LISTING,LABNAME)
                           ELSE WRITELN(LISTING,LABVAL:0);
                    LASTERR := LINECOUNT;
                    PAGEPOS := PAGEPOS + 1
                 END;
               LLP := LLP@.NEXTLAB
             END;

           K  := ALIGN (ABS(LCMIN));
           GENDEF(SEGSIZE,K)  ;  (* ASSURE EVEN ADDR *)
           IF K > STKSIZES(.LEVEL.) THEN  STKSIZES(.LEVEL.)  := K;
           IF FPROCP = NIL THEN GEN(95(* STP *));


        OLDIC := OLDIC+ IC ;  IC := 0 ;  (*  RESET IC FOR NEXT PROC  *)
       END (* BODY *) ;

     BEGIN (* **START** BLOCK *)
       FWDLIST    := NIL;
       LOCFILELIST:= GLOBFILELIST; GLOBFILELIST := NIL;
       DP := TRUE;
       REPEAT
         IF SY = LABELSY THEN
           BEGIN INSYMBOL; LABELDECLARATION END;
         IF SY = CONSTSY THEN
           BEGIN INSYMBOL; CONSTDECLARATION END;
         IF SY = TYPESY THEN
           BEGIN INSYMBOL; TYPEDECLARATION END;
         IF SY = VARSY THEN
           BEGIN INSYMBOL; VARDECLARATION END;
         WHILE SY IN (.PROCSY,FUNCSY.) DO
           BEGIN LSY := SY; INSYMBOL; PROCDECLARATION(LSY) END;
        IF NOT(SY IN FSYS + (.PERIOD.)) THEN
                         BEGIN ERROR(18); SKIP(FSYS + (.PERIOD.)) END;
         IF STANDARD AND (SY <> BEGINSY) THEN WARNING(502) (* UNORDERED DECL'S *
)      UNTIL SY IN STATBEGSYS+(.PERIOD.);

             (* EXPECTING DECL'S TO BE FINISHED HERE; CHECK UNRESOLVED
               FWD TYPE DEFINITIONS (CODE MOVED HERE FROM 'TYPEDECL' *)
         WHILE FWPTR <> NIL DO
            BEGIN
               IF PAGEPOS > PAGEEND THEN NEWPAGE;
               ERRORCOUNT := ERRORCOUNT + 1;
               WRITELN(LISTING,ERRMES:11,LASTERR:6,'** 117 TYPE-ID ',FWPTR@.NAME
);             PAGEPOS := PAGEPOS + 1;
               LASTERR := LINECOUNT;
               FWPTR := FWPTR@.NEXT
            END;

             (* CHECK FOR AND FLAG UNRESOLVED FORWARD PROC/FUNCS *)
             (* IF IN MAIN BODY THEY ARE ASSUMED TO BE EXTERNAL  *)
           WHILE FWDLIST <> NIL DO
               BEGIN WITH FWDLIST@.PF@ DO
                   BEGIN
                      IF LEVEL = 0 THEN
                         BEGIN (* IN MAIN BODY *)
                            GENDEF1(PFNAME,NAME);
                            IF PAGEPOS > PAGEEND THEN NEWPAGE;
                            PAGEPOS := PAGEPOS + 1;
                            WRITELN(LISTING, STARS:7,NAME,' ASSUMED EXTERNAL')
                         END
                      ELSE
                         BEGIN
                           IF PAGEPOS > PAGEEND THEN NEWPAGE;
                            ERRORCOUNT := ERRORCOUNT + 1;
                            WRITE(LISTING, ERRMES:11,LASTERR:6);
                            WRITELN(LISTING,'** 117 PROC/FUNC ',NAME);
                            LASTERR := LINECOUNT;
                            PAGEPOS := PAGEPOS + 1;
                         END;
                   END;
               FWDLIST := FWDLIST@.NEXTPF
             END;

       DP := FALSE;

     IF NOT (SUBPROG AND (LEVEL = 0)) THEN
       BEGIN
         IF SY = BEGINSY THEN
            BEGIN
               PRINTKOUNT := TRUE;
               SBLOCK := TRUE;
               BLEV := 'B';
               MLEV := 'A';
               INSYMBOL
            END
         ELSE
            ERROR(17);
         REPEAT BODY(FSYS + (.CASESY.));
           IF (SY <> FSY) AND NOT ((SY = PERIOD) AND (LEVEL = 1) AND SUBPROG)
             THEN BEGIN ERROR(6); SKIP(FSYS + (.FSY.) + (.PERIOD.)) END
         UNTIL (SY = FSY) OR (SY = PERIOD) OR (SY IN BLOCKBEGSYS);
       END
     END (* BLOCK *) ;


   (* -------------------------------------------------------------------------
      PROCEDURE PROGRAMME
     ------------------------------------------------------------------------- *
)
     PROCEDURE PROGRAMME(FSYS: SETOFSYS);
       VAR EXTFP:EXTFILEP;
           LCP: CTP;
           I, FILEPOS: INTEGER;
     BEGIN
       IF (SY = PROGSY) OR (SY = SUBPROGSY) THEN
         BEGIN IF SY = SUBPROGSY THEN BEGIN SUBPROG:=TRUE;
                                            IF STANDARD THEN WARNING(507)
                                      END
                                 ELSE SUBPROG:=FALSE;
           INSYMBOL; IF SY <> IDENT THEN ERROR(2); PROGNAME:=ID;  INSYMBOL;
           IF NOT (SY IN (.LPARENT,SEMICOLON.)) THEN ERROR(14);
           IF SY = LPARENT  THEN
             BEGIN
               FILEPOS := 0;
               REPEAT INSYMBOL;
                 IF SY = IDENT THEN
                   BEGIN
                        IF     (ID <> 'INPUT   ')
                           AND (ID <> 'OUTPUT  ') THEN
                        BEGIN NEW(EXTFP);
                          FILEPOS := FILEPOS + 1;
                          WITH EXTFP@ DO
                             BEGIN FILENAME := ID;
                                   NEXTFILE := FEXTFILEP ;
                                   POS := FILEPOS;
                                   DEF := FALSE
                             END;
                           FEXTFILEP := EXTFP;
                        END
                     ELSE
                        BEGIN NEW(LCP,VARS);
                           WITH LCP@ DO
                           BEGIN NAME := ID; IDTYPE := TEXTPTR;
                              KLASS := VARS; VKIND := ACTUAL; VLEV := 0;
                              EXTRNL := TRUE;
                              LOCN  := LOCN - 2 * ADDRSIZE;  VADDR(.1.) := LOCN;
                              NEXT := GLOBFILELIST; GLOBFILELIST := LCP;
                           END;
                           IF ID = 'INPUT   ' THEN STDINPUT  := LCP
                                                ELSE STDOUTPUT := LCP;

                           ENTERID(LCP)
                        END;

                     INSYMBOL;
                     IF NOT ( SY IN (.COMMA,RPARENT.) ) THEN ERROR(20)
                   END
                 ELSE ERROR(2)
               UNTIL SY <> COMMA;
               IF SY <> RPARENT THEN ERROR(4);
               INSYMBOL
             END;
           IF SY <> SEMICOLON THEN ERROR(14)
           ELSE INSYMBOL;
         END;

       WRITE(PCODE,'HP');
       IF ADDRSIZE = 4 THEN
          WRITE(PCODE,'20')
       ELSE
          WRITE(PCODE,'09');
       WRITE (PCODE,' ''',PROGNAME,'''');
       IF SUBPROG THEN
          WRITE(PCODE,'S ':3)
       ELSE
          WRITE(PCODE,'M ':3);
       OUTHEX (PCODE,JUMPBASE);
       WRITE (PCODE,JUMPENTRIES:6,' ');
       OUTHEX (PCODE,HEAPSTART);
       WRITE (PCODE,' ');
       OUTHEX (PCODE,STACKSTART);
       WRITELN (PCODE,' ');

       (*REPEAT*) BLOCK(FSYS,PERIOD,NIL);
         IF SY <> PERIOD THEN ERROR(21)
       (*UNTIL SY = PERIOD*) ;

       WRITELN (PCODE,' END');

       IF LIST THEN WRITELINE;
       IF ERRINX > 0 THEN  PRINTERROR ;

       WHILE FEXTFILEP <> NIL DO
          BEGIN
             IF NOT FEXTFILEP@.DEF THEN
                BEGIN
                   IF PAGEPOS > PAGEEND THEN NEWPAGE;
                   ERRORCOUNT := ERRORCOUNT + 1;
                   WRITE(LISTING, ERRMES:11, LASTERR:6);
                   WRITELN(LISTING,'** 172 FILE ',FEXTFILEP@.FILENAME);
                   LASTERR := LINECOUNT;
                   PAGEPOS := PAGEPOS + 1;
                END; (* IF NOT FEXTFILEP@.DEF ... *)
             FEXTFILEP := FEXTFILEP@.NEXTFILE
          END; (* WHILE FEXTFILEP <> NIL *)
     END (* PROGRAMME *) ;



   (* -------------------------------------------------------------------------
     INITIALIZATION PROCEDURES
     ------------------------------------------------------------------------- *
)
     PROCEDURE ENTERSTDTYPES;
     BEGIN                                             (* TYPE UNDERLYING: *)
                                                       (* +++++++++++++++++ *)

       NEW (INT1PTR,SCALAR);                           (*SHORTINT*)
       WITH INT1PTR@ DO
          BEGIN
             SIZE  := INT1SIZE;
             FORM  := SCALAR
          END; (*WITH*)

       NEW(INT2PTR,SCALAR);                             (* INTEGER *)
       WITH INT2PTR@ DO
         BEGIN SIZE := INT2SIZE;
               FORM := SCALAR; END;

       NEW (INT4PTR,SCALAR);                           (*LONGINT*)
       WITH INT4PTR@ DO
          BEGIN
             SIZE  := INT4SIZE;
             FORM  := SCALAR
          END; (*WITH*)

       NEW(REALPTR,SCALAR);                            (* REAL *)
       WITH REALPTR@ DO
         BEGIN SIZE := REALSIZE;
               FORM := SCALAR; END;

       NEW(CHARPTR,SCALAR);                            (* CHAR *)
       WITH CHARPTR@ DO
         BEGIN SIZE := CHARSIZE;
               FORM := SCALAR; END;

       NEW(BOOLPTR,SCALAR);                             (* BOOLEAN *)
       WITH BOOLPTR@ DO
         BEGIN SIZE := BOOLSIZE;
               FORM := SCALAR; END;

       NEW(NILPTR,POINTER);                                      (* NIL *)
       WITH NILPTR@ DO
         BEGIN ELTYPE := NIL; SIZE := ADDRSIZE;
               FORM := POINTER END;

       NEW(TEXTPTR,FILES);                                       (* TEXT *)
       WITH TEXTPTR@ DO
         BEGIN FILTYPE := CHARPTR; SIZE := 2*ADDRSIZE;
               FORM := FILES END;

       NEW(SINGLECHARSTRING, STRINGS);
       WITH SINGLECHARSTRING@ DO
          BEGIN
             FORM := STRINGS;
             SIZE := 4;
          END;

     END (* ENTERSTDTYPES *) ;


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  ENTSTDNAMES                                      *)
   (*                                                                    *)
   (*        THIS PROCEDURE ENTERS THE STANDARD NAMES INTO THE HEAP.     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  ENTSTDNAMES;

      VAR
         NA:      ARRAY (.STDNAMES.) OF ALPHA;     (*THE NAMES*)
         CP,
         CPLAST:  CTP;                             (*PTRS TO NAMES*)
         N:       STDNAMES;


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  ENTERPROC (PROCNAME,PROCTYPE)                    *)
   (*                                                                    *)
   (*        THIS PROCEDURE ENTERS THE PROCEDURE OR FUNCTION WHOSE       *)
   (*        NAME IS 'PROCNAME' AND TYPE IS 'PROCTYPE' INTO THE HEAP.    *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  ENTERPROC (PROCNAME: STDNAMES;  PROCTYPE: IDCLASS);

      VAR
         CP:   CTP;                         (*PTR TO NAME*)

      BEGIN (*ENTERPROC*)
         NEW (CP,PROC);                     (*GET A NEW RECORD*)

         WITH CP@ DO                        (*SET UP THE RECORD*)
            BEGIN
               NAME      := NA(.PROCNAME.);
               IDTYPE    := NIL;
               NEXT      := NIL;
               KEY       := PROCNAME;
               KLASS     := PROCTYPE;
               PFDECKIN  := BUILTIN
            END; (*WITH*)

         ENTERID (CP)                       (*ENTER THE NAME*)

      END; (*ENTERPROC*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        PROCEDURE  ENTERTYPE (TYPENAME,TYPEPTR)                     *)
   (*                                                                    *)
   (*        THIS PROCEDURE ENTERS THE TYPE WHOSE NAME IS 'TYPENAME'     *)
   (*        AND POINTER IS 'TYPEPTR'.                                   *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

   PROCEDURE  ENTERTYPE (TYPENAME: STDNAMES;  TYPEPTR: STP);

      VAR
         CP:  CTP;                          (*PTR TO THE NAME*)

      BEGIN (*ENTERTYPE*)
         NEW (CP,TYPES);                    (*GET A NEW RECORD*)

         WITH CP@ DO                        (*SET UP THE RECORD*)
            BEGIN
               NAME    := NA(.TYPENAME.);
               IDTYPE  := TYPEPTR;
               KLASS   := TYPES
            END; (*WITH*)

         ENTERID (CP)                       (*ENTER THE NAME*)

      END; (*ENTERTYPES*)


   (*--------------------------------------------------------------------*)
   (*                                                                    *)
   (*        ENTSTDNAMES STARTS HERE                                     *)
   (*                                                                    *)
   (*--------------------------------------------------------------------*)

      BEGIN (*ENTSTDNAMES*)

         (*FIRST INITIALIZE THE ARRAY OF NAMES*)

         (*CONSTANTS*)

         NA(.XTRUE    .)  := 'TRUE    ';   NA(.XMAXINT  .)  := 'MAXINT  ';
         NA(.XNIL     .)  := 'NIL     ';   NA(.XFALSE   .)  := 'FALSE   ';

         (*TYPES*)

         NA(.XCHAR    .)  := 'CHAR    ';   NA(.XBOOLEAN .)  := 'BOOLEAN ';
         NA(.XINTEGER .)  := 'INTEGER ';   NA(.XREAL    .)  := 'REAL    ';
         NA(.XTEXT    .)  := 'TEXT    ';

         (*FUNCTIONS*)

         NA(.XPOSITION.)  := 'POSITION';   NA(.XCOPY    .)  := 'COPY    ';
         NA(.XEOF     .)  := 'EOF     ';   NA(.XLENGTH  .)  := 'LENGTH  ';
         NA(.XORD     .)  := 'ORD     ';   NA(.XSQR     .)  := 'SQR     ';
         NA(.XTRUNC   .)  := 'TRUNC   ';   NA(.XARCTAN  .)  := 'ARCTAN  ';
         NA(.XCLOCK   .)  := 'CLOCK   ';   NA(.XDELETE  .)  := 'DELETE  ';
         NA(.XEXP     .)  := 'EXP     ';   NA(.XINSERT  .)  := 'INSERT  ';
         NA(.XSUCC    .)  := 'SUCC    ';   NA(.XABS     .)  := 'ABS     ';
         NA(.XCHR     .)  := 'CHR     ';   NA(.XCONCAT  .)  := 'CONCAT  ';
         NA(.XCOS     .)  := 'COS     ';   NA(.XEOLN    .)  := 'EOLN    ';
         NA(.XLN      .)  := 'LN      ';   NA(.XODD     .)  := 'ODD     ';
         NA(.XPOS     .)  := 'POS     ';   NA(.XPRED    .)  := 'PRED    ';
         NA(.XROUND   .)  := 'ROUND   ';   NA(.XSIN     .)  := 'SIN     ';
         NA(.XSQRT    .)  := 'SQRT    ';

         (*PROCEDURES*)

         NA(.XGET     .)  := 'GET     ';   NA(.XREWRITE .)  := 'REWRITE ';
         NA(.XUNPACK  .)  := 'UNPACK  ';   NA(.XREADLN  .)  := 'READLN  ';
         NA(.XWRITELN .)  := 'WRITELN ';   NA(.XPAGE    .)  := 'PAGE    ';
         NA(.XPUT     .)  := 'PUT     ';   NA(.XRELEASE .)  := 'RELEASE ';
         NA(.XWRITE   .)  := 'WRITE   ';   NA(.XDISPOSE .)  := 'DISPOSE ';
         NA(.XHALT    .)  := 'HALT    ';   NA(.XMARK    .)  := 'MARK    ';
         NA(.XNEW     .)  := 'NEW     ';   NA(.XPACK    .)  := 'PACK    ';
         NA(.XREAD    .)  := 'READ    ';   NA(.XRESET   .)  := 'RESET   ';


         (* NOW PUT THE STUFF IN THE HEAP IN SUCH AN ORDER AS TO KEEP THE *)
         (* TREE AS BALANCED AS POSSIBLE.                                 *)

         FOR N := XODD TO XDELETE DO
            ENTERPROC (N,FUNC);

         ENTERPROC (XREWRITE,PROC);

         ENTERTYPE (XTEXT,TEXTPTR);

         FOR N := XPUT TO XUNPACK DO
            ENTERPROC (N,PROC);

         ENTERTYPE (XCHAR,CHARPTR);
   (*    ENTERTYPE (XREAL,REALPTR);       COMMENTED UNTIL REALS ARE REAL*)

         NEW (CP,KONST);                  (*MAXINT*)
         WITH CP@ DO
            BEGIN
               NAME    := NA(.XMAXINT.);
               IDTYPE  := INT4PTR;
               NEXT    := NIL;
               NEW (VALUES.VALP,LINT);
               VALUES.VALP@.LINTVAL  := LINT4MAX;
               KLASS   := KONST
            END; (*WITH*)
         ENTERID (CP);

         FOR N := XPOS TO XSQRT DO
            ENTERPROC (N,FUNC);

         FOR N := XDISPOSE TO XWRITE DO
            ENTERPROC (N,PROC);

         ENTERTYPE (XINTEGER,INT4PTR);

         CPLAST  := NIL;
         FOR N := XFALSE TO XTRUE DO
            BEGIN
               NEW (CP,KONST);
               WITH CP@ DO
                  BEGIN
                     NAME    := NA(.N.);
                     IDTYPE  := BOOLPTR;
                     NEXT    := CPLAST;
                     IF N = XFALSE
                        THEN  VALUES.IVAL  := 0
                        ELSE  VALUES.IVAL  := 1;
                     KLASS   := KONST
                  END; (*WITH*)
               ENTERID (CP);
               CPLAST  := CP
            END; (*FOR*)
         BOOLPTR@.FCONST  := CPLAST;

         NEW (CP,KONST);                  (*NIL*)
         WITH CP@ DO
            BEGIN
               NAME         := NA(.XNIL.);
               IDTYPE       := NILPTR;
               NEXT         := NIL;
               VALUES.IVAL  := 0;
               KLASS        := KONST
            END; (*WITH*)
         ENTERID (CP);

         ENTERTYPE (XBOOLEAN,BOOLPTR);

         FOR N := XGET TO XWRITELN DO
            ENTERPROC (N,PROC);

         FOR N := XABS TO XTRUNC DO
            ENTERPROC (N,FUNC);

         (* NOW UP THE DISPLAY TO ALLOW REDEFINITION OF STD NAMES *)
         (* AT A GLOBAL LEVEL.                                    *)

         TOP  := TOP + 1;
         WITH DISPLAY(.TOP.) DO
            BEGIN
               FNAME  := NIL;
               FLABEL := NIL;
               OCCUR  := BLCK
            END (*WITH*)

      END; (*ENTSTDNAMES*)


     PROCEDURE ENTERUNDECL;
     BEGIN
       NEW(UTYPPTR,TYPES);
       WITH UTYPPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; KLASS := TYPES END;
       NEW(UCSTPTR,KONST);
       WITH UCSTPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; NEXT := NIL;
           VALUES.IVAL := 0; KLASS := KONST
         END;
       NEW(ULABPTR,LABELS);
       WITH ULABPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL;
           NEXT := NIL;  KLASS := LABELS
         END;
       NEW(UVARPTR,VARS);
       WITH UVARPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; VKIND := ACTUAL;
           EXTRNL := FALSE;
           NEXT := NIL; VLEV := 0; VADDR := LONGZERO; KLASS := VARS
         END;
       NEW(UFLDPTR,FIELD);
       WITH UFLDPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; NEXT := NIL; FLDADDR := 0;
           KLASS := FIELD
         END;
       NEW(UPRCPTR,PROC,DECLARED,ACTUAL);
       WITH UPRCPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; FORWDECL := FALSE;
           NEXT := NIL; (*EXTERN := FALSE;*) PFLEV := 0;
           PFNAME := 1;
           KLASS := PROC; PFDECKIND := DECLARED; PFKIND := ACTUAL
         END;
       NEW(UFCTPTR,FUNC,DECLARED,ACTUAL);
       WITH UFCTPTR@ DO
         BEGIN NAME := BLANKID; IDTYPE := NIL; NEXT := NIL;
           FORWDECL := FALSE; (*EXTERN := FALSE;*) PFLEV := 0;
           PFNAME := 1;
           KLASS := FUNC; PFDECKIND := DECLARED; PFKIND := ACTUAL
         END
     END (* ENTERUNDECL *) ;

     PROCEDURE INITSCALARS;
      VAR I: INTEGER;
      BEGIN FOR I := 1 TO IDLNGTH DO BLANKID(.I.) := ' ';
       FWPTR := NIL;

       NEW(CNSTVALPTR) ;
       NEW(CNSTSTRPTR) ;
       CNSTVALPTR@.SVAL:=CNSTSTRPTR;

       LIST   := TRUE;                DEBUG     := FALSE ;
       PLIST  := TRUE;                PRCODE    := TRUE;
       DP     := TRUE;                STANDARD  := FALSE;
       PRTERR := TRUE;

       ERRORS   := FALSE;       ERRORCOUNT :=0 ;
       WARNINGS := FALSE;       WARNCOUNT  :=0 ;
       ERRINX := 0;

       (* DEFAULTS FOR 32 BIT ADDRESSES, AND WORD (16 BITS) ALIGNED MACHINE *)
       ADDRSIZE := 2 * MACHINE;
       ALIGNMENT := MACHINE;

       ASSIGN  :=  FALSE  ;

       FEXTFILEP := NIL;
       GLOBFILELIST := NIL;
       STDINPUT := NIL;  STDOUTPUT := NIL;

       LOCN := 0; (* ADR. OF THE FIRST VARIABLE OF 'MAIN BLOCK' *)

       PKOUNTERS:=FALSE; KOUNTERS:=FALSE; PRINTKOUNT := FALSE;
       LABELEDKOUNT := TRUE; KOUNT := 1;

       OLDIC := 0;   IC := 0;

       EOL := FALSE;  CH := ' ';  LINEBUF(.0.) := ' ';

       DOUBLECHAR  := FALSE;

       GLOBTESTP := NIL;
       INTLABEL := 0;            PROCLAB := 0;

       ARITHMETICSIZE  := 'J';

       LONGZERO(.1.)  := 0;    LONGZERO(.2.)  := 0;
       LONGZERO(.3.)  := 0;    LONGZERO(.4.)  := 0;

       MAKELONG (-128,LINT1MIN);
       MAKELONG (127,LINT1MAX);
       MAKELONG (-32767 - 1,LINT2MIN);
       MAKELONG (32767,LINT2MAX);

       LINT4MIN       := LONGZERO;
       LINT4MIN(.4.)  := 128;

       LINT4MAX(.1.)   := 255;  LINT4MAX(.2.)   := 255;
       LINT4MAX(.3.)   := 255;  LINT4MAX(.4.)   := 127;

       MAKELONG (ORDMAXCHAR,LONGORDMAXCHAR);

       (*SET UP THE DEFAULT JUMP TABLE ADDRESS, JUMP TABLE SIZE,
         HEAP START ADDRESS, AND STACK START (TOP) ADDRESS       *)

       JUMPENTRIES      := 10;

       JUMPBASE         := LONGZERO;
       JUMPBASE(.2.)    := 48;

       HEAPSTART        := LINT4MAX;
       HEAPSTART(.4.)   := 255;

       STACKSTART       := LONGZERO;
       STACKSTART(.1.)  := 254;
       STACKSTART(.2.)  := 127;

       FOR I := 0 TO MAXLEVEL DO  STKSIZES(.I.)  := 0;

       LONGONLY       := FALSE;


      TOP := 0;
      LEVEL := 0;
      WITH DISPLAY(. 0 .) DO
         BEGIN
            FNAME := NIL;
            FLABEL := NIL;
            OCCUR := BLCK
         END;

      LASTERR := 0;
      LINECOUNT := 0;

      PAGENUM := 0;
      PAGELEN := PAGEDEFAULT;
      PAGEPOS := STARTPAGE;
      LINEWIDTH := WIDTHDEFAULT;
      PAGEEND := ENDOFPAGE;
      BLEV := 'A';
      HEADER := 'MOTOROLA PASCAL JUL 25, 1980 ';
      STARS := '**** ';
      ERRMES := '**ERROR--';
      EOFMESSAGE := '**** ERROR, END OF FILE ENCOUNTERED';
     END (* INITSCALARS *) ;

     PROCEDURE INITSETS;
     BEGIN
       CONSTBEGSYS    := (.ADDOP,INT1CONST,INT2CONST,INT4CONST,REALCONST,
                           STRINGCONST,IDENT.);
       SIMPTYPEBEGSYS := (.LPARENT.) + CONSTBEGSYS;
       TYPEBEGSYS     := (.ARROW,PACKEDSY,STRINGSY,ARRAYSY,RECORDSY,SETSY,FILESY
.)                       +SIMPTYPEBEGSYS;
       TYPEDELS       := (.STRINGSY,ARRAYSY,RECORDSY,SETSY,FILESY.);
       BLOCKBEGSYS    := (.LABELSY,CONSTSY,TYPESY,VARSY,PROCSY,FUNCSY,
                          BEGINSY.);
       SELECTSYS      := (.ARROW,PERIOD,LBRACK.);
       FACBEGSYS      := (.INT1CONST,INT2CONST,INT4CONST,REALCONST,STRINGCONST,
                          IDENT,LPARENT,LBRACK,NOTSY.);
       STATBEGSYS     := (.BEGINSY,GOTOSY,IFSY,WHILESY,REPEATSY,FORSY,WITHSY,
                          CASESY,EXITSY.);

       LOOPBEGSYS     := (.WHILESY,FORSY,REPEATSY.);

     END (* INITSETS *) ;

     PROCEDURE INITTABLES;
       PROCEDURE RESWORDS;
       BEGIN
         RW(. 1.):= 'IF      '; RW(. 2.):= 'DO      '; RW(. 3.):= 'OF      ';
         RW(. 4.):= 'TO      '; RW(. 5.):= 'IN      '; RW(. 6.):= 'OR      ';
         RW(. 7.):= 'END     '; RW(. 8.):= 'FOR     '; RW(. 9.):= 'VAR     ';
         RW(.10.):= 'DIV     '; RW(.11.):= 'MOD     '; RW(.12.):= 'SET     ';
         RW(.13.):= 'AND     '; RW(.14.):= 'NOT     '; RW(.15.):= 'THEN    ';
         RW(.16.):= 'ELSE    '; RW(.17.):= 'WITH    '; RW(.18.):= 'GOTO    ';
         RW(.19.):= 'CASE    '; RW(.20.):= 'TYPE    '; RW(.21.):= 'EXIT    ';
         RW(.22.):= 'FILE    '; RW(.23.):= 'BEGIN   ';
         RW(.24.):= 'UNTIL   '; RW(.25.):= 'WHILE   '; RW(.26.):= 'ARRAY   ';
         RW(.27.):= 'CONST   '; RW(.28.):= 'LABEL   ';
         RW(.29.):= 'REPEAT  '; RW(.30.):= 'RECORD  '; RW(.31.):= 'DOWNTO  ';
         RW(.32.):= 'PACKED  '; RW(.33.):= 'ORIGIN  '; RW(.34.):= 'STRING  ';
         RW(.35.):= 'FORWARD ';
         RW(.36.):= 'PROGRAM '; RW(.37.):= 'FUNCTION'; RW(.38.):= 'PROCEDUR';
         RW(.39.):= 'OTHERWIS'; RW(.40.):= 'SUBPROGR';

         FRW(.1.)  :=  1; FRW(.2.)  :=  1; FRW(.3.)  :=  7; FRW(.4.) := 15;
         FRW(.5.)  := 23; FRW(.6.)  := 29; FRW(.7.)  := 35; FRW(.8.) := 37;
         FRW(.9.)  := NEXTRESWD; FRW(.10.) := NEXTRESWD;
         FRW(.11.) := NEXTRESWD; FRW(.12.) := NEXTRESWD; FRW(.13.):= NEXTRESWD;
       END (* RESWORDS *) ;

       PROCEDURE SYMBOLS;
       VAR C: CHAR;
       BEGIN
         RSY(.1.)  := IFSY;     RSY(.2.)  := DOSY;        RSY(.3.)  := OFSY;
         RSY(.4.)  := TOSY;     RSY(.5.)  := RELOP;       RSY(.6.)  := ADDOP;
         RSY(.7.)  := ENDSY;    RSY(.8.)  := FORSY;       RSY(.9.)  := VARSY;
         RSY(.10.) := MULOP;    RSY(.11.) := MULOP;       RSY(.12.) := SETSY;
         RSY(.13.) := MULOP;    RSY(.14.) := NOTSY;       RSY(.15.) := THENSY;
         RSY(.16.) := ELSESY;   RSY(.17.) := WITHSY;      RSY(.18.) := GOTOSY;
         RSY(.19.) := CASESY;   RSY(.20.) := TYPESY;      RSY(.21.) := EXITSY;
         RSY(.22.) := FILESY;
         RSY(.23.) := BEGINSY;  RSY(.24.) := UNTILSY;     RSY(.25.) := WHILESY;
         RSY(.26.) := ARRAYSY;  RSY(.27.) := CONSTSY;     RSY(.28.) := LABELSY;
         RSY(.29.) := REPEATSY; RSY(.30.) := RECORDSY;    RSY(.31.) := DOWNTOSY;
         RSY(.32.) := PACKEDSY; RSY(.33.) := ORIGINSY;    RSY(.34.) := STRINGSY;
         RSY(.35.) := FORWARDSY;
         RSY(.36.) := PROGSY;   RSY(.37.) := FUNCSY;      RSY(.38.) := PROCSY;
         RSY(.39.) := OTHERWZSY;RSY(.40.) := SUBPROGSY;

   (*PP*)FOR C := CHR(0) TO CHR(ORDMAXBASECHAR) DO SSY(.C.) := OTHERSY;
                               (*POSSIBLE PORTABILITY PROBLEM WITH "127"*)

         SSY(.'+'.) := ADDOP;   SSY(.'-'.) := ADDOP;   SSY(.'*'.) := MULOP;
         SSY(.'/'.) := MULOP;   SSY(.'('.) := LPARENT; SSY(.')'.) := RPARENT;
         SSY(.'='.) := RELOP;   SSY(.','.) := COMMA;   SSY(.'.'.) := PERIOD;
         SSY(.':'.) := COLON;
         SSY(.'Æ'.) := LBRACK;  SSY(.'Å'.) := RBRACK;  SSY(.'!'.) := ARROW;
         SSY(.'!'.) := ADDOP ;  SSY(.'&'.) := MULOP ;
         SSY(.'ü'.) := NOTSY;   SSY(.'<'.) := RELOP;   SSY(.'>'.) := RELOP;
         SSY(.'@'.) := ARROW;   SSY(.';'.) := SEMICOLON;
       END (* SYMBOLS *) ;

       PROCEDURE RATORS;
         VAR I: INTEGER;  C: CHAR;
       BEGIN
         FOR I := 1 TO LASTRESWD (* NR OF RES WORDS *) DO ROP(.I.) := NOOP;
         ROP(.5.) := INOP; ROP(.10.) := IDIV; ROP(.11.) := IMOD;
         ROP(.6.) := OROP; ROP(.13.) := ANDOP;
   (*PP*)FOR C := CHR(0) TO CHR(ORDMAXBASECHAR) DO SOP(.C.) := NOOP;
                               (*POSSIBLE PORTABILITY PROBLEM WITH "127"*)
         SOP(.'+'.) := PLUS;   SOP(.'-'.) := MINUS; SOP(.'*'.) := MUL;
         SOP(.'='.) := EQOP;   SOP(.'/'.) := RDIV;
         SOP(.'<'.) := LTOP;   SOP(.'>'.) := GTOP;
         SOP(.'ø'.) := OROP;   SOP(.'&'.) := ANDOP;
   (*PP*)SOP(.'Æ'.) := NOOP;   SOP(.'Å'.) := NOOP;

         (*  INITIALIZE CHARACTER TABLE FOR INSYMBOL  *)

   (*PP*)FOR C := CHR(0) TO CHR(ORDMAXBASECHAR) DO CHTAB(.C.) := ILLEGALCHAR;
                               (*POSSIBLE PORTABILITY PROBLEM WITH "127"*)
         FOR C := 'a' TO 'z' DO CHTAB(.C.) := ATOZ;
         FOR C := 'A' TO 'Z' DO CHTAB(.C.) := ATOZ;
         FOR C := '0' TO '9' DO CHTAB(.C.) := NUMBER;

         CHTAB(.'_'.) := ATOZ; CHTAB(. '$' .) := ATOZ;

         CHTAB(.'*'.) := MISCCHAR;    CHTAB(.'+'.) := MISCCHAR;
         CHTAB(.'-'.) := MISCCHAR;    CHTAB(.'='.) := MISCCHAR;
         CHTAB(.'/'.) := MISCCHAR;    CHTAB(.')'.) := MISCCHAR;
         CHTAB(.'&'.) := MISCCHAR;    CHTAB(.'@'.) := MISCCHAR;
         CHTAB(.','.) := MISCCHAR;    CHTAB(.';'.) := MISCCHAR;
   (*PP*)CHTAB(.'Æ'.) := MISCCHAR;    CHTAB(.'Å'.) := MISCCHAR;
   (*PP*)CHTAB(.'æ'.) := CMNTBRACK;   CHTAB(.'!'.) := MISCCHAR;
         CHTAB(.':'.) := COLONCHAR;
         CHTAB(.'.'.) := PERIODCHAR;  CHTAB(.''''.):= STRQUOTE;
         CHTAB(.'<'.) := LPOINTY;     CHTAB(.'>'.) := RPOINTY;
         CHTAB(.'('.) := LPARN;
         CHTAB(.' '.) := BLANKCHAR;   CHTAB(.CHR(9).) := BLANKCHAR; (* TAB CHAR
*)
         (*  INITIALIZE ASCII TABLE FOR CASESTATEMENT, ETC. *)

   (*PP*)FOR C := CHR(0) TO CHR(ORDMAXBASECHAR) DO ASCII(.C.) := 95 (*UNDERLINE*
);                             (*POSSIBLE PORTABILITY PROBLEM WITH "127"*)
       ASCII(.'a'.):= 97; ASCII(.'b'.):= 98; ASCII(.'c'.):= 99; ASCII(.'d'.):=10
0;     ASCII(.'e'.):=101; ASCII(.'f'.):=102; ASCII(.'g'.):=103; ASCII(.'h'.):=10
4;     ASCII(.'i'.):=105; ASCII(.'j'.):=106; ASCII(.'k'.):=107; ASCII(.'l'.):=01
8;     ASCII(.'m'.):=109; ASCII(.'n'.):=110; ASCII(.'o'.):=111; ASCII(.'p'.):=11
2;     ASCII(.'q'.):=113; ASCII(.'r'.):=114; ASCII(.'s'.):=115; ASCII(.'t'.):=11
6;     ASCII(.'u'.):=117; ASCII(.'v'.):=118; ASCII(.'w'.):=119; ASCII(.'x'.):=12
0;     ASCII(.'y'.):=121; ASCII(.'z'.):=122; ASCII(.'A'.):= 65; ASCII(.'B'.):= 6
6;     ASCII(.'C'.):= 67; ASCII(.'D'.):= 68; ASCII(.'E'.):= 69; ASCII(.'F'.):= 7
0;     ASCII(.'G'.):= 71; ASCII(.'H'.):= 72; ASCII(.'I'.):= 73; ASCII(.'J'.):= 7
4;     ASCII(.'K'.):= 75; ASCII(.'L'.):= 76; ASCII(.'M'.):= 77; ASCII(.'N'.):= 7
8;     ASCII(.'O'.):= 79; ASCII(.'P'.):= 80; ASCII(.'Q'.):= 81; ASCII(.'R'.):= 8
2;     ASCII(.'S'.):= 83; ASCII(.'T'.):= 84; ASCII(.'U'.):= 85; ASCII(.'V'.):= 8
6;     ASCII(.'W'.):= 87; ASCII(.'X'.):= 88; ASCII(.'Y'.):= 89; ASCII(.'Z'.):= 9
0;     ASCII(.'0'.):= 48; ASCII(.'1'.):= 49; ASCII(.'2'.):= 50; ASCII(.'3'.):= 5
1;     ASCII(.'4'.):= 52; ASCII(.'5'.):= 53; ASCII(.'6'.):= 54; ASCII(.'7'.):= 5
5;     ASCII(.'8'.):= 56; ASCII(.'9'.):= 57;

       ASCII(.' '.) := 32;        ASCII(.'*'.) := 42;        ASCII(.'>'.) := 62;
       ASCII(.'!'.) := 33;        ASCII(.'+'.) := 43;        ASCII(.'?'.) := 63;
       ASCII(.'"'.) := 34;        ASCII(.','.) := 44;        ASCII(.'@'.) := 64;
       ASCII(.'#'.) := 35;        ASCII(.'-'.) := 45;        ASCII(.'Æ'.) := 91;
       ASCII(.'$'.) := 36;        ASCII(.'.'.) := 46;        ASCII(.'Ø'.) := 92;
       ASCII(.'%'.) := 37;        ASCII(.'/'.) := 47;        ASCII(.'Å'.) := 93;
       ASCII(.'&'.) := 38;        ASCII(.':'.) := 58;        ASCII(.'!'.) := 94;
       ASCII(.''''.):= 39;        ASCII(.';'.) := 59;        ASCII(.'_'.) := 95;
       ASCII(.'('.) := 40;        ASCII(.'<'.) := 60;        ASCII(.'`'.) := 96;
       ASCII(.')'.) := 41;        ASCII(.'='.) := 61;
       (* POTENTIAL PORTABILITY PROBLEM WITH THE FOLLOWING CHARACTERS ON A
          EBCDIC MACHINE *)
       ASCII(.'æ'.) := 123;       ASCII(.'ø'.) := 124;       ASCII(.'å'.) := 125
;      ASCII(.'^'.) := 126;

       END (* RATORS *) ;

       PROCEDURE INSTRMNEMONICS;
       BEGIN

       MN(. 0.) :='AB  ';MN(. 1.) :='AD  ';MN(. 2.) :='AFI ';MN(. 3.) :='AND ';
       MN(. 4.) :='AST ';MN(. 5.) :='ATN ';MN(. 6.) :='CHK ';MN(. 7.) :='CLO ';
       MN(. 8.) :='COS ';MN(. 9.) :='CSP ';MN(.10.) :='CSPF';MN(.11.) :='CUP ';
       MN(.12.) :='CUPF';MN(.13.) :='CVT ';MN(.14.) :='CVB ';MN(.15.) :='DAS ';
       MN(.16.) :='DEC ';MN(.17.) :='DEF ';MN(.18.) :='DIF ';MN(.19.) :='DIS ';
       MN(.20.) :='DV  ';MN(.21.) :='ENT ';MN(.22.) :='ENTB';MN(.23.) :='EOF ';
       MN(.24.) :='EOL ';MN(.25.) :='EQU ';MN(.26.) :='EXIT';MN(.27.) :='EXP ';
       MN(.28.) :='EXT ';MN(.29.) :='FJP ';MN(.30.) :='GEQ ';MN(.31.) :='GET ';
       MN(.32.) :='GRT ';MN(.33.) :='IFD ';MN(.34.) :='INC ';MN(.35.) :='IND ';
       MN(.36.) :='INN ';MN(.37.) :='INS ';MN(.38.) :='INT ';MN(.39.) :='IOR ';
       MN(.40.) :='ISC ';MN(.41.) :='IXA ';MN(.42.) :='LAB ';MN(.43.) :='LCA ';
       MN(.44.) :='LDA ';MN(.45.) :='LDC ';MN(.46.) :='LEQ ';MN(.47.) :='LES ';
       MN(.48.) :='LOD ';MN(.49.) :='LOG ';MN(.50.) :='LSC ';MN(.51.) :='LSPA';
       MN(.52.) :='LTA ';MN(.53.) :='LUPA';MN(.54.) :='MOD ';MN(.55.) :='MOV ';
       MN(.56.) :='MOVV';MN(.57.) :='MP  ';MN(.58.) :='MRK ';MN(.59.) :='NEQ ';
       MN(.60.) :='NEW ';MN(.61.) :='NG  ';MN(.62.) :='NOT ';MN(.63.) :='ODD ';
       MN(.64.) :='PAG ';MN(.65.) :='PEE ';MN(.66.) :='POS ';MN(.67.) :='POK ';
       MN(.68.) :='PUT ';MN(.69.) :='RDB ';MN(.70.) :='RDC ';MN(.71.) :='RDE ';
       MN(.72.) :='RDI ';MN(.73.) :='RDJ ';MN(.74.) :='RDQ ';MN(.75.) :='RDR ';
       MN(.76.) :='RDS ';MN(.77.) :='RET ';MN(.78.) :='RLN ';MN(.79.) :='RLS ';
       MN(.80.) :='RST ';MN(.81.) :='RWT ';MN(.82.) :='SB  ';MN(.83.) :='SCON';
       MN(.84.) :='SCOP';MN(.85.) :='SDEL';MN(.86.) :='SEE ';MN(.87.) :='SGS ';
       MN(.88.) :='SIN ';MN(.89.) :='SINS';MN(.90.) :='SLEN';MN(.91.) :='SPOS';
       MN(.92.) :='SQR ';MN(.93.) :='SQT ';MN(.94.) :='STO ';MN(.95.) :='STP ';
       MN(.96.) :='STR ';MN(.97.) :='TRC ';MN(.98.) :='UJP ';MN(.99.) :='UNI ';
       MN(.100.):='WLN ';MN(.101.):='WRB ';MN(.102.):='WRC ';MN(.103.):='WRE ';
       MN(.104.):='WRI ';MN(.105.):='WRJ ';MN(.106.):='WRQ ';MN(.107.):='WRR ';
       MN(.108.):='WRS ';MN(.109.):='XJP ';MN(.110.):='RND ';MN(.111.):='EIO ';
       MN(.112.):='MST ';MN(.113.):='VJP ';MN(.114.):='RDV ';MN(.115.):='WRV ';
       MN(.116.):='ARG ';MN(.117.):='RDH ';MN(.118.):='WRH ';
                                 (*IF MN GETS BIGGER CHANGE TYPE "MNRANGE"*)
       END (* INSTRMNEMONICS *) ;


       PROCEDURE UPPERCASE;     (* FOR INSYMBOL TO CONVERT TO UPPERCASE
                                  INTERNAL FORM OF IDENTIFIERS *)
           VAR C: CHAR;
           BEGIN
   (*PP*)     FOR C := CHR(0) TO CHR(ORDMAXBASECHAR) DO UPPER(.C.) := C;
   (*PP*)     FOR C := 'a' TO 'z' DO UPPER(.C.) := CHR(ORD(C)-ORD('a')+ORD('A'))
;          END;


     BEGIN (* INITTABLES *)
       RESWORDS;
       SYMBOLS;
       RATORS;
       INSTRMNEMONICS;
       UPPERCASE;
     END (* INITTABLES *) ;

   BEGIN  (* **START** PASCALCOMPILER *)
      WRITELN(OUTPUT,' MOTOROLA PASCAL COMPILER VERSION ', VERSION);
      WRITELN(OUTPUT,' COPYRIGHTED 1980 BY MOTOROLA, INC.');

      INITSCALARS;           (* INITIALIZE GLOBAL SCALARS *)
      INITSETS;              (* INITIALIZE GLOBAL SETS    *)
      INITTABLES;            (* INITIALIZE GLOBAL TABLES  *)

      ENTERSTDTYPES;         (* INITIALIZE HEAP WITH STANDARD TYPES *)
      ENTSTDNAMES;           (* INITIALIZE HEAP WITH STANDARD NAMES *)
      ENTERUNDECL;           (* INITIALIZE HEAP WITH UNDECLARED DEFAULTS *)

      RESET(SOURCE);
      REWRITE(PCODE);
      REWRITE(LISTING);

      NEWPAGE;
      WRITELN(PCODE,'.',HEADER);

      READLINE;

      INSYMBOL;              (* GET FIRST SYMBOL *)

      PROGRAMME(BLOCKBEGSYS + STATBEGSYS - (. CASESY .));

      (* SUMMERIZE COMPILATION *)

      IF PAGEEND - PAGEPOS < 9 THEN NEWPAGE;

      WRITELN(LISTING,' ');
      WRITELN(LISTING,' ');

      WRITE(LISTING, STARS:15);
      IF ERRORCOUNT = 0 THEN
         WRITE(LISTING,'NO')
      ELSE
         WRITE(LISTING,ERRORCOUNT:0);
      WRITE(LISTING,'ERROR(S) AND ':14);
      IF WARNCOUNT = 0 THEN
         WRITE(LISTING,'NO')
      ELSE
         WRITE(LISTING,WARNCOUNT:0);
      WRITELN(LISTING,'WARNING(S) DETECTED':20);
      WRITELN(LISTING,' ');

      IF (ERRORCOUNT <> 0) OR (WARNCOUNT <> 0) THEN
         BEGIN
            WRITELN(LISTING, STARS:15,'LAST ERROR LINE WAS ', LASTERR:0);
            WRITELN(LISTING,' ')
         END;

      WRITE(LISTING, STARS:15,LINECOUNT:0,'LINES ':7);
      WRITELN(LISTING, PROCLAB:0,'PROCEDURES':11);
      WRITELN(LISTING,' ');

      WRITELN(LISTING, STARS:15,OLDIC:0, 'PCODE INSTRUCTIONS':19);

      WRITELN(OUTPUT,' ');
      WRITE(OUTPUT, STARS:6);
      IF ERRORCOUNT = 0 THEN
         WRITE(OUTPUT,'NO')
      ELSE
         WRITE(OUTPUT,ERRORCOUNT:0);
      WRITELN(OUTPUT,'ERROR(S) DETECTED IN COMPILATION ****':38)
   END.
   ▶EOF◀