Annotation of researchv10no/cmd/spitbol/spitv35.src, revision 1.1.1.1

1.1       root        1:        #title  s p i t b o l - revision history
                      2:        #page   
                      3: #      R E V I S I O N   H I S T O R Y
                      4: #      -------------------------------
                      5: #
                      6: #
                      7: #      VERSION 3.5B (FEB 81... - SGD PATCHES)
                      8: #      -----------------------------------
                      9: #
                     10: #      SGD03 - ADDITION OF .CNCI AND SYSCI (INT->STRING
                     11: #              SYSTEM ROUTINE OPTION)
                     12: #      SGD04 - (06-MAY-1981) MODIFIED INILN TO 132
                     13: #      SGD05 - (13-MAY-1981) INSERTED MISSING WTB AFTER SYSMM
                     14: #              CALLS
                     15: #      SGD06 - (25-MAY-1981) MERGED IN PROFILER PATCHES
                     16: #              (NOT MARKED)
                     17: #      SGD07 - (25-MAY-1981) MUCHO PATCHES TO PROFILER (MARKED,
                     18: #              BUT BEST JUST TO EXTRACT ENMASSE)
                     19: #      SGD08 - (25-MAY-1981) USE STRING LENGTH IN HASHS
                     20: #      SGD09 - (25-MAY-1981) FIXED SERIOUS PARSER PROBLEM
                     21: #              RELATING TO (X Y) ON LINE BEING VIEWED AS PATTERN
                     22: #              MATCH.  FIXED BY ADDITION OF NEW CMTYP VALUE
                     23: #              C$CNP (CONCATENATION - NOT PATTERN MATCH)
                     24: #      SGD10 - (01-AUG-1981) FIXED EXIT(N) RESPECIFICATION CODE
                     25: #              TO PROPERLY OBSERVE HEADER SEMANTICS ON RETURN.
                     26: #      SGD11 - (07-AUG-1981) BYPASS PRTPG CALL AT INITIALIZATION
                     27: #              FOLLOWING COMPILATION IF NO OUTPUT GENERATED.
                     28: #              THIS PREVENTS OUTPUT FILES CONSISTING OF THE
                     29: #              HEADERS AND A FEW BLANK LINES WHEN THERE IS NO
                     30: #              SOURCE LISTING AND NO COMPILATION STATS.
                     31: #              ALSO FIX TIMSX INITIALIZATION IN SAME CODE.
                     32: #      SGD12 - (17-AUG-1981) B$EFC CODE DID NOT CHECK FOR
                     33: #              UNCONVERTED RESULT RETURNING NULL STRING.  FIXED.
                     34: #      SGDBF - (   NOV-1981) ADDED BUFFER TYPE AND SYMBOL CNBF
                     35: #      SGD13 - (03-MAR-1982) LOAD PFVBL FIELD IN RETRN FOR
                     36: #              RETURN TRACING. THIS WAS CAUSING BUG ON RETURN
                     37: #              TRACES THAT TRIED TO ACCESS THE VARIABLE NAME
                     38: #      SGD14 - ADDED CHAR FUNCTION.  CHAR(N) RETURNS NTH
                     39: #              CHARACTER OF HOST MACHINE CHARACTER SET.
                     40: #              NOT CONDITIONALIZED OR MARKED.
                     41: #      SGD15 - FIXED PROBLEM RELATING TO COMPILATION OF GOTO
                     42: #              FIELDS CONTAINING SMALL INTEGERS (IN CONST SEC).
                     43: #
                     44: #      REG01 - (XX-AUG-82)
                     45: #              ADDED CFP$U TO EASE TRANSLATION ON SMALLER
                     46: #              SYSTEMS                  - CONDITIONAL .CUCF
                     47: #              ADDED LOWER CASE SUPPORT - CONDITIONAL .CULC
                     48: #              ADDED SET I/O FUNCTION   - CONDITIONAL .CUST
                     49: #
                     50: #      REG02 - (XX-SEP-82)
                     51: #              CHANGED INILN AND AND INILS TO 258
                     52: #
                     53: #      REG03 - (XX-OCT-82)
                     54: #              CONDITIONALIZED THE PAGE EJECT AFTER CALL TO SYSBX
                     55: #              AND ADDED ANOTHER BEFORE CALL TO SYSBX, SO THAT,
                     56: #              IF DESIRED BY THE IMPLEMENTOR, STANDARD OUTPUT
                     57: #              WILL REFLECT ASSIGNMENTS MADE BY EXECUTING PROGRAM
                     58: #              ONLY. CONDITIONAL .CUEJ CONTROLS - IF DEFINED
                     59: #              EJECT IS BEFORE CALL TO SYSBX.
                     60: #
                     61: #      REG04 - (XX-NOV-82)
                     62: #              FIXED DIFFICULTIES WITH LISTINGS DURING EXECUTION
                     63: #              WHEN NO LISTING GENERATED DURING COMPILATION.
                     64: #
                     65: #              -LIST TO CODE() CAUSED BOMB. FIX IS TO RESET
                     66: #              R$TTL AND R$STL TO NULLS NOT 0 AFTER COMPILATION.
                     67: #              (LISTR AND LISTT EXPECT NULLS)
                     68: #
                     69: #              WHEN LISTING AND STATISTICS ROUTED TO DIFFERENT
                     70: #              FILE THAN EXECUTION OUTPUT, ERROR MESSAGE IS SENT
                     71: #              TO EXECUTION OUTPUT (AND GETS SEPARATED FROM
                     72: #              ... IN STATEMENT ... MSG). LABO1 CALLS SYSAX AND
                     73: #              STOPR DOES NOT CALL SYSAX IF ENTERED FROM LABO1.
                     74: #
                     75: #      REG05 - (XX-NOV-82)
                     76: #              PREVENT CLEAR() FROM CLOBBERING PROTECTED VARIABLES
                     77: #              AT LABEL SCLR5.
                     78: #
                     79: #      REG06 - (XX-NOV-82)
                     80: #              FIXED GTEXP FROM ACCEPTING TRAILING SEMICOLON OR
                     81: #              COLON. NOT LEGAL WAY TO END AN EXPRESSION.
                     82: #
                     83: #      VERSION 3.5A (OCT 79 - SGD PATCHES)
                     84: #      -----------------------------------
                     85: #
                     86: #      SGD01 - PATCH IN ASIGN TO FIX MULTIPLE TRAP BLOCK PROBLEM
                     87: #              (ASG10+2)
                     88: #      SGD02 - PATCH IN GTARR TO FIX NULL CONVERT (GTAR9+0)
                     89: #
                     90:        #title  s p i t b o l  -- basic information
                     91:        #page   
                     92: #
                     93: #      GENERAL STRUCTURE
                     94: #      -----------------
                     95: #
                     96: #      THIS PROGRAM IS A TRANSLATOR FOR A VERSION OF THE SNOBOL4
                     97: #      PROGRAMMING LANGUAGE. LANGUAGE DETAILS ARE CONTAINED IN
                     98: #      THE MANUAL MACRO SPITBOL BY DEWAR AND MCCANN, TECHNICAL
                     99: #      REPORT 90, UNIVERSITY OF LEEDS 1976.  THE LANGUAGE
                    100: #      IS IDENTICAL TO THAT IMPLEMENTED BY THE BTL TRANSLATOR
                    101: #      (R. E. GRISWOLD ET AL.) WITH THE FOLLOWING EXCEPTIONS.
                    102: #
                    103: #      1)   REDEFINITION OF STANDARD SYSTEM FUNCTIONS AND
                    104: #           OPERATORS IS NOT PERMITTED.
                    105: #
                    106: #      2)   THE VALUE FUNCTION IS NOT PROVIDED.
                    107: #
                    108: #      3)   ACCESS TRACING IS PROVIDED IN ADDITION TO THE
                    109: #           OTHER STANDARD TRACE MODES.
                    110: #
                    111: #      4)   THE KEYWORD STFCOUNT IS NOT PROVIDED.
                    112: #
                    113: #      5)   THE KEYWORD FULLSCAN IS NOT PROVIDED AND ALL PATTERN
                    114: #           MATCHING TAKES PLACE IN FULLSCAN MODE (I.E. WITH NO
                    115: #           HEURISTICS APPLIED).
                    116: #
                    117: #      6)   A SERIES OF EXPRESSIONS SEPARATED BY COMMAS MAY
                    118: #           BE GROUPED WITHIN PARENTHESES TO PROVIDE A SELECTION
                    119: #           CAPABILITY. THE SEMANTICS ARE THAT THE SELECTION
                    120: #           ASSUMES THE VALUE OF THE FIRST EXPRESSION WITHIN IT
                    121: #           WHICH SUCCEEDS AS THEY ARE EVALUATED FROM THE LEFT.
                    122: #           IF NO EXPRESSION SUCCEEDS THE ENTIRE STATEMENT FAILS
                    123: #
                    124: #      7)   AN EXPLICIT PATTERN MATCHING OPERATOR IS PROVIDED.
                    125: #           THIS IS THE BINARY QUERY (SEE GIMPEL SIGPLAN OCT 74)
                    126: #
                    127: #      8)   THE ASSIGNMENT OPERATOR IS INTRODUCED AS IN THE
                    128: #           GIMPEL REFERENCE.
                    129: #
                    130: #      9)   THE EXIT FUNCTION IS PROVIDED FOR GENERATING LOAD
                    131: #           MODULES - CF. GIMPELS SITBOL.
                    132: #
                    133: #
                    134: #      THE METHOD USED IN THIS PROGRAM IS TO TRANSLATE THE
                    135: #      SOURCE CODE INTO AN INTERNAL PSEUDO-CODE (SEE FOLLOWING
                    136: #      SECTION). AN INTERPRETOR IS THEN USED TO EXECUTE THIS
                    137: #      GENERATED PSEUDO-CODE. THE NATURE OF THE SNOBOL4 LANGUAGE
                    138: #      IS SUCH THAT THE LATTER TASK IS MUCH MORE COMPLEX THAN
                    139: #      THE ACTUAL TRANSLATION PHASE. ACCORDINGLY, NEARLY ALL THE
                    140: #      CODE IN THE PROGRAM SECTION IS CONCERNED WITH THE ACTUAL
                    141: #      EXECUTION OF THE SNOBOL4 PROGRAM.
                    142:        #page   
                    143: #
                    144: #      INTERPRETIVE CODE FORMAT
                    145: #      ------------------------
                    146: #
                    147: #      THE INTERPRETIVE PSEUDO-CODE CONSISTS OF A SERIES OF
                    148: #      ADDRESS POINTERS. THE EXACT FORMAT OF THE CODE IS
                    149: #      DESCRIBED IN CONNECTION WITH THE CDBLK FORMAT. THE
                    150: #      PURPOSE OF THIS SECTION IS TO GIVE GENERAL INSIGHT INTO
                    151: #      THE INTERPRETIVE APPROACH INVOLVED.
                    152: #
                    153: #      THE BASIC FORM OF THE CODE IS RELATED TO REVERSE POLISH.
                    154: #      IN OTHER WORDS, THE OPERANDS PRECEDE THE OPERATORS WHICH
                    155: #      ARE ZERO ADDRESS OPERATORS. THERE ARE SOME EXCEPTIONS TO
                    156: #      THESE RULES, NOTABLY THE UNARY NOT OPERATOR AND THE
                    157: #      SELECTION CONSTRUCTION WHICH CLEARLY REQUIRE ADVANCE
                    158: #      KNOWLEDGE OF THE OPERATOR INVOLVED.
                    159: #
                    160: #      THE OPERANDS ARE MOVED TO THE TOP OF THE MAIN STACK AND
                    161: #      THE OPERATORS ARE APPLIED TO THE TOP STACK ENTRIES. LIKE
                    162: #      OTHER VERSIONS OF SPITBOL, THIS PROCESSOR DEPENDS ON
                    163: #      KNOWING WHETHER OPERANDS ARE REQUIRED BY NAME OR BY VALUE
                    164: #      AND MOVES THE APPROPRIATE OBJECT TO THE STACK. THUS NO
                    165: #      NAME/VALUE CHECKS ARE INCLUDED IN THE OPERATOR CIRCUITS.
                    166: #
                    167: #      THE ACTUAL POINTERS IN THE CODE POINT TO A BLOCK WHOSE
                    168: #      FIRST WORD IS THE ADDRESS OF THE INTERPRETOR ROUTINE
                    169: #      TO BE EXECUTED FOR THE CODE WORD.
                    170: #
                    171: #      IN THE CASE OF OPERATORS, THE POINTER IS TO A WORD WHICH
                    172: #      CONTAINS THE ADDRESS OF THE OPERATOR TO BE EXECUTED. IN
                    173: #      THE CASE OF OPERANDS SUCH AS CONSTANTS, THE POINTER IS TO
                    174: #      THE OPERAND ITSELF. ACCORDINGLY, ALL OPERANDS CONTAIN
                    175: #      A FIELD WHICH POINTS TO THE ROUTINE TO LOAD THE VALUE OF
                    176: #      THE OPERAND ONTO THE STACK. IN THE CASE OF A VARIABLE,
                    177: #      THERE ARE THREE SUCH POINTERS. ONE TO LOAD THE VALUE,
                    178: #      ONE TO STORE THE VALUE AND A THIRD TO JUMP TO THE LABEL.
                    179: #
                    180: #      THE HANDLING OF FAILURE RETURNS DESERVES SPECIAL COMMENT.
                    181: #      THE LOCATION FLPTR CONTAINS THE POINTER TO THE LOCATION
                    182: #      ON THE MAIN STACK WHICH CONTAINS THE FAILURE RETURN
                    183: #      WHICH IS IN THE FORM OF A BYTE OFFSET IN THE CURRENT
                    184: #      CODE BLOCK (CDBLK OR EXBLK). WHEN A FAILURE OCCURS, THE
                    185: #      STACK IS POPPED AS INDICATED BY THE SETTING OF FLPTR AND
                    186: #      CONTROL IS PASSED TO THE APPROPRIATE LOCATION IN THE
                    187: #      CURRENT CODE BLOCK WITH THE STACK POINTER POINTING TO THE
                    188: #      FAILURE OFFSET ON THE STACK AND FLPTR UNCHANGED.
                    189:        #page   
                    190: #
                    191: #      INTERNAL DATA REPRESENTATIONS
                    192: #      -----------------------------
                    193: #
                    194: #      REPRESENTATION OF VALUES
                    195: #
                    196: #      A VALUE IS REPRESENTED BY A POINTER TO A BLOCK WHICH
                    197: #      DESCRIBES THE TYPE AND PARTICULARS OF THE DATA VALUE.
                    198: #      IN GENERAL, A VARIABLE IS A LOCATION CONTAINING SUCH A
                    199: #      POINTER (ALTHOUGH IN THE CASE OF TRACE ASSOCIATIONS THIS
                    200: #      IS MODIFIED, SEE DESCRIPTION OF TRBLK).
                    201: #
                    202: #      THE FOLLOWING IS A LIST OF POSSIBLE DATATYPES SHOWING THE
                    203: #      TYPE OF BLOCK USED TO HOLD THE VALUE. THE DETAILS OF
                    204: #      EACH BLOCK FORMAT ARE GIVEN LATER.
                    205: #
                    206: #      DATATYPE              BLOCK TYPE
                    207: #      --------              ----------
                    208: #
                    209: #
                    210: #      ARRAY                 ARBLK OR VCBLK
                    211: #
                    212: #      CODE                  CDBLK
                    213: #
                    214: #      EXPRESSION            EXBLK OR SEBLK
                    215: #
                    216: #      INTEGER               ICBLK
                    217: #
                    218: #      NAME                  NMBLK
                    219: #
                    220: #      PATTERN               P0BLK OR P1BLK OR P2BLK
                    221: #
                    222: #      REAL                  RCBLK
                    223: #
                    224: #      STRING                SCBLK
                    225: #
                    226: #      TABLE                 TBBLK
                    227: #
                    228: #      PROGRAM DATATYPE      PDBLK
                    229:        #page   
                    230: #
                    231: #      REPRESENTATION OF VARIABLES
                    232: #      ---------------------------
                    233: #
                    234: #      DURING THE COURSE OF EVALUATING EXPRESSIONS, IT IS
                    235: #      NECESSARY TO GENERATE NAMES OF VARIABLES (FOR EXAMPLE
                    236: #      ON THE LEFT SIDE OF A BINARY EQUALS OPERATOR). THESE ARE
                    237: #      NOT TO BE CONFUSED WITH OBJECTS OF DATATYPE NAME WHICH
                    238: #      ARE IN FACT VALUES.
                    239: #
                    240: #      FROM A LOGICAL POINT OF VIEW, SUCH NAMES COULD BE SIMPLY
                    241: #      REPRESENTED BY A POINTER TO THE APPROPRIATE VALUE CELL.
                    242: #      HOWEVER IN THE CASE OF ARRAYS AND PROGRAM DEFINED
                    243: #      DATATYPES, THIS WOULD VIOLATE THE RULE THAT THERE MUST BE
                    244: #      NO POINTERS INTO THE MIDDLE OF A BLOCK IN DYNAMIC STORE.
                    245: #      ACCORDINGLY, A NAME IS ALWAYS REPRESENTED BY A BASE AND
                    246: #      OFFSET. THE BASE POINTS TO THE START OF THE BLOCK
                    247: #      CONTAINING THE VARIABLE VALUE AND THE OFFSET IS THE
                    248: #      OFFSET WITHIN THIS BLOCK IN BYTES. THUS THE ADDRESS
                    249: #      OF THE ACTUAL VARIABLE IS DETERMINED BY ADDING THE BASE
                    250: #      AND OFFSET VALUES.
                    251: #
                    252: #      THE FOLLOWING ARE THE INSTANCES OF VARIABLES REPRESENTED
                    253: #      IN THIS MANNER.
                    254: #
                    255: #      1)   NATURAL VARIABLE BASE IS PTR TO VRBLK
                    256: #                            OFFSET IS *VRVAL
                    257: #
                    258: #      2)   TABLE ELEMENT    BASE IS PTR TO TEBLK
                    259: #                            OFFSET IS *TEVAL
                    260: #
                    261: #      3)   ARRAY ELEMENT    BASE IS PTR TO ARBLK
                    262: #                            OFFSET IS OFFSET TO ELEMENT
                    263: #
                    264: #      4)   VECTOR ELEMENT   BASE IS PTR TO VCBLK
                    265: #                            OFFSET IS OFFSET TO ELEMENT
                    266: #
                    267: #      5)   PROG DEF DTP     BASE IS PTR TO PDBLK
                    268: #                            OFFSET IS OFFSET TO FIELD VALUE
                    269: #
                    270: #      IN ADDITION THERE ARE TWO CASES OF OBJECTS WHICH ARE
                    271: #      LIKE VARIABLES BUT CANNOT BE HANDLED IN THIS MANNER.
                    272: #      THESE ARE CALLED PSEUDO-VARIABLES AND ARE REPRESENTED
                    273: #      WITH A SPECIAL BASE POINTER AS FOLLOWS=
                    274: #
                    275: #      EXPRESSION VARIABLE   PTR TO EVBLK (SEE EVBLK)
                    276: #
                    277: #      KEYWORD VARIABLE      PTR TO KVBLK (SEE KVBLK)
                    278: #
                    279: #      PSEUDO-VARIABLES ARE HANDLED AS SPECIAL CASES BY THE
                    280: #      ACCESS PROCEDURE (ACESS) AND THE ASSIGNMENT PROCEDURE
                    281: #      (ASIGN). SEE THESE TWO PROCEDURES FOR DETAILS.
                    282:        #page   
                    283: #
                    284: #      ORGANIZATION OF DATA AREA
                    285: #      -------------------------
                    286: #
                    287: #
                    288: #      THE DATA AREA IS DIVIDED INTO TWO REGIONS.
                    289: #
                    290: #      STATIC AREA
                    291: #
                    292: #      THE STATIC AREA BUILDS UP FROM THE BOTTOM AND CONTAINS
                    293: #      DATA AREAS WHICH ARE ALLOCATED DYNAMICALLY BUT ARE NEVER
                    294: #      DELETED OR MOVED AROUND. THE MACRO-PROGRAM ITSELF
                    295: #      USES THE STATIC AREA FOR THE FOLLOWING.
                    296: #
                    297: #      1)   ALL VARIABLE BLOCKS (VRBLK).
                    298: #
                    299: #      2)   THE HASH TABLE FOR VARIABLE BLOCKS.
                    300: #
                    301: #      3)   MISCELLANEOUS BUFFERS AND WORK AREAS (SEE PROGRAM
                    302: #           INITIALIZATION SECTION).
                    303: #
                    304: #      IN ADDITION, THE SYSTEM PROCEDURES MAY USE THIS AREA FOR
                    305: #      INPUT/OUTPUT BUFFERS, EXTERNAL FUNCTIONS ETC. SPACE IN
                    306: #      THE STATIC REGION IS ALLOCATED BY CALLING PROCEDURE ALOST
                    307: #
                    308: #      THE FOLLOWING GLOBAL VARIABLES DEFINE THE CURRENT
                    309: #      LOCATION AND SIZE OF THE STATIC AREA.
                    310: #
                    311: #      STATB                 ADDRESS OF START OF STATIC AREA
                    312: #      STATE                 ADDRESS+1 OF LAST WORD IN AREA.
                    313: #
                    314: #      THE MINIMUM SIZE OF STATIC IS GIVEN APPROXIMATELY BY
                    315: #           12 + *E$HNB + *E$STS + SPACE FOR ALPHABET STRING
                    316: #           AND STANDARD PRINT BUFFER.
                    317:        #page   
                    318: #
                    319: #      DYNAMIC AREA
                    320: #
                    321: #      THE DYNAMIC AREA IS BUILT UPWARDS IN MEMORY AFTER THE
                    322: #      STATIC REGION. DATA IN THIS AREA MUST ALL BE IN STANDARD
                    323: #      BLOCK FORMATS SO THAT IT CAN BE PROCESSED BY THE GARBAGE
                    324: #      COLLECTOR (PROCEDURE GBCOL). GBCOL COMPACTS BLOCKS DOWN
                    325: #      IN THIS REGION AS REQUIRED BY SPACE EXHAUSTION AND CAN
                    326: #      ALSO MOVE ALL BLOCKS UP TO ALLOW FOR EXPANSION OF THE
                    327: #      STATIC REGION.
                    328: #      WITH THE EXCEPTION OF TABLES AND ARRAYS, NO SPITBOL
                    329: #      OBJECT ONCE BUILT IN DYNAMIC MEMORY IS EVER SUBSEQUENTLY
                    330: #      MODIFIED. OBSERVING THIS RULE NECESSITATES A COPYING
                    331: #      ACTION DURING STRING AND PATTERN CONCATENATION.
                    332: #
                    333: #      GARBAGE COLLECTION IS FUNDAMENTAL TO THE ALLOCATION OF
                    334: #      SPACE FOR VALUES. SPITBOL USES A VERY EFFICIENT GARBAGE
                    335: #      COLLECTOR WHICH INSISTS THAT POINTERS INTO DYNAMIC STORE
                    336: #      SHOULD BE IDENTIFIABLE WITHOUT USE OF BIT TABLES,
                    337: #      MARKER BITS ETC. TO SATISFY THIS REQUIREMENT, DYNAMIC
                    338: #      MEMORY MUST NOT START AT TOO LOW AN ADDRESS AND LENGTHS
                    339: #      OF ARRAYS, TABLES, STRINGS, CODE AND EXPRESSION BLOCKS
                    340: #      MAY NOT EXCEED THE NUMERICAL VALUE OF THE LOWEST DYNAMIC
                    341: #      ADDRESS. TO AVOID EITHER PENALIZING USERS WITH MODEST
                    342: #      REQUIREMENTS OR RESTRICTING THOSE WITH GREATER NEEDS ON
                    343: #      HOST SYSTEMS WHERE DYNAMIC MEMORY IS ALLOCATED IN LOW
                    344: #      ADDRESSES, THE MINIMUM DYNAMIC ADDRESS MAY BE SPECIFIED
                    345: #      SUFFICIENTLY HIGH TO PERMIT ARBITRARILY LARGE SPITBOL
                    346: #      OBJECTS TO BE CREATED ( WITH THE POSSIBILITY IN EXTREME
                    347: #      CASES OF WASTING LARGE AMOUNTS OF MEMORY BELOW THE
                    348: #      START ADDRESS). THIS MINIMUM VALUE IS MADE AVAILABLE
                    349: #      IN VARIABLE MXLEN BY A SYSTEM ROUTINE, SYSMX.
                    350: #      ALTERNATIVELY SYSMX MAY INDICATE THAT A
                    351: #      DEFAULT MAY BE USED IN WHICH DYNAMIC IS PLACED
                    352: #      AT THE LOWEST POSSIBLE ADDRESS FOLLOWING STATIC.
                    353: #
                    354: #      THE FOLLOWING GLOBAL WORK CELLS DEFINE THE LOCATION AND
                    355: #      LENGTH OF THE DYNAMIC AREA.
                    356: #
                    357: #      DNAMB                 START OF DYNAMIC AREA
                    358: #      DNAMP                 NEXT AVAILABLE LOCATION
                    359: #      DNAME                 LAST AVAILABLE LOCATION + 1
                    360: #
                    361: #      DNAMB IS ALWAYS HIGHER THAN STATE SINCE THE ALOST
                    362: #      PROCEDURE MAINTAINS SOME EXPANSION SPACE ABOVE STATE.
                    363: #      *** DNAMB MUST NEVER BE PERMITTED TO HAVE A VALUE LESS
                    364: #      THAN THAT IN MXLEN ***
                    365: #
                    366: #      SPACE IN THE DYNAMIC REGION IS ALLOCATED BY THE ALLOC
                    367: #      PROCEDURE. THE DYNAMIC REGION MAY BE USED BY SYSTEM
                    368: #      PROCEDURES PROVIDED THAT ALL THE RULES ARE OBEYED.
                    369:        #page   
                    370: #
                    371: #      REGISTER USAGE
                    372: #      --------------
                    373: #
                    374: #      (CP)                  CODE POINTER REGISTER. USED TO
                    375: #                            HOLD A POINTER TO THE CURRENT
                    376: #                            LOCATION IN THE INTERPRETIVE PSEUDO
                    377: #                            CODE (I.E. PTR INTO A CDBLK).
                    378: #
                    379: #      (XL,XR)               GENERAL INDEX REGISTERS. USUALLY
                    380: #                            USED TO HOLD POINTERS TO BLOCKS IN
                    381: #                            DYNAMIC STORAGE. AN IMPORTANT
                    382: #                            RESTRICTION IS THAT THE VALUE IN
                    383: #                            XL MUST BE COLLECTABLE FOR
                    384: #                            A GARBAGE COLLECT CALL. A VALUE
                    385: #                            IS COLLECTABLE IF IT EITHER POINTS
                    386: #                            OUTSIDE THE DYNAMIC AREA, OR IF IT
                    387: #                            POINTS TO THE START OF A BLOCK IN
                    388: #                            THE DYNAMIC AREA.
                    389: #
                    390: #      (XS)                  STACK POINTER. USED TO POINT TO
                    391: #                            THE STACK FRONT. THE STACK MAY
                    392: #                            BUILD UP OR DOWN AND IS USED
                    393: #                            TO STACK SUBROUTINE RETURN POINTS
                    394: #                            AND OTHER RECURSIVELY SAVED DATA.
                    395: #
                    396: #      (XT)                  AN ALTERNATIVE NAME FOR XL DURING
                    397: #                            ITS USE IN ACCESSING STACKED ITEMS.
                    398: #
                    399: #      (WA,WB,WC)            GENERAL WORK REGISTERS. CANNOT BE
                    400: #                            USED FOR INDEXING, BUT MAY HOLD
                    401: #                            VARIOUS TYPES OF DATA.
                    402: #
                    403: #      (IA)                  USED FOR ALL SIGNED INTEGER
                    404: #                            ARITHMETIC, BOTH THAT USED BY THE
                    405: #                            TRANSLATOR AND THAT ARISING FROM
                    406: #                            USE OF SNOBOL4 ARITHMETIC OPERATORS
                    407: #
                    408: #      (RA)                  REAL ACCUMULATOR. USED FOR ALL
                    409: #                            FLOATING POINT ARITHMETIC.
                    410:        #page   
                    411: #
                    412: #      SPITBOL CONDITIONAL ASSEMBLY SYMBOLS
                    413: #      ------------------------------------
                    414: #
                    415: #      IN THE SPITBOL TRANSLATOR, THE FOLLOWING CONDITIONAL
                    416: #      ASSEMBLY SYMBOLS ARE REFERRED TO. TO INCORPORATE THE
                    417: #      FEATURES REFERRED TO, THE MINIMAL SOURCE SHOULD BE
                    418: #      PREFACED BY SUITABLE CONDITIONAL ASSEMBLY SYMBOL
                    419: #      DEFINITIONS.
                    420: #      IN ALL CASES IT IS PERMISSIBLE TO DEFAULT THE DEFINITIONS
                    421: #      IN WHICH CASE THE ADDITIONAL FEATURES WILL BE OMITTED
                    422: #      FROM THE TARGET CODE.
                    423: #
                    424: #      .CASL                 DEFINE TO INCLUDE 26 SHIFTED LETTRS
                    425: #      .CAHT                 DEFINE TO INCLUDE HORIZONTAL TAB
                    426: #      .CAVT                 DEFINE TO INCLUDE VERTICAL TAB
                    427: #      .CIOD                 IF DEFINED, DEFAULT DELIMITER IS
                    428: #                            NOT USED IN PROCESSING 3RD ARG OF
                    429: #                            INPUT() AND OUTPUT()
                    430: #      .CNBT                 DEFINE TO OMIT BATCH INITIALISATION
                    431: #      .CNCI                 DEFINE TO ENABLE SYSCI ROUTINE
                    432: #      .CNEX                 DEFINE TO OMIT EXIT() CODE.
                    433: #      .CNLD                 DEFINE TO OMIT LOAD() CODE.
                    434: #      .CNPF                 DEFINE TO OMIT PROFILE STUFF
                    435: #      .CNRA                 DEFINE TO OMIT ALL REAL ARITHMETIC
                    436: #      .CNSR                 DEFINE TO OMIT SORT, RSORT
                    437: #      .CSAX                 DEFINE IF SYSAX IS TO BE CALLED
                    438: #      .CSN6                 DEFINE TO PAD STMT NOS TO 6 CHARS
                    439: #      .CSN8                 DEFINE TO PAD STMT NOS TO 8 CHARS
                    440: #      .CUCF                 DEFINE TO INCLUDE CFP$U
                    441: #      .CULC                 DEFINE TO INCLUDE &CASE (LC NAMES)
                    442: #      .CUST                 DEFINE TO INCLUDE SET() CODE
                    443:        #title  s p i t b o l -- procedures section
                    444: #
                    445: #      THIS SECTION STARTS WITH DESCRIPTIONS OF THE OPERATING
                    446: #      SYSTEM DEPENDENT PROCEDURES WHICH ARE USED BY THE SPITBOL
                    447: #      TRANSLATOR. ALL SUCH PROCEDURES HAVE FIVE LETTER NAMES
                    448: #      BEGINNING WITH SYS. THEY ARE LISTED IN ALPHABETICAL
                    449: #      ORDER.
                    450: #      ALL PROCEDURES HAVE A  SPECIFICATION CONSISTING OF A
                    451: #      MODEL CALL, PRECEDED BY A POSSIBLY EMPTY LIST OF REGISTER
                    452: #      CONTENTS GIVING PARAMETERS AVAILABLE TO THE PROCEDURE AND
                    453: #      FOLLOWED BY A POSSIBLY EMPTY LIST OF REGISTER CONTENTS
                    454: #      REQUIRED ON RETURN FROM THE CALL OR WHICH MAY HAVE HAD
                    455: #      THEIR CONTENTS DESTROYED. ONLY THOSE REGISTERS EXPLICITLY
                    456: #      MENTIONED IN THE LIST AFTER THE CALL MAY HAVE THEIR
                    457: #      VALUES CHANGED.
                    458: #      THE SEGMENT OF CODE PROVIDING THE EXTERNAL PROCEDURES IS
                    459: #      CONVENIENTLY REFERRED TO AS OSINT (OPERATING SYSTEM
                    460: #      INTERFACE). THE SYSXX PROCEDURES IT CONTAINS PROVIDE
                    461: #      FACILITIES NOT USUALLY AVAILABLE AS PRIMITIVES IN
                    462: #      ASSEMBLY LANGUAGES. FOR PARTICULAR TARGET MACHINES,
                    463: #      IMPLEMENTORS MAY CHOOSE FOR SOME MINIMAL OPCODES WHICH
                    464: #      DO NOT HAVE REASONABLY DIRECT TRANSLATIONS, TO USE CALLS
                    465: #      OF ADDITIONAL PROCEDURES WHICH THEY PROVIDE IN OSINT.
                    466: #      E.G. MWB OR TRC MIGHT BE TRANSLATED AS JSR SYSMB,
                    467: #      JSR SYSTC IN SOME IMPLEMENTATIONS.
                    468: #
                    469: #      IN THE DESCRIPTIONS, REFERENCE IS MADE TO --BLK
                    470: #      FORMATS (-- = A PAIR OF LETTERS). SEE THE SPITBOL
                    471: #      DEFINITIONS SECTION FOR DETAILED DESCRIPTIONS OF ALL
                    472: #      SUCH BLOCK FORMATS EXCEPT FCBLK FOR WHICH SYSFC SHOULD
                    473: #      BE CONSULTED.
                    474: #
                    475: #      SECTION 0 CONTAINS INP,INR SPECIFICATIONS OF INTERNAL
                    476: #      PROCEDURES,ROUTINES. THIS GIVES A SINGLE PASS TRANSLATOR
                    477: #      INFORMATION MAKING IT EASY TO GENERATE ALTERNATIVE CALLS
                    478: #      IN THE TRANSLATION OF JSR-S FOR PROCEDURES OF DIFFERENT
                    479: #      TYPES IF THIS PROVES NECESSARY.
                    480: #
                    481:        #sec                    # start of procedures section
                    482:        #page   
                    483: #
                    484: #      SYSAX -- AFTER EXECUTION
                    485: #
                    486:        .globl  sysax           # define external entry point
                    487: #
                    488: #      IF THE CONDITIONAL ASSEMBLY SYMBOL .CSAX IS DEFINED,
                    489: #      THIS ROUTINE IS CALLED IMMEDIATELY AFTER EXECUTION AND
                    490: #      BEFORE PRINTING OF EXECUTION STATISTICS OR DUMP OUTPUT.
                    491: #      PURPOSE OF CALL IS FOR IMPLEMENTOR TO DETERMINE AND
                    492: #      IF THE CALL IS NOT REQUIRED IT WILL BE OMITTED IF .CSAX
                    493: #      IS UNDEFINED. IN THIS CASE SYSAX NEED NOT BE CODED.
                    494: #
                    495: #      JSR  SYSAX            CALL AFTER EXECUTION
                    496:        #page   
                    497: #
                    498: #      SYSBX -- BEFORE EXECUTION
                    499: #
                    500:        .globl  sysbx           # define external entry point
                    501: #
                    502: #      CALLED AFTER INITIAL SPITBOL COMPILATION AND BEFORE
                    503: #      COMMENCING EXECUTION IN CASE OSINT NEEDS
                    504: #      TO ASSIGN FILES OR PERFORM OTHER NECESSARY SERVICES.
                    505: #      OSINT MAY ALSO CHOOSE TO SEND A MESSAGE TO ONLINE
                    506: #      TERMINAL (IF ANY) INDICATING THAT EXECUTION IS STARTING.
                    507: #
                    508: #      JSR  SYSBX            CALL BEFORE EXECUTION STARTS
                    509:        #page   
                    510: #
                    511: #      SYSDC -- DATE CHECK
                    512: #
                    513:        .globl  sysdc           # define external entry point
                    514: #
                    515: #      SYSDC IS CALLED TO CHECK THAT THE EXPIRY DATE FOR A TRIAL
                    516: #      VERSION OF SPITBOL IS UNEXPIRED.
                    517: #
                    518: #      JSR  SYSDC            CALL TO CHECK DATE
                    519: #      RETURN ONLY IF DATE IS OK
                    520:        #page   
                    521: #
                    522: #      SYSDM  -- DUMP CORE
                    523: #
                    524:        .globl  sysdm           # define external entry point
                    525: #
                    526: #      SYSDM IS CALLED BY A SPITBOL PROGRAM CALL OF DUMP(N) WITH
                    527: #      N GE 3.  ITS PURPOSE IS TO PROVIDE A CORE DUMP.
                    528: #      N COULD HOLD AN ENCODING OF THE START ADRS FOR DUMP AND
                    529: #      AMOUNT TO BE DUMPED E.G.  N = 256*A + S , S = START ADRS
                    530: #      IN KILOWORDS,  A = KILOWORDS TO DUMP
                    531: #
                    532: #      (XR)                  PARAMETER N OF CALL DUMP(N)
                    533: #      JSR  SYSDM            CALL TO ENTER ROUTINE
                    534:        #page   
                    535: #
                    536: #      SYSDT -- GET CURRENT DATE
                    537: #
                    538:        .globl  sysdt           # define external entry point
                    539: #
                    540: #      SYSDT IS USED TO OBTAIN THE CURRENT DATE. THE DATE IS
                    541: #      RETURNED AS A CHARACTER STRING IN ANY FORMAT APPROPRIATE
                    542: #      TO THE OPERATING SYSTEM IN USE. IT MAY ALSO CONTAIN THE
                    543: #      CURRENT TIME OF DAY. SYSDT IS USED TO IMPLEMENT THE
                    544: #      SNOBOL4 FUNCTION DATE.
                    545: #
                    546: #      JSR  SYSDT            CALL TO GET DATE
                    547: #      (XL)                  POINTER TO BLOCK CONTAINING DATE
                    548: #
                    549: #      THE FORMAT OF THE BLOCK IS LIKE AN SCBLK EXCEPT THAT
                    550: #      THE FIRST WORD NEED NOT BE SET. THE RESULT IS COPIED
                    551: #      INTO SPITBOL DYNAMIC MEMORY ON RETURN.
                    552:        #page   
                    553: #
                    554: #      SYSEF -- EJECT FILE
                    555: #
                    556:        .globl  sysef           # define external entry point
                    557: #
                    558: #      SYSEF IS USED TO WRITE A PAGE EJECT TO A NAMED FILE. IT
                    559: #      MAY ONLY BE USED FOR FILES WHERE THIS CONCEPT MAKES
                    560: #      SENSE. NOTE THAT SYSEF IS NOT NORMALLY USED FOR THE
                    561: #      STANDARD OUTPUT FILE (SEE SYSEP).
                    562: #
                    563: #      (WA)                  PTR TO FCBLK OR ZERO
                    564: #      (XR)                  EJECT ARGUMENT (SCBLK PTR)
                    565: #      JSR  SYSEF            CALL TO EJECT FILE
                    566: #      PPM  LOC              RETURN HERE IF FILE DOES NOT EXIST
                    567: #      PPM  LOC              RETURN HERE IF INAPPROPRIATE FILE
                    568: #      PPM  LOC              RETURN HERE IF I/O ERROR
                    569:        #page   
                    570: #
                    571: #      SYSEJ -- END OF JOB
                    572: #
                    573:        .globl  sysej           # define external entry point
                    574: #
                    575: #      SYSEJ IS CALLED ONCE AT THE END OF EXECUTION TO
                    576: #      TERMINATE THE RUN. THE SIGNIFICANCE OF THE ABEND AND
                    577: #      CODE VALUES IS SYSTEM DEPENDENT. IN GENERAL, THE CODE
                    578: #      VALUE SHOULD BE MADE AVAILABLE FOR TESTING, AND THE
                    579: #      ABEND VALUE SHOULD CAUSE SOME POST-MORTEM ACTION SUCH AS
                    580: #      A DUMP. NOTE THAT SYSEJ DOES NOT RETURN TO ITS CALLER.
                    581: #      SEE SYSXI FOR DETAILS OF FCBLK CHAIN
                    582: #
                    583: #      (WA)                  VALUE OF ABEND KEYWORD
                    584: #      (WB)                  VALUE OF CODE KEYWORD
                    585: #      (XL)                  O OR PTR TO HEAD OF FCBLK CHAIN
                    586: #      JSR  SYSEJ            CALL TO END JOB
                    587: #
                    588: #      THE FOLLOWING SPECIAL VALUES ARE USED AS CODES IN (WB)
                    589: #      999  EXECUTION SUPPRESSED
                    590: #      998  STANDARD OUTPUT FILE FULL OR UNAVAILABLE IN A SYSXI
                    591: #           LOAD MODULE. IN THESE CASES (WA) CONTAINS THE NUMBER
                    592: #           OF THE STATEMENT CAUSING PREMATURE TERMINATION.
                    593:        #page   
                    594: #
                    595: #      SYSEM -- GET ERROR MESSAGE TEXT
                    596: #
                    597:        .globl  sysem           # define external entry point
                    598: #
                    599: #      SYSEM IS USED TO OBTAIN THE TEXT OF ERR, ERB CALLS IN THE
                    600: #      SOURCE PROGRAM GIVEN THE ERROR CODE NUMBER. IT IS ALLOWED
                    601: #      TO RETURN A NULL STRING IF THIS FACILITY IS UNAVAILABLE.
                    602: #
                    603: #      (WA)                  ERROR CODE NUMBER
                    604: #      JSR  SYSEM            CALL TO GET TEXT
                    605: #      (XR)                  TEXT OF MESSAGE
                    606: #
                    607: #      THE RETURNED VALUE IS A POINTER TO A BLOCK IN SCBLK
                    608: #      FORMAT EXCEPT THAT THE FIRST WORD NEED NOT BE SET. THE
                    609: #      STRING IS COPIED INTO DYNAMIC MEMORY ON RETURN.
                    610: #      IF THE NULL STRING IS RETURNED EITHER BECAUSE SYSEM DOES
                    611: #      NOT PROVIDE ERROR MESSAGE TEXTS OR BECAUSE WA IS OUT OF
                    612: #      RANGE, SPITBOL WILL PRINT THE STRING STORED IN ERRTEXT
                    613: #      KEYWORD.
                    614:        #page   
                    615: #
                    616: #      SYSEN -- ENDFILE
                    617: #
                    618:        .globl  sysen           # define external entry point
                    619: #
                    620: #      SYSEN IS USED TO IMPLEMENT THE SNOBOL4 FUNCTION ENDFILE.
                    621: #      THE MEANING IS SYSTEM DEPENDENT. IN GENERAL, ENDFILE
                    622: #      IMPLIES THAT NO FURTHER I/O OPERATIONS WILL BE PERFORMED,
                    623: #      BUT DOES NOT GUARANTEE THIS TO BE THE CASE. THE FILE
                    624: #      SHOULD BE CLOSED AFTER THE CALL, A SUBSEQUENT READ
                    625: #      OR WRITE MAY REOPEN THE FILE AT THE START OR IT MAY BE
                    626: #      NECESSARY TO REOPEN THE FILE VIA SYSIO.
                    627: #
                    628: #      (WA)                  PTR TO FCBLK OR ZERO
                    629: #      (XR)                  ENDFILE ARGUMENT (SCBLK PTR)
                    630: #      JSR  SYSEN            CALL TO ENDFILE
                    631: #      PPM  LOC              RETURN HERE IF FILE DOES NOT EXIST
                    632: #      PPM  LOC              RETURN HERE IF ENDFILE NOT ALLOWED
                    633: #      PPM  LOC              RETURN HERE IF I/O ERROR
                    634: #      (WA,WB)               DESTROYED
                    635: #
                    636: #      THE SECOND ERROR RETURN IS USED FOR FILES FOR WHICH
                    637: #      ENDFILE IS NOT PERMITTED. FOR EXAMPLE, IT MAY BE EXPECTED
                    638: #      THAT THE STANDARD INPUT AND OUTPUT FILES ARE IN THIS
                    639: #      CATEGORY.
                    640:        #page   
                    641: #
                    642: #      SYSEP -- EJECT PRINTER PAGE
                    643: #
                    644:        .globl  sysep           # define external entry point
                    645: #
                    646: #      SYSEP IS CALLED TO PERFORM A PAGE EJECT ON THE STANDARD
                    647: #      PRINTER OUTPUT FILE (CORRESPONDING TO SYSPR OUTPUT).
                    648: #
                    649: #      JSR  SYSEP            CALL TO EJECT PRINTER OUTPUT
                    650:        #page   
                    651: #
                    652: #      SYSEX -- CALL EXTERNAL FUNCTION
                    653: #
                    654:        .globl  sysex           # define external entry point
                    655: #
                    656: #      SYSEX IS CALLED TO PASS CONTROL TO AN EXTERNAL FUNCTION
                    657: #      PREVIOUSLY LOADED WITH A CALL TO SYSLD.
                    658: #
                    659: #      (XS)                  POINTER TO ARGUMENTS ON STACK
                    660: #      (XL)                  POINTER TO CONTROL BLOCK (EFBLK)
                    661: #      (WA)                  NUMBER OF ARGUMENTS ON STACK
                    662: #      JSR  SYSEX            CALL TO PASS CONTROL TO FUNCTION
                    663: #      PPM  LOC              RETURN HERE IF FUNCTION CALL FAILS
                    664: #      (XS)                  POPPED PAST ARGUMENTS
                    665: #      (XR)                  RESULT RETURNED
                    666: #
                    667: #      THE ARGUMENTS ARE STORED ON THE STACK WITH
                    668: #      THE LAST ARGUMENT AT 0(XS). ON RETURN, XS
                    669: #      IS POPPED PAST THE ARGUMENTS.
                    670: #
                    671: #      THE FORM OF THE ARGUMENTS AS PASSED IS THAT USED IN THE
                    672: #      SPITBOL TRANSLATOR (SEE DEFINITIONS AND DATA STRUCTURES
                    673: #      SECTION). THE CONTROL BLOCK FORMAT IS ALSO DESCRIBED
                    674: #      (UNDER EFBLK) IN THIS SECTION.
                    675: #
                    676: #      THERE ARE TWO WAYS OF RETURNING A RESULT.
                    677: #
                    678: #      1)   RETURN A POINTER TO A BLOCK IN DYNAMIC STORAGE. THIS
                    679: #           BLOCK MUST BE IN EXACTLY CORRECT FORMAT, INCLUDING
                    680: #           THE FIRST WORD. ONLY FUNCTIONS WRITTEN WITH INTIMATE
                    681: #           KNOWLEDGE OF THE SYSTEM WILL RETURN IN THIS WAY.
                    682: #
                    683: #      2)   STRING, INTEGER AND REAL RESULTS MAY BE RETURNED BY
                    684: #           POINTING TO A PSEUDO-BLOCK OUTSIDE DYNAMIC MEMORY.
                    685: #           THIS BLOCK IS IN ICBLK, RCBLK OR SCBLK FORMAT EXCEPT
                    686: #           THAT THE FIRST WORD WILL BE OVERWRITTEN
                    687: #           BY A TYPE WORD ON RETURN AND SO NEED NOT
                    688: #           BE CORRECTLY SET. SUCH A RESULT IS
                    689: #           COPIED INTO MAIN STORAGE BEFORE PROCEEDING.
                    690: #           UNCONVERTED RESULTS MAY SIMILARLY BE RETURNED IN A
                    691: #           PSEUDO-BLOCK WHICH IS IN CORRECT FORMAT INCLUDING
                    692: #           TYPE WORD RECOGNISABLE BY GARBAGE COLLECTOR SINCE
                    693: #           BLOCK IS COPIED INTO DYNAMIC MEMORY.
                    694:        #page   
                    695: #
                    696: #      SYSFC -- FILE CONTROL BLOCK ROUTINE
                    697: #
                    698:        .globl  sysfc           # define external entry point
                    699: #
                    700: #      SEE ALSO SYSIO
                    701: #      INPUT AND OUTPUT HAVE 3 ARGUMENTS REFERRED TO AS SHOWN
                    702: #           INPUT(VARIABLE NAME,FILE ARG1,FILE ARG2)
                    703: #           OUTPUT(VARIABLE NAME,FILE ARG1,FILE ARG2)
                    704: #      FILE ARG1 MAY BE AN INTEGER OR STRING USED TO IDENTIFY
                    705: #      AN I/O CHANNEL. IT IS CONVERTED TO A STRING FOR CHECKING.
                    706: #      THE EXACT SIGNIFICANCE OF FILE ARG2
                    707: #      IS NOT RIGOROUSLY PRESCRIBED BUT TO IMPROVE PORTABILITY,
                    708: #      THE SCHEME DESCRIBED IN THE SPITBOL USER MANUAL
                    709: #      SHOULD BE ADOPTED WHEN POSSIBLE. THE PREFERRED FORM IS
                    710: #      A STRING $F$,R$R$,C$C$,I$I$,...,Z$Z$  WHERE
                    711: #      $F$ IS AN OPTIONAL FILE NAME WHICH IS PLACED FIRST.
                    712: #       REMAINING ITEMS MAY BE OMITTED OR INCLUDED IN ANY ORDER.
                    713: #      $R$ IS MAXIMUM RECORD LENGTH
                    714: #      $C$ IS A CARRIAGE CONTROL CHARACTER OR CHARACTER STRING
                    715: #      $I$ IS SOME FORM OF CHANNEL IDENTIFICATION USED IN THE
                    716: #         ABSENCE OF $F$ TO ASSOCIATE THE VARIABLE
                    717: #         WITH A FILE ALLOCATED DYNAMICALLY BY JCL COMMANDS AT
                    718: #         SPITBOL LOAD TIME.
                    719: #      ,...,Z$Z$ ARE ADDITIONAL FIELDS.
                    720: #      IF , (COMMA) CANNOT BE USED AS A DELIMITER, .CIOD
                    721: #      SHOULD BE DEFINED TO INTRODUCE BY CONDITIONAL ASSEMBLY
                    722: #      ANOTHER DELIMITER (SEE
                    723: #        IODEL  EQU  *
                    724: #      EARLY IN DEFINITIONS SECTION).
                    725: #      SYSFC IS CALLED WHEN A VARIABLE IS INPUT OR OUTPUT
                    726: #      ASSOCIATED TO CHECK FILE ARG1 AND FILE ARG2 AND
                    727: #      TO  REPORT WHETHER AN FCBLK (FILE CONTROL
                    728: #      BLOCK) IS NECESSARY AND IF SO WHAT SIZE IT SHOULD BE.
                    729: #      THIS MAKES IT POSSIBLE FOR SPITBOL RATHER THAN OSINT TO
                    730: #      ALLOCATE SUCH A BLOCK IN DYNAMIC MEMORY IF REQUIRED
                    731: #      OR ALTERNATIVELY IN STATIC MEMORY.
                    732: #      THE SIGNIFICANCE OF AN FCBLK , IF ONE IS REQUESTED, IS
                    733: #      ENTIRELY UP TO THE SYSTEM INTERFACE. THE ONLY RESTRICTION
                    734: #      IS THAT IF THE FCBLK SHOULD APPEAR TO LIE IN DYNAMIC
                    735: #      MEMORY , POINTERS TO IT SHOULD BE PROPER POINTERS TO
                    736: #      THE START OF A RECOGNISABLE AND GARBAGE COLLECTABLE
                    737: #      BLOCK (THIS CONDITION WILL BE MET IF SYSFC REQUESTS
                    738: #      SPITBOL TO PROVIDE AN FCBLK).
                    739: #      AN OPTION IS PROVIDED FOR OSINT TO RETURN A POINTER IN
                    740: #      XL TO AN FCBLK WHICH IT PRIVATELY ALLOCATED. THIS PTR
                    741: #      WILL BE MADE AVAILABLE WHEN I/O OCCURS LATER.
                    742: #      PRIVATE FCBLKS MAY HAVE ARBITRARY CONTENTS AND SPITBOL
                    743: #      STORES NOTHING IN THEM.
                    744:        #page   
                    745: #      THE REQUESTED SIZE FOR AN FCBLK IN DYNAMIC MEMORY
                    746: #      SHOULD ALLOW A 2 WORD OVERHEAD FOR BLOCK TYPE AND
                    747: #      LENGTH FIELDS. INFORMATION SUBSEQUENTLY STORED IN THE
                    748: #      REMAINING WORDS MAY BE ARBITRARY IF AN XNBLK (EXTERNAL
                    749: #      NON-RELOCATABLE BLOCK) IS REQUESTED. IF THE REQUEST IS
                    750: #      FOR AN XRBLK (EXTERNAL RELOCATABLE BLOCK) THE
                    751: #      CONTENTS OF WORDS SHOULD BE COLLECTABLE (I.E. ANY
                    752: #      APPARENT POINTERS INTO DYNAMIC SHOULD BE GENUINE BLOCK
                    753: #      POINTERS). THESE RESTRICTIONS DO NOT APPLY IF AN FCBLK
                    754: #      IS ALLOCATED OUTSIDE DYNAMIC OR IS NOT ALLOCATED AT ALL.
                    755: #      IF AN FCBLK IS REQUESTED, ITS FIELDS WILL BE INITIALISED
                    756: #      TO ZERO BEFORE ENTRY TO SYSIO WITH THE EXCEPTION OF
                    757: #      WORDS 0 AND 1 IN WHICH THE BLOCK TYPE AND LENGTH
                    758: #      FIELDS ARE PLACED FOR FCBLKS IN DYNAMIC MEMORY ONLY.
                    759: #      FOR THE POSSIBLE USE OF SYSEJ AND SYSXI, IF FCBLKS
                    760: #      ARE USED, A CHAIN IS BUILT SO THAT THEY MAY ALL BE
                    761: #      FOUND - SEE SYSXI FOR DETAILS.
                    762: #      IF BOTH FILE ARG1 AND FILE ARG2 ARE NULL, CALLS OF SYSFC
                    763: #      AND SYSIO ARE OMITTED.
                    764: #      IF FILE ARG1 IS NULL (STANDARD INPUT/OUTPUT FILE), SYSFC
                    765: #      IS CALLED TO CHECK NON-NULL FILE ARG2 BUT ANY REQUEST
                    766: #      FOR AN FCBLK WILL BE IGNORED, SINCE SPITBOL HANDLES THE
                    767: #      STANDARD FILES SPECIALLY AND CANNOT READILY KEEP FCBLK
                    768: #      POINTERS FOR THEM.
                    769: #      FILEARG1 IS TYPE CHECKED BY SPITBOL SO FURTHER CHECKING
                    770: #      MAY BE UNNECCESSARY IN MANY IMPLEMENTATIONS.
                    771: #      FILE ARG2 IS PASSED SO THAT SYSFC MAY ANALYSE AND
                    772: #      CHECK IT. HOWEVER TO ASSIST IN THIS, SPITBOL ALSO PASSES
                    773: #      ON THE STACK THE COMPONENTS OF THIS ARGUMENT WITH
                    774: #      FILE NAME, $F$ (OTHERWISE NULL) EXTRACTED AND STACKED
                    775: #      FIRST.
                    776: #      THE OTHER FIELDS, IF ANY, ARE EXTRACTED AS SUBSTRINGS,
                    777: #      POINTERS TO THEM ARE STACKED AND A COUNT OF ALL ITEMS
                    778: #      STACKED IS PLACED IN WC. IF AN FCBLK WAS EARLIER
                    779: #      ALLOCATED AND POINTED TO VIA FILE ARG1, SYSFC IS ALSO
                    780: #      PASSED A POINTER TO THIS FCBLK.
                    781: #
                    782: #      (XL)                  FILE ARG1 SCBLK PTR (2ND ARG)
                    783: #      (XR)                  FILEARG2 (3RD ARG) OR NULL
                    784: #      -(XS)...-(XS)         SCBLKS FOR $F$,$R$,$C$,...
                    785: #      (WC)                  NO. OF STACKED SCBLKS ABOVE
                    786: #      (WA)                  EXISTING FILE ARG1 FCBLK PTR OR 0
                    787: #      (WB)                  0/3 FOR INPUT/OUTPUT ASSOCN
                    788: #      JSR  SYSFC            CALL TO CHECK NEED FOR FCBLK
                    789: #      PPM  LOC              INVALID FILE ARGUMENT
                    790: #      (XS)                  POPPED (WC) TIMES
                    791: #      (WA NON ZERO)         BYTE SIZE OF REQUESTED FCBLK
                    792: #      (WA=0,XL NON ZERO)    PRIVATE FCBLK PTR IN XL
                    793: #      (WA=XL=0)             NO FCBLK WANTED, NO PRIVATE FCBLK
                    794: #      (WC)                  0/1/2 REQUEST ALLOC OF XRBLK/XNBLK
                    795: #                            /STATIC BLOCK FOR USE AS FCBLK
                    796: #      (WB)                  DESTROYED
                    797:        #page   
                    798: #
                    799: #      SYSHS -- GIVE ACCESS TO HOST COMPUTER FEATURES
                    800: #
                    801:        .globl  syshs           # define external entry point
                    802: #
                    803: #      PROVIDES MEANS FOR IMPLEMENTING SPECIAL FEATURES
                    804: #      ON DIFFERENT HOST COMPUTERS. THE ONLY DEFINED ENTRY IS
                    805: #      THAT WHERE ALL ARGUMENTS ARE NULL IN WHICH CASE SYSHS
                    806: #      RETURNS AN SCBLK CONTAINING NAME OF COMPUTER,
                    807: #      NAME OF OPERATING SYSTEM AND NAME OF SITE SEPARATED BY
                    808: #      COLONS. THE SCBLK NEED NOT HAVE A CORRECT FIRST FIELD
                    809: #      AS THIS IS SUPPLIED ON COPYING STRING TO DYNAMIC MEMORY.
                    810: #      SPITBOL DOES NO ARGUMENT CHECKING BUT DOES PROVIDE A
                    811: #      SINGLE ERROR RETURN FOR ARGUMENTS CHECKED AS ERRONEOUS
                    812: #      BY OSINT. IT ALSO PROVIDES A SINGLE EXECUTION ERROR
                    813: #      RETURN. IF THESE ARE INADEQUATE, USE MAY BE MADE OF THE
                    814: #      MINIMAL ERROR SECTION DIRECT AS DESCRIBED IN MINIMAL
                    815: #      DOCUMENTATION, SECTION 10.
                    816: #      SEVERAL NON-ERROR RETURNS ARE PROVIDED. THE FIRST
                    817: #      CORRESPONDS TO THE DEFINED ENTRY OR, FOR IMPLEMENTATION
                    818: #      DEFINED ENTRIES, ANY STRING MAY BE RETURNED. THE OTHERS
                    819: #      PERMIT RESPECTIVELY,  RETURN A NULL RESULT, RETURN WITH A
                    820: #      RESULT TO BE STACKED WHICH IS POINTED AT BY XR, AND A
                    821: #      RETURN CAUSING SPITBOL STATEMENT FAILURE. IF A RETURNED
                    822: #      RESULT IS IN DYNAMIC MEMORY IT MUST OBEY GARBAGE
                    823: #      COLLECTOR RULES. THE ONLY RESULTS COPIED ON RETURN
                    824: #      ARE STRINGS RETURNED VIA PPM LOC3 RETURN.
                    825: #
                    826: #      (WA)                  ARGUMENT 1
                    827: #      (XL)                  ARGUMENT 2
                    828: #      (XR)                  ARGUMENT 3
                    829: #      JSR  SYSHS            CALL TO GET HOST INFORMATION
                    830: #      PPM  LOC1             ERRONEOUS ARG
                    831: #      PPM  LOC2             EXECUTION ERROR
                    832: #      PPM  LOC3             SCBLK PTR IN XL OR 0 IF UNAVAILABLE
                    833: #      PPM  LOC4             RETURN A NULL RESULT
                    834: #      PPM  LOC5             RETURN RESULT IN XR
                    835: #      PPM  LOC6             CAUSE STATEMENT FAILURE
                    836:        #page   
                    837: #
                    838: #      SYSID -- RETURN SYSTEM IDENTIFICATION
                    839: #
                    840:        .globl  sysid           # define external entry point
                    841: #
                    842: #      THIS ROUTINE SHOULD RETURN STRINGS TO HEAD THE STANDARD
                    843: #      PRINTER OUTPUT. THE FIRST STRING WILL BE APPENDED TO
                    844: #      A HEADING LINE OF THE FORM
                    845: #           MACRO SPITBOL VERSION V.V
                    846: #      SUPPLIED BY SPITBOL ITSELF. V.V ARE DIGITS GIVING THE
                    847: #      MAJOR VERSION NUMBER AND GENERALLY AT LEAST A MINOR
                    848: #      VERSION NUMBER RELATING TO OSINT SHOULD BE SUPPLIED TO
                    849: #      GIVE SAY
                    850: #           MACRO SPITBOL VERSION V.V(M.M)
                    851: #      THE SECOND STRING SHOULD IDENTIFY AT LEAST THE MACHINE
                    852: #      AND OPERATING SYSTEM.  PREFERABLY IT SHOULD INCLUDE
                    853: #      THE DATE AND TIME OF THE RUN.
                    854: #      OPTIONALLY THE STRINGS MAY INCLUDE SITE NAME OF THE
                    855: #      THE IMPLEMENTOR AND/OR MACHINE ON WHICH RUN TAKES PLACE,
                    856: #      UNIQUE SITE OR COPY NUMBER AND OTHER INFORMATION AS
                    857: #      APPROPRIATE WITHOUT MAKING IT SO LONG AS TO BE A
                    858: #      NUISANCE TO USERS.
                    859: #      THE FIRST WORDS OF THE SCBLKS POINTED AT NEED NOT BE
                    860: #      CORRECTLY SET.
                    861: #
                    862: #      JSR  SYSID            CALL FOR SYSTEM IDENTIFICATION
                    863: #      (XR)                  SCBLK PTR FOR ADDITION TO HEADER
                    864: #      (XL)                  PTR TO SECOND HEADER SCBLK
                    865:        #page   
                    866: #
                    867: #      SYSIL -- GET INPUT RECORD LENGTH
                    868: #
                    869:        .globl  sysil           # define external entry point
                    870: #
                    871: #      SYSIL IS USED TO GET THE LENGTH OF THE NEXT INPUT RECORD
                    872: #      FROM A FILE PREVIOUSLY INPUT ASSOCIATED WITH A SYSIO
                    873: #      CALL. THE LENGTH RETURNED IS USED TO ESTABLISH A BUFFER
                    874: #      FOR A SUBSEQUENT SYSIN CALL.
                    875: #
                    876: #      (WA)                  PTR TO FCBLK OR ZERO
                    877: #      JSR  SYSIL            CALL TO GET RECORD LENGTH
                    878: #      (WA)                  LENGTH OR ZERO IF FILE CLOSED
                    879: #
                    880: #      NO HARM IS DONE IF THE VALUE RETURNED IS TOO LONG SINCE
                    881: #      UNUSED SPACE WILL BE RECLAIMED AFTER THE SYSIN CALL.
                    882: #
                    883: #      NOTE THAT IT IS THE SYSIL CALL (NOT THE SYSIO CALL) WHICH
                    884: #      CAUSES THE FILE TO BE OPENED AS REQUIRED FOR THE FIRST
                    885: #      RECORD INPUT FROM THE FILE.
                    886:        #page   
                    887: #
                    888: #      SYSIN -- READ INPUT RECORD
                    889: #
                    890:        .globl  sysin           # define external entry point
                    891: #
                    892: #      SYSIN IS USED TO READ A RECORD FROM THE FILE WHICH WAS
                    893: #      REFERENCED IN A PRIOR CALL TO SYSIL (I.E. THESE CALLS
                    894: #      ALWAYS OCCUR IN PAIRS). THE BUFFER PROVIDED IS AN
                    895: #      SCBLK FOR A STRING OF LENGTH SET FROM THE SYSIL CALL.
                    896: #      IF THE ACTUAL LENGTH READ IS LESS THAN THIS, THE LENGTH
                    897: #      FIELD OF THE SCBLK MUST BE MODIFIED BEFORE RETURNING
                    898: #      UNLESS BUFFER IS RIGHT PADDED WITH ZEROES.
                    899: #      IT IS ALSO PERMISSIBLE TO TAKE ANY OF THE ALTERNATIVE
                    900: #      RETURNS AFTER SCBLK LENGTH HAS BEEN MODIFIED.
                    901: #
                    902: #      (WA)                  PTR TO FCBLK OR ZERO
                    903: #      (XR)                  POINTER TO BUFFER (SCBLK PTR)
                    904: #      JSR  SYSIN            CALL TO READ RECORD
                    905: #      PPM  LOC              ENDFILE OR NO I/P FILE AFTER SYSXI
                    906: #      PPM  LOC              RETURN HERE IF I/O ERROR
                    907: #      PPM  LOC              RETURN HERE IF RECORD FORMAT ERROR
                    908: #      (WA,WB,WC)            DESTROYED
                    909:        #page   
                    910: #
                    911: #      SYSIO -- INPUT/OUTPUT FILE ASSOCIATION
                    912: #
                    913:        .globl  sysio           # define external entry point
                    914: #
                    915: #      SEE ALSO SYSFC.
                    916: #      SYSIO IS CALLED IN RESPONSE TO A SNOBOL4 INPUT OR OUTPUT
                    917: #      FUNCTION CALL EXCEPT WHEN FILE ARG1 AND FILE ARG2
                    918: #      ARE BOTH NULL.
                    919: #      ITS CALL ALWAYS FOLLOWS IMMEDIATELY AFTER A CALL
                    920: #      OF SYSFC. IF SYSFC REQUESTED ALLOCATION
                    921: #      OF AN FCBLK, ITS ADDRESS WILL BE IN WA.
                    922: #      FOR INPUT FILES, NON-ZERO VALUES OF $R$ SHOULD BE
                    923: #      COPIED TO WC FOR USE IN ALLOCATING INPUT BUFFERS. IF $R$
                    924: #      IS DEFAULTED OR NOT IMPLEMENTED, WC SHOULD BE ZEROISED.
                    925: #      ONCE A FILE HAS BEEN OPENED, SUBSEQUENT INPUT(),OUTPUT()
                    926: #      CALLS IN WHICH THE SECOND ARGUMENT IS IDENTICAL WITH THAT
                    927: #      IN A PREVIOUS CALL, MERELY ASSOCIATE THE ADDITIONAL
                    928: #      VARIABLE NAME (FIRST ARGUMENT) TO THE FILE AND DO NOT
                    929: #      RESULT IN RE-OPENING THE FILE.
                    930: #      IN SUBSEQUENT ASSOCIATED ACCESSES TO THE FILE A POINTER
                    931: #      TO ANY FCBLK ALLOCATED WILL BE MADE AVAILABLE.
                    932: #
                    933: #      (XL)                  FILE ARG1 SCBLK PTR (2ND ARG)
                    934: #      (XR)                  FILE ARG2 SCBLK PTR (3RD ARG)
                    935: #      (WA)                  FCBLK PTR (0 IF NONE)
                    936: #      (WB)                  0 FOR INPUT, 3 FOR OUTPUT
                    937: #      JSR  SYSIO            CALL TO ASSOCIATE FILE
                    938: #      PPM  LOC              RETURN HERE IF FILE DOES NOT EXIST
                    939: #      PPM  LOC              RETURN IF INPUT/OUTPUT NOT ALLOWED
                    940: #      (XL)                  FCBLK POINTER (0 IF NONE)
                    941: #      (WC)                  0 (FOR DEFAULT) OR MAX RECORD LNGTH
                    942: #      (WA,WB)               DESTROYED
                    943: #
                    944: #      THE SECOND ERROR RETURN IS USED IF THE FILE NAMED EXISTS
                    945: #      BUT INPUT/OUTPUT FROM THE FILE IS NOT ALLOWED. FOR
                    946: #      EXAMPLE, THE STANDARD OUTPUT FILE MAY BE IN THIS CATEGORY
                    947: #      AS REGARDS INPUT ASSOCIATION.
                    948:        #page   
                    949: #
                    950: #      SYSLD -- LOAD EXTERNAL FUNCTION
                    951: #
                    952:        .globl  sysld           # define external entry point
                    953: #
                    954: #      SYSLD IS CALLED IN RESPONSE TO THE USE OF THE SNOBOL4
                    955: #      LOAD FUNCTION. THE NAMED FUNCTION IS LOADED (WHATEVER
                    956: #      THIS MEANS), AND A POINTER IS RETURNED. THE POINTER WILL
                    957: #      BE USED ON SUBSEQUENT CALLS TO THE FUNCTION (SEE SYSEX).
                    958: #
                    959: #      (XR)                  POINTER TO FUNCTION NAME (SCBLK)
                    960: #      (XL)                  POINTER TO LIBRARY NAME (SCBLK)
                    961: #      JSR  SYSLD            CALL TO LOAD FUNCTION
                    962: #      PPM  LOC              RETURN HERE IF FUNC DOES NOT EXIST
                    963: #      PPM  LOC              RETURN HERE IF I/O ERROR
                    964: #      (XR)                  POINTER TO LOADED CODE
                    965: #
                    966: #      THE SIGNIFICANCE OF THE POINTER RETURNED IS UP TO THE
                    967: #      SYSTEM INTERFACE ROUTINE. THE ONLY RESTRICTION IS THAT
                    968: #      IF THE POINTER IS WITHIN DYNAMIC STORAGE, IT MUST BE
                    969: #      A PROPER BLOCK POINTER.
                    970:        #page   
                    971: #
                    972: #      SYSMM -- GET MORE MEMORY
                    973: #
                    974:        .globl  sysmm           # define external entry point
                    975: #
                    976: #      SYSMM IS CALLED IN AN ATTEMPT TO ALLOCATE MORE DYNAMIC
                    977: #      MEMORY. THIS MEMORY MUST BE ALLOCATED CONTIGUOUSLY WITH
                    978: #      THE CURRENT DYNAMIC DATA AREA.
                    979: #
                    980: #      THE AMOUNT ALLOCATED IS UP TO THE SYSTEM TO DECIDE. ANY
                    981: #      VALUE IS ACCEPTABLE INCLUDING ZERO IF ALLOCATION IS
                    982: #      IMPOSSIBLE.
                    983: #
                    984: #      JSR  SYSMM            CALL TO GET MORE MEMORY
                    985: #      (XR)                  NUMBER OF ADDITIONAL WORDS OBTAINED
                    986:        #page   
                    987: #
                    988: #      SYSMX -- SUPPLY MXLEN
                    989: #
                    990:        .globl  sysmx           # define external entry point
                    991: #
                    992: #      BECAUSE OF THE METHOD OF GARBAGE COLLECTION, NO SPITBOL
                    993: #      OBJECT IS ALLOWED TO OCCUPY MORE BYTES OF MEMORY THAN
                    994: #      THE INTEGER GIVING THE LOWEST ADDRESS OF DYNAMIC
                    995: #      (GARBAGE COLLECTABLE) MEMORY. MXLEN IS THE NAME USED TO
                    996: #      REFER TO THIS MAXIMUM LENGTH OF AN OBJECT AND FOR MOST
                    997: #      USERS OF MOST IMPLEMENTATIONS, PROVIDED DYNAMIC MEMORY
                    998: #      STARTS AT AN ADDRESS OF AT LEAST A FEW THOUSAND WORDS,
                    999: #      THERE IS NO PROBLEM.
                   1000: #      IF THE DEFAULT STARTING ADDRESS IS LESS THAN SAY 10000 OR
                   1001: #      20000, THEN A LOAD TIME OPTION SHOULD BE PROVIDED WHERE A
                   1002: #      USER CAN REQUEST THAT HE BE ABLE TO CREATE LARGER
                   1003: #      OBJECTS. THIS ROUTINE INFORMS SPITBOL OF THIS REQUEST IF
                   1004: #      ANY. THE VALUE RETURNED IS EITHER AN INTEGER
                   1005: #      REPRESENTING THE DESIRED VALUE OF MXLEN (AND HENCE THE
                   1006: #      MINIMUM DYNAMIC STORE ADDRESS WHICH MAY RESULT IN
                   1007: #      NON-USE OF SOME STORE) OR ZERO IF A DEFAULT IS ACCEPTABLE
                   1008: #      IN WHICH MXLEN IS SET TO THE LOWEST ADDRESS ALLOCATED
                   1009: #      TO DYNAMIC STORE BEFORE COMPILATION STARTS.
                   1010: #      IF A NON-ZERO VALUE IS RETURNED, THIS IS USED FOR KEYWORD
                   1011: #      MAXLNGTH. OTHERWISE THE INITIAL LOW ADDRESS OF DYNAMIC
                   1012: #      MEMORY IS USED FOR THIS KEYWORD.
                   1013: #
                   1014: #      JSR  SYSMX            CALL TO GET MXLEN
                   1015: #      (WA)                  EITHER MXLEN OR 0 FOR DEFAULT
                   1016:        #page   
                   1017: #
                   1018: #      SYSOU -- OUTPUT RECORD
                   1019: #
                   1020:        .globl  sysou           # define external entry point
                   1021: #
                   1022: #      SYSOU IS USED TO WRITE A RECORD TO A FILE PREVIOUSLY
                   1023: #      ASSOCIATED WITH A SYSIO CALL.
                   1024: #
                   1025: #      (WA)                  PTR TO FCBLK OR ZERO
                   1026: #      (XR)                  RECORD TO BE WRITTEN (SCBLK)
                   1027: #      JSR  SYSOU            CALL TO OUTPUT RECORD
                   1028: #      PPM  LOC              FILE FULL OR NO FILE AFTER SYSXI
                   1029: #      PPM  LOC              RETURN HERE IF I/O ERROR
                   1030: #      (WA,WB,WC)            DESTROYED
                   1031: #
                   1032: #      NOTE THAT IT IS THE SYSOU CALL (NOT THE SYSIO CALL) WHICH
                   1033: #      CAUSES THE FILE TO BE OPENED AS REQUIRED FOR THE FIRST
                   1034: #      RECORD OUTPUT TO THE FILE.
                   1035:        #page   
                   1036: #
                   1037: #      SYSPI -- PRINT ON INTERACTIVE CHANNEL
                   1038: #
                   1039:        .globl  syspi           # define external entry point
                   1040: #
                   1041: #      IF SPITBOL IS RUN FROM AN ONLINE TERMINAL, OSINT CAN
                   1042: #      REQUEST THAT MESSAGES SUCH AS COPIES OF COMPILATION
                   1043: #      ERRORS BE SENT TO THE TERMINAL (SEE SYSPP). IF RELEVANT
                   1044: #      REPLY WAS MADE BY SYSPP THEN SYSPI IS CALLED TO SEND SUCH
                   1045: #      MESSAGES TO THE INTERACTIVE CHANNEL.
                   1046: #      SYSPI IS ALSO USED FOR SENDING OUTPUT TO THE TERMINAL
                   1047: #      THROUGH THE SPECIAL VARIABLE NAME, TERMINAL.
                   1048: #
                   1049: #      (XR)                  PTR TO LINE BUFFER (SCBLK)
                   1050: #      (WA)                  LINE LENGTH
                   1051: #      JSR  SYSPI            CALL TO PRINT LINE
                   1052: #      PPM  LOC              FAILURE RETURN
                   1053: #      (WA,WB)               DESTROYED
                   1054:        #page   
                   1055: #
                   1056: #      SYSPP -- OBTAIN PRINT PARAMETERS
                   1057: #
                   1058:        .globl  syspp           # define external entry point
                   1059: #
                   1060: #      SYSPP IS CALLED ONCE DURING COMPILATION TO OBTAIN
                   1061: #      PARAMETERS REQUIRED FOR CORRECT PRINTED OUTPUT FORMAT
                   1062: #      AND TO SELECT OTHER OPTIONS. IT MAY ALSO BE CALLED AGAIN
                   1063: #      AFTER SYSXI WHEN A LOAD MODULE IS RESUMED. IN THIS
                   1064: #      CASE THE VALUE RETURNED IN WA MAY BE LESS THAN OR EQUAL
                   1065: #      TO THAT RETURNED IN INITIAL CALL BUT MAY NOT BE
                   1066: #      GREATER.
                   1067: #      THE INFORMATION RETURNED IS -
                   1068: #      1.   LINE LENGTH IN CHARS FOR STANDARD PRINT FILE
                   1069: #      2.   NO OF LINES/PAGE. 0 IS PREFERABLE FOR A NON-PAGED
                   1070: #           DEVICE (E.G. ONLINE TERMINAL) IN WHICH CASE LISTING
                   1071: #           PAGE THROWS ARE SUPPRESSED AND PAGE HEADERS
                   1072: #           RESULTING FROM -TITLE,-STITL LINES ARE KEPT SHORT.
                   1073: #      3.   AN INITIAL -NOLIST OPTION TO SUPPRESS LISTING UNLESS
                   1074: #           THE PROGRAM CONTAINS AN EXPLICIT -LIST.
                   1075: #      4.   OPTIONS TO SUPPRESS LISTING OF COMPILATION AND/OR
                   1076: #           EXECUTION STATS (USEFUL FOR ESTABLISHED PROGRAMS) -
                   1077: #           COMBINED WITH 3. GIVES POSSIBILITY OF LISTING
                   1078: #           FILE NEVER BEING OPENED.
                   1079: #      5.   OPTION TO HAVE COPIES OF ERRORS SENT TO AN
                   1080: #           INTERACTIVE CHANNEL IN ADDITION TO STANDARD PRINTER.
                   1081: #      6.   OPTION TO KEEP PAGE HEADERS SHORT (E.G. IF LISTING
                   1082: #           TO AN ONLINE TERMINAL).
                   1083: #      7.   AN OPTION TO CHOOSE EXTENDED OR COMPACT LISTING
                   1084: #           FORMAT. IN THE FORMER A PAGE EJECT AND IN THE LATTER
                   1085: #           A FEW LINE FEEDS PRECEDE THE PRINTING OF EACH
                   1086: #           OF-- LISTING, COMPILATION STATISTICS, EXECUTION
                   1087: #           OUTPUT AND EXECUTION STATISTICS.
                   1088: #      8.   AN OPTION TO SUPPRESS EXECUTION AS THOUGH A
                   1089: #           -NOEXECUTE CARD WERE SUPPLIED.
                   1090: #      9.   AN OPTION TO REQUEST THAT NAME /TERMINAL/  BE PRE-
                   1091: #           ASSOCIATED TO AN ONLINE TERMINAL VIA SYSPI AND SYSRI
                   1092: #      10.  AN INTERMEDIATE (STANDARD) LISTING OPTION REQUIRING
                   1093: #           THAT PAGE EJECTS OCCUR IN SOURCE LISTINGS. REDUNDANT
                   1094: #           IF EXTENDED OPTION CHOSEN BUT PARTIALLY EXTENDS
                   1095: #           COMPACT OPTION.
                   1096: #      11.  OPTION TO SUPPRESS SYSID IDENTIFICATION.
                   1097: #
                   1098: #      JSR  SYSPP            CALL TO GET PRINT PARAMETERS
                   1099: #      (WA)                  PRINT LINE LENGTH IN CHARS
                   1100: #      (WB)                  NUMBER OF LINES/PAGE
                   1101: #      (WC)                  BITS VALUE ...JIHGFEDCBA WHERE
                   1102: #                            A = 1 TO SEND ERROR COPY TO INT.CH.
                   1103: #                            B = 1 MEANS STD PRINTER IS INT. CH.
                   1104: #                            C = 1 FOR -NOLIST OPTION
                   1105: #                            D = 1 TO SUPPRESS COMPILN. STATS
                   1106: #                            E = 1 TO SUPPRESS EXECN. STATS
                   1107: #                            F = 1/0 FOR EXTNDED/COMPACT LISTING
                   1108: #                            G = 1 FOR -NOEXECUTE
                   1109: #                            H = 1 PRE-ASSOCIATE /TERMINAL/
                   1110: #                            I = 1 FOR STANDARD LISTING OPTION.
                   1111: #                            J = 1 SUPPRESSES LISTING HEADER
                   1112:        #page   
                   1113: #
                   1114: #      SYSPR -- PRINT LINE ON STANDARD OUTPUT FILE
                   1115: #
                   1116:        .globl  syspr           # define external entry point
                   1117: #
                   1118: #      SYSPR IS USED TO PRINT A SINGLE LINE ON THE STANDARD
                   1119: #      OUTPUT FILE.
                   1120: #
                   1121: #      (XR)                  POINTER TO LINE BUFFER (SCBLK)
                   1122: #      (WA)                  LINE LENGTH
                   1123: #      JSR  SYSPR            CALL TO PRINT LINE
                   1124: #      PPM  LOC              TOO MUCH O/P OR NO FILE AFTER SYSXI
                   1125: #      (WA,WB)               DESTROYED
                   1126: #
                   1127: #      THE BUFFER POINTED TO IS THE LENGTH OBTAINED FROM THE
                   1128: #      SYSPP CALL AND IS FILLED OUT WITH TRAILING BLANKS. THE
                   1129: #      VALUE IN WA IS THE ACTUAL LINE LENGTH WHICH MAY BE LESS
                   1130: #      THAN THE MAXIMUM LINE LENGTH POSSIBLE. THERE IS NO SPACE
                   1131: #      CONTROL ASSOCIATED WITH THE LINE, ALL LINES ARE PRINTED
                   1132: #      SINGLE SPACED. NOTE THAT NULL LINES (WA=0) ARE POSSIBLE
                   1133: #      IN WHICH CASE A BLANK LINE IS TO BE PRINTED.
                   1134: #
                   1135: #      THE ERROR EXIT IS USED FOR SYSTEMS WHICH LIMIT THE AMOUNT
                   1136: #      OF PRINTED OUTPUT. IF POSSIBLE, PRINTING SHOULD BE
                   1137: #      PERMITTED AFTER THIS CONDITION HAS BEEN SIGNALLED ONCE TO
                   1138: #      ALLOW FOR DUMP AND OTHER DIAGNOSTIC INFORMATION.
                   1139: #      ASSUMING THIS TO BE POSSIBLE, SPITBOL MAY MAKE MORE SYSPR
                   1140: #      CALLS. IF THE ERROR RETURN OCCURS ANOTHER TIME, EXECUTION
                   1141: #      IS TERMINATED BY A CALL OF SYSEJ WITH ENDING CODE 998.
                   1142:        #page   
                   1143: #
                   1144: #      SYSRD -- READ RECORD FROM STANDARD INPUT FILE
                   1145: #
                   1146:        .globl  sysrd           # define external entry point
                   1147: #
                   1148: #      SYSRD IS USED TO READ A RECORD FROM THE STANDARD INPUT
                   1149: #      FILE. THE BUFFER PROVIDED IS AN SCBLK FOR A STRING THE
                   1150: #      LENGTH OF WHICH IN CHARACTERS IS GIVEN IN WC, THIS
                   1151: #      CORRESPONDING TO THE MAXIMUM LENGTH OF STRING WHICH
                   1152: #      SPITBOL IS PREPARED TO RECEIVE. AT COMPILE TIME IT
                   1153: #      CORRESPONDS TO XXX IN THE MOST RECENT -INXXX CARD
                   1154: #      (DEFAULT 72) AND AT EXECUTION TIME TO THE MOST RECENT
                   1155: #      ,R$R$ (RECORD LENGTH) IN THE THIRD ARG OF AN INPUT()
                   1156: #      STATEMENT FOR THE STANDARD INPUT FILE (DEFAULT 80).
                   1157: #      IF FEWER THAN (WC) CHARACTERS ARE READ, THE LENGTH
                   1158: #      FIELD OF THE SCBLK MUST BE ADJUSTED BEFORE RETURNING
                   1159: #      UNLESS THE BUFFER IS RIGHT PADDED WITH ZEROES.
                   1160: #      IT IS ALSO PERMISSIBLE TO TAKE THE ALTERNATIVE RETURN
                   1161: #      AFTER SUCH AN ADJUSTMENT HAS BEEN MADE.
                   1162: #      SPITBOL MAY CONTINUE TO MAKE CALLS AFTER AN ENDFILE
                   1163: #      RETURN SO THIS ROUTINE SHOULD BE PREPARED TO MAKE
                   1164: #      REPEATED ENDFILE RETURNS.
                   1165: #
                   1166: #      (XR)                  POINTER TO BUFFER (SCBLK PTR)
                   1167: #      (WC)                  LENGTH OF BUFFER IN CHARACTERS
                   1168: #      JSR  SYSRD            CALL TO READ LINE
                   1169: #      PPM  LOC              ENDFILE OR NO I/P FILE AFTER SYSXI
                   1170: #      (WA,WB,WC)            DESTROYED
                   1171:        #page   
                   1172: #
                   1173: #      SYSRI -- READ RECORD FROM INTERACTIVE CHANNEL
                   1174: #
                   1175:        .globl  sysri           # define external entry point
                   1176: #
                   1177: #      READS A RECORD FROM ONLINE TERMINAL FOR SPITBOL VARIABLE,
                   1178: #      TERMINAL. IF ONLINE TERMINAL IS UNAVAILABLE THEN CODE THE
                   1179: #      ENDFILE RETURN ONLY.
                   1180: #      THE BUFFER PROVIDED IS OF LENGTH 120 CHARACTERS. SYSRI
                   1181: #      SHOULD REPLACE THE COUNT IN THE SECOND WORD OF THE SCBLK
                   1182: #      BY THE ACTUAL CHARACTER COUNT UNLESS BUFFER IS RIGHT
                   1183: #      PADDED WITH ZEROES.
                   1184: #      IT IS ALSO PERMISSIBLE TO TAKE THE ALTERNATIVE
                   1185: #      RETURN AFTER ADJUSTING THE COUNT.
                   1186: #      THE END OF FILE RETURN MAY BE USED IF THIS MAKES
                   1187: #      SENSE ON THE TARGET MACHINE (E.G. IF THERE IS AN
                   1188: #      EOF CHARACTER.)
                   1189: #
                   1190: #      (XR)                  PTR TO 120 CHAR BUFFER (SCBLK PTR)
                   1191: #      JSR  SYSRI            CALL TO READ LINE FROM TERMINAL
                   1192: #      PPM  LOC              END OF FILE RETURN
                   1193: #      (WA,WB,WC)            MAY BE DESTROYED
                   1194:        #page   
                   1195: #
                   1196: #      SYSRW -- REWIND FILE
                   1197: #
                   1198:        .globl  sysrw           # define external entry point
                   1199: #
                   1200: #      SYSRW IS USED TO REWIND A FILE I.E. REPOSITION THE FILE
                   1201: #      AT THE START BEFORE THE FIRST RECORD. THE FILE SHOULD BE
                   1202: #      CLOSED AND THE NEXT READ OR WRITE CALL WILL OPEN THE
                   1203: #      FILE AT THE START.
                   1204: #
                   1205: #      (WA)                  PTR TO FCBLK OR ZERO
                   1206: #      (XR)                  REWIND ARG (SCBLK PTR)
                   1207: #      JSR  SYSRW            CALL TO REWIND FILE
                   1208: #      PPM  LOC              RETURN HERE IF FILE DOES NOT EXIST
                   1209: #      PPM  LOC              RETURN HERE IF REWIND NOT ALLOWED
                   1210: #      PPM  LOC              RETURN HERE IF I/O ERROR
                   1211:        #page   
                   1212: #
                   1213: #      SYSST -- SET FILE POINTER
                   1214: #
                   1215:        .globl  sysst           # define external entry point
                   1216: #
                   1217: #      SYSST IS CALLED TO CHANGE THE POSITION OF A FILE
                   1218: #      POINTER. THIS IS ACCOMPLISHED IN A SYSTEM DEPENDENT
                   1219: #      MANNER, AND THUS THE 2ND AND 3RD ARGUMENTS ARE PASSED
                   1220: #      UNCONVERTED.
                   1221: #
                   1222: #      (WA)                  FCBLK POINTER
                   1223: #      (WB)                  2ND ARGUMENT
                   1224: #      (WC)                  3RD ARGUMENT
                   1225: #      JSR  SYSST            CALL TO SET FILE POINTER
                   1226: #      PPM  LOC              RETURN HERE IF INVALID 2ND ARG
                   1227: #      PPM  LOC              RETURN HERE IF INVALID 3RD ARG
                   1228: #      PPM  LOC              RETURN HERE IF FILE DOES NOT EXIST
                   1229: #      PPM  LOC              RETURN HERE IF SET NOT ALLOWED
                   1230: #      PPM  LOC              RETURN HERE IF I/O ERROR
                   1231: #
                   1232:        #page   
                   1233: #
                   1234: #      SYSTM -- GET EXECUTION TIME SO FAR
                   1235: #
                   1236:        .globl  systm           # define external entry point
                   1237: #
                   1238: #      SYSTM IS USED TO OBTAIN THE AMOUNT OF EXECUTION TIME
                   1239: #      USED SO FAR SINCE SPITBOL WAS GIVEN CONTROL. THE UNITS
                   1240: #      ARE DESCRIBED AS MILLISECONDS IN THE SPITBOL OUTPUT, BUT
                   1241: #      THE EXACT MEANING IS SYSTEM DEPENDENT. WHERE APPROPRIATE,
                   1242: #      THIS VALUE SHOULD RELATE TO PROCESSOR RATHER THAN CLOCK
                   1243: #      TIMING VALUES.
                   1244: #
                   1245: #      JSR  SYSTM            CALL TO GET TIMER VALUE
                   1246: #      (IA)                  TIME SO FAR IN MILLISECONDS
                   1247:        #page   
                   1248: #
                   1249: #      SYSTT -- TRACE TOGGLE
                   1250: #
                   1251:        .globl  systt           # define external entry point
                   1252: #
                   1253: #      CALLED BY SPITBOL FUNCTION TRACE() WITH NO ARGS TO
                   1254: #      TOGGLE THE SYSTEM TRACE SWITCH.  THIS PERMITS TRACING OF
                   1255: #      LABELS IN SPITBOL CODE TO BE TURNED ON OR OFF.
                   1256: #
                   1257: #      JSR  SYSTT            CALL TO TOGGLE TRACE SWITCH
                   1258:        #page   
                   1259: #
                   1260: #      SYSUL -- UNLOAD EXTERNAL FUNCTION
                   1261: #
                   1262:        .globl  sysul           # define external entry point
                   1263: #
                   1264: #      SYSUL IS USED TO UNLOAD A FUNCTION PREVIOUSLY
                   1265: #      LOADED WITH A CALL TO SYSLD.
                   1266: #
                   1267: #      (XR)                  PTR TO CONTROL BLOCK (EFBLK)
                   1268: #      JSR  SYSUL            CALL TO UNLOAD FUNCTION
                   1269: #
                   1270: #      THE FUNCTION CANNOT BE CALLED FOLLOWING A SYSUL CALL
                   1271: #      UNTIL ANOTHER SYSLD CALL IS MADE FOR THE SAME FUNCTION.
                   1272: #
                   1273: #      THE EFBLK CONTAINS THE FUNCTION CODE POINTER AND ALSO A
                   1274: #      POINTER TO THE VRBLK CONTAINING THE FUNCTION NAME (SEE
                   1275: #      DEFINITIONS AND DATA STRUCTURES SECTION).
                   1276:        #page   
                   1277: #
                   1278: #      SYSXI -- EXIT TO PRODUCE LOAD MODULE
                   1279: #
                   1280:        .globl  sysxi           # define external entry point
                   1281: #
                   1282: #      WHEN SYSXI IS CALLED, XL CONTAINS EITHER A STRING POINTER
                   1283: #      OR ZERO. IN THE FORMER CASE, THE STRING GIVES THE
                   1284: #      CHARACTER NAME OF A PROGRAM. THE INTENTION IS THAT
                   1285: #      SPITBOL EXECUTION SHOULD BE TERMINATED FORTHWITH AND
                   1286: #      THE NAMED PROGRAM LOADED AND EXECUTED. THIS TYPE OF CHAIN
                   1287: #      EXECUTION IS VERY SYSTEM DEPENDENT AND IMPLEMENTORS MAY
                   1288: #      CHOOSE TO OMIT IT OR FIND IT IMPOSSIBLE TO PROVIDE.
                   1289: #      IF (XL) IS ZERO,IA CONTAINS ONE OF THE FOLLOWING INTEGERS
                   1290: #
                   1291: #      -1, -2, -3
                   1292: #           CREATE IF POSSIBLE A LOAD MODULE CONTAINING ONLY THE
                   1293: #           IMPURE AREA OF MEMORY WHICH NEEDS TO BE LOADED WITH
                   1294: #           A COMPATIBLE PURE SEGMENT FOR SUBSEQUENT EXECUTIONS.
                   1295: #           VERSION NUMBERS TO CHECK COMPATIBILITY SHOULD BE
                   1296: #           KEPT IN BOTH SEGMENTS AND CHECKED ON LOADING.
                   1297: #           TO ASSIST WITH THIS CHECK, (XR) ON ENTRY IS A
                   1298: #           POINTER TO AN SCBLK CONTAINING THE SPITBOL MAJOR
                   1299: #           VERSION NUMBER V.V (SEE SYSID).
                   1300: #
                   1301: #      0    IF POSSIBLE, RETURN CONTROL TO JOB CONTROL
                   1302: #           COMMAND LEVEL. THE EFFECT IF AVAILABLE WILL BE
                   1303: #           SYSTEM DEPENDENT.
                   1304: #
                   1305: #      +1, +2, +3
                   1306: #           CREATE IF POSSIBLE A LOAD MODULE FROM ALL OF
                   1307: #           MEMORY. IT SHOULD BE POSSIBLE TO LOAD AND EXECUTE
                   1308: #           THIS MODULE DIRECTLY.
                   1309: #
                   1310: #      IN THE CASE OF SAVED LOAD MODULES, THE STATUS OF OPEN
                   1311: #      FILES IS NOT PRESERVED AND IMPLEMENTORS MAY CHOOSE TO
                   1312: #      OFFER MEANS OF ATTACHING FILES BEFORE EXECUTION OF LOAD
                   1313: #      MODULES STARTS OR LEAVE IT TO THE USER TO INCLUDE
                   1314: #      SUITABLE INPUT(), OUTPUT() CALLS IN HIS PROGRAM.
                   1315: #      SYSXI SHOULD MAKE A NOTE THAT NO I/O CHANNELS,
                   1316: #      INCLUDING STANDARD FILES, HAVE FILES ATTACHED SO THAT
                   1317: #      CALLS OF SYSIN, SYSOU, SYSPR, SYSRD SHOULD FAIL UNLESS
                   1318: #      NEW ASSOCIATIONS ARE MADE FOR THE LOAD MODULE.
                   1319: #      AT LEAST IN THE CASE OF THE STANDARD OUTPUT FILE, IT IS
                   1320: #      RECOMMENDED THAT EITHER THE USER BE REQUIRED TO ATTACH
                   1321: #      A FILE OR THAT A DEFAULT FILE IS ATTACHED, SINCE THE
                   1322: #      PROBLEM OF ERROR MESSAGES GENERATED BY THE LOAD MODULE
                   1323: #      IS OTHERWISE SEVERE. AS A LAST RESORT, IF SPITBOL
                   1324: #      ATTEMPTS TO WRITE TO THE STANDARD OUTPUT FILE AND GETS A
                   1325: #      REPLY INDICATING THAT SUCH OUPUT IS UNACCEPTABLE IT STOPS
                   1326: #      BY USING AN ENTRY TO SYSEJ WITH ENDING CODE 998.
                   1327: #      AS DESCRIBED BELOW, PASSING OF SOME ARGUMENTS MAKES IT
                   1328: #      CLEAR THAT LOAD MODULE WILL USE A STANDARD OUTPUT FILE.
                   1329: #
                   1330: #      IF USE IS MADE OF FCBLKS FOR I/O ASSOCIATION, SPITBOL
                   1331: #      BUILDS A CHAIN SO THAT THOSE IN USE MAY BE FOUND IN SYSXI
                   1332: #      AND SYSEJ. THE NODES ARE 4 WORDS LONG. THIRD WORD
                   1333: #      CONTAINS LINK TO NEXT NODE OR 0, FOURTH WORD CONTAINS
                   1334: #      FCBLK POINTER.
                   1335:        #page   
                   1336: #
                   1337: #      SYSXI (CONTINUED)
                   1338: #
                   1339: #      (XL)                  ZERO OR SCBLK PTR
                   1340: #      (XR)                  PTR TO V.V SCBLK
                   1341: #      (IA)                  SIGNED INTEGER ARGUMENT
                   1342: #      (WB)                  0 OR PTR TO HEAD OF FCBLK CHAIN
                   1343: #      JSR  SYSXI            CALL TO EXIT
                   1344: #      PPM  LOC              REQUESTED ACTION NOT POSSIBLE
                   1345: #      PPM  LOC              ACTION CAUSED IRRECOVERABLE ERROR
                   1346: #      (REGISTERS)           SHOULD BE PRESERVED OVER CALL
                   1347: #
                   1348: #      LOADING AND RUNNING THE LOAD MODULE OR RETURNING FROM
                   1349: #      JCL COMMAND LEVEL CAUSES EXECUTION TO RESUME AT THE POINT
                   1350: #      AFTER THE ERROR RETURNS WHICH FOLLOW THE CALL OF SYSXI.
                   1351: #      THE VALUE PASSED AS EXIT ARGUMENT IS USED TO INDICATE
                   1352: #      OPTIONS REQUIRED ON RESUMPTION OF LOAD MODULE.
                   1353: #      +1 OR -1 REQUIRE THAT ON RESUMPTION, SYSID AND SYSPP BE
                   1354: #      CALLED AND A HEADING PRINTED ON THE STANDARD OUTPUT FILE.
                   1355: #      +2 OR -2 INDICATE THAT SYSPP WILL BE CALLED BUT NOT SYSID
                   1356: #      AND NO HEADING WILL BE PUT ON STANDARD OUTPUT FILE.
                   1357: #      ABOVE OPTIONS HAVE THE OBVIOUS IMPLICATION THAT A
                   1358: #      STANDARD O/P FILE MUST BE PROVIDED FOR THE LOAD MODULE.
                   1359: #      +3 OR -3 INDICATE CALLS OF NEITHER SYSID NOR SYSPP
                   1360: #      AND NO HEADING WILL BE PLACED ON STANDARD OUTPUT FILE.
                   1361: #      NO RETURN FROM SYSXI IS POSSIBLE IF ANOTHER PROGRAM
                   1362: #      IS LOADED AND ENTERED.
                   1363:        #page   
                   1364: #
                   1365: #      INTRODUCE THE INTERNAL PROCEDURES.
                   1366: #
                   1367:        .globl  acess
                   1368:        .globl  acomp
                   1369:        .globl  alloc
                   1370:        .globl  alobf
                   1371:        .globl  alocs
                   1372:        .globl  alost
                   1373:        .globl  apndb
                   1374:        .globl  arith
                   1375:        .globl  asign
                   1376:        .globl  asinp
                   1377:        .globl  blkln
                   1378:        .globl  cdgcg
                   1379:        .globl  cdgex
                   1380:        .globl  cdgnm
                   1381:        .globl  cdgvl
                   1382:        .globl  cdwrd
                   1383:        .globl  cmgen
                   1384:        .globl  cmpil
                   1385:        .globl  cncrd
                   1386:        .globl  copyb
                   1387:        .globl  dffnc
                   1388:        .globl  dtach
                   1389:        .globl  dtype
                   1390:        .globl  dumpr
                   1391:        .globl  ermsg
                   1392:        .globl  ertex
                   1393:        .globl  evali
                   1394:        .globl  evalp
                   1395:        .globl  evals
                   1396:        .globl  evalx
                   1397:        .globl  exbld
                   1398:        .globl  expan
                   1399:        .globl  expap
                   1400:        .globl  expdm
                   1401:        .globl  expop
                   1402:        .globl  flstg
                   1403:        .globl  gbcol
                   1404:        .globl  gbcpf
                   1405:        .globl  gtarr
                   1406:        #page   
                   1407:        .globl  gtcod
                   1408:        .globl  gtexp
                   1409:        .globl  gtint
                   1410:        .globl  gtnum
                   1411:        .globl  gtnvr
                   1412:        .globl  gtpat
                   1413:        .globl  gtrea
                   1414:        .globl  gtsmi
                   1415:        .globl  gtstg
                   1416:        .globl  gtvar
                   1417:        .globl  hashs
                   1418:        .globl  icbld
                   1419:        .globl  ident
                   1420:        .globl  inout
                   1421:        .globl  insbf
                   1422:        .globl  iofcb
                   1423:        .globl  ioppf
                   1424:        .globl  ioput
                   1425:        .globl  ktrex
                   1426:        .globl  kwnam
                   1427:        .globl  lcomp
                   1428:        .globl  listr
                   1429:        .globl  listt
                   1430:        .globl  nexts
                   1431:        .globl  patin
                   1432:        .globl  patst
                   1433:        .globl  pbild
                   1434:        .globl  pconc
                   1435:        .globl  pcopy
                   1436:        .globl  prflr
                   1437:        .globl  prflu
                   1438:        .globl  prpar
                   1439:        .globl  prtch
                   1440:        .globl  prtic
                   1441:        .globl  prtis
                   1442:        .globl  prtin
                   1443:        .globl  prtmi
                   1444:        .globl  prtmx
                   1445:        .globl  prtnl
                   1446:        .globl  prtnm
                   1447:        .globl  prtnv
                   1448:        .globl  prtpg
                   1449:        .globl  prtps
                   1450:        .globl  prtsn
                   1451:        .globl  prtst
                   1452:        #page   
                   1453:        .globl  prttr
                   1454:        .globl  prtvl
                   1455:        .globl  prtvn
                   1456:        .globl  rcbld
                   1457:        .globl  readr
                   1458:        .globl  sbstr
                   1459:        .globl  scane
                   1460:        .globl  scngf
                   1461:        .globl  setvr
                   1462:        .globl  sorta
                   1463:        .globl  sortc
                   1464:        .globl  sortf
                   1465:        .globl  sorth
                   1466:        .globl  tfind
                   1467:        .globl  trace
                   1468:        .globl  trbld
                   1469:        .globl  trimr
                   1470:        .globl  trxeq
                   1471:        .globl  xscan
                   1472:        .globl  xscni
                   1473: #
                   1474: #      INTRODUCE THE INTERNAL ROUTINES
                   1475: #
                   1476:        .globl  arref
                   1477:        .globl  cfunc
                   1478:        .globl  exfal
                   1479:        .globl  exint
                   1480:        .globl  exits
                   1481:        .globl  exixr
                   1482:        .globl  exnam
                   1483:        .globl  exnul
                   1484:        .globl  exrea
                   1485:        .globl  exsid
                   1486:        .globl  exvnm
                   1487:        .globl  failp
                   1488:        .globl  flpop
                   1489:        .globl  indir
                   1490:        .globl  match
                   1491:        .globl  retrn
                   1492:        .globl  stcov
                   1493:        .globl  stmgo
                   1494:        .globl  stopr
                   1495:        .globl  succp
                   1496:        .globl  sysab
                   1497:        .globl  systu
                   1498:        #title  s p i t b o l -- definitions and data structures
                   1499:        #sec                    # start of definitions section
                   1500: #
                   1501: #      DEFINITIONS OF MACHINE PARAMETERS
                   1502: #
                   1503: #      THE MINIMAL TRANSLATOR SHOULD SUPPLY APPROPRIATE VALUES
                   1504: #      FOR THE PARTICULAR TARGET MACHINE FOR ALL THE
                   1505: #      EQU  *
                   1506: #      DEFINITIONS GIVEN AT THE START OF THIS SECTION.
                   1507: #
                   1508:        .set    cfp$a,256       # number of characters in alphabet
                   1509: #
                   1510:        .set    cfp$b,4         # bytes/word addressing factor
                   1511: #
                   1512:        .set    cfp$c,4         # number of characters per word
                   1513: #
                   1514:        .set    cfp$f,8         # offset in bytes to chars in
                   1515: #                            SCBLK. SEE SCBLK FORMAT.
                   1516: #
                   1517:        .set    cfp$i,1         # number of words in integer constant
                   1518: #
                   1519:        .set    cfp$m,0x7fffffff# max positive integer in one word
                   1520: #
                   1521:        .set    cfp$n,32        # number of bits in one word
                   1522: #
                   1523: #      THE FOLLOWING DEFINITIONS REQUIRE THE SUPPLY OF EITHER
                   1524: #      A SINGLE PARAMETER IF REAL ARITHMETIC IS OMITTED OR
                   1525: #      THREE PARAMETERS IF REAL ARITHMETIC IS INCLUDED.
                   1526: #
                   1527: #
                   1528:        .set    cfp$r,1         # number of words in real constant
                   1529: #
                   1530:        .set    cfp$s,6         # number of sig digs for real output
                   1531: #
                   1532:        .set    cfp$x,2         # max digits in real exponent
                   1533: #
                   1534:        .set    mxdgs,cfp$s+cfp$x# max digits in real number
                   1535: #
                   1536:        .set    nstmx,mxdgs+5   # max space for real (for +0.e+)
                   1537: #
                   1538: #      THE FOLLOWING DEFINITION FOR CFP$U SUPPLIES A REALISTIC
                   1539: #      UPPER BOUND ON THE SIZE OF THE ALPHABET.  CFP$U IS USED
                   1540: #      TO SAVE SPACE IN THE SCANE BSW-IFF-ESW TABLE AND TO EASE
                   1541: #      TRANSLATION STORAGE REQUIREMENTS.
                   1542: #
                   1543:        .set    cfp$u,128       # realistic upper bound on alphabet
                   1544:        #page   
                   1545: #
                   1546: #      ENVIRONMENT PARAMETERS
                   1547: #
                   1548: #      THE SPITBOL PROGRAM IS ESSENTIALLY INDEPENDENT OF
                   1549: #      THE DEFINITIONS OF THESE PARAMETERS. HOWEVER, THE
                   1550: #      EFFICIENCY OF THE SYSTEM MAY BE AFFECTED. CONSEQUENTLY,
                   1551: #      THESE PARAMETERS MAY REQUIRE TUNING FOR A GIVEN VERSION
                   1552: #      THE VALUES GIVEN IN COMMENTS HAVE BEEN SUCCESSFULLY USED.
                   1553: #
                   1554: #      E$SRS IS THE NUMBER OF WORDS TO RESERVE AT THE END OF
                   1555: #      STORAGE FOR END OF RUN PROCESSING. IT SHOULD BE
                   1556: #      SET AS SMALL AS POSSIBLE WITHOUT CAUSING MEMORY OVERFLOW
                   1557: #      IN CRITICAL SITUATIONS (E.G. MEMORY OVERFLOW TERMINATION)
                   1558: #      AND SHOULD THUS RESERVE SUFFICIENT SPACE AT LEAST FOR
                   1559: #      AN SCBLK CONTAINING SAY 30 CHARACTERS.
                   1560: #
                   1561:        .set    e$srs,50        # 30 words
                   1562: #
                   1563: #      E$STS IS THE NUMBER OF WORDS GRABBED IN A CHUNK WHEN
                   1564: #      STORAGE IS ALLOCATED IN THE STATIC REGION. THE MINIMUM
                   1565: #      PERMITTED VALUE IS 256/CFP$B. LARGER VALUES WILL LEAD
                   1566: #      TO INCREASED EFFICIENCY AT THE COST OF WASTING MEMORY.
                   1567: #
                   1568:        .set    e$sts,512       # 500 words
                   1569: #
                   1570: #      E$CBS IS THE SIZE OF CODE BLOCK ALLOCATED INITIALLY AND
                   1571: #      THE EXPANSION INCREMENT IF OVERFLOW OCCURS. IF THIS VALUE
                   1572: #      IS TOO SMALL OR TOO LARGE, EXCESSIVE GARBAGE COLLECTIONS
                   1573: #      WILL OCCUR DURING COMPILATION AND MEMORY MAY BE LOST
                   1574: #      IN THE CASE OF A TOO LARGE VALUE.
                   1575: #
                   1576:        .set    e$cbs,512       # 500 words
                   1577: #
                   1578: #      E$HNB IS THE NUMBER OF BUCKET HEADERS IN THE VARIABLE
                   1579: #      HASH TABLE. IT SHOULD ALWAYS BE ODD. LARGER VALUES WILL
                   1580: #      SPEED UP COMPILATION AND INDIRECT REFERENCES AT THE
                   1581: #      EXPENSE OF ADDITIONAL STORAGE FOR THE HASH TABLE ITSELF.
                   1582: #
                   1583:        .set    e$hnb,253       # 127 bucket headers
                   1584: #
                   1585: #      E$HNW IS THE MAXIMUM NUMBER OF WORDS OF A STRING
                   1586: #      NAME WHICH PARTICIPATE IN THE STRING HASH ALGORITHM.
                   1587: #      LARGER VALUES GIVE A BETTER HASH AT THE EXPENSE OF TAKING
                   1588: #      LONGER TO COMPUTE THE HASH. THERE IS SOME OPTIMAL VALUE.
                   1589: #
                   1590:        .set    e$hnw,3         # 6 words
                   1591: #
                   1592: #      E$FSP .  IF THE AMOUNT OF FREE SPACE LEFT AFTER A GARBAGE
                   1593: #      COLLECTION IS SMALL COMPARED TO THE TOTAL AMOUNT OF SPACE
                   1594: #      IN USE GARBAGE COLLECTOR THRASHING IS LIKELY TO OCCUR AS
                   1595: #      THIS SPACE IS USED UP.  E$FSP IS A MEASURE OF THE
                   1596: #      MINIMUM PERCENTAGE OF DYNAMIC MEMORY LEFT AS FREE SPACE
                   1597: #      BEFORE THE SYSTEM ROUTINE SYSMM IS CALLED TO TRY TO
                   1598: #      OBTAIN MORE MEMORY.
                   1599: #
                   1600:        .set    e$fsp,20        # 15 percent
                   1601:        #page   
                   1602: #
                   1603: #      DEFINITIONS OF CODES FOR LETTERS
                   1604: #
                   1605:        .set    ch$la,65        # letter a
                   1606:        .set    ch$lb,66        # letter b
                   1607:        .set    ch$lc,67        # letter c
                   1608:        .set    ch$ld,68        # letter d
                   1609:        .set    ch$le,69        # letter e
                   1610:        .set    ch$lf,70        # letter f
                   1611:        .set    ch$lg,71        # letter g
                   1612:        .set    ch$lh,72        # letter h
                   1613:        .set    ch$li,73        # letter i
                   1614:        .set    ch$lj,74        # letter j
                   1615:        .set    ch$lk,75        # letter k
                   1616:        .set    ch$ll,76        # letter l
                   1617:        .set    ch$lm,77        # letter m
                   1618:        .set    ch$ln,78        # letter n
                   1619:        .set    ch$lo,79        # letter o
                   1620:        .set    ch$lp,80        # letter p
                   1621:        .set    ch$lq,81        # letter q
                   1622:        .set    ch$lr,82        # letter r
                   1623:        .set    ch$ls,83        # letter s
                   1624:        .set    ch$lt,84        # letter t
                   1625:        .set    ch$lu,85        # letter u
                   1626:        .set    ch$lv,86        # letter v
                   1627:        .set    ch$lw,87        # letter w
                   1628:        .set    ch$lx,88        # letter x
                   1629:        .set    ch$ly,89        # letter y
                   1630:        .set    ch$l$,90        # letter z
                   1631: #
                   1632: #      DEFINITIONS OF CODES FOR DIGITS
                   1633: #
                   1634:        .set    ch$d0,48        # digit 0
                   1635:        .set    ch$d1,49        # digit 1
                   1636:        .set    ch$d2,50        # digit 2
                   1637:        .set    ch$d3,51        # digit 3
                   1638:        .set    ch$d4,52        # digit 4
                   1639:        .set    ch$d5,53        # digit 5
                   1640:        .set    ch$d6,54        # digit 6
                   1641:        .set    ch$d7,55        # digit 7
                   1642:        .set    ch$d8,56        # digit 8
                   1643:        .set    ch$d9,57        # digit 9
                   1644:        #page   
                   1645: #
                   1646: #      DEFINITIONS OF CODES FOR SPECIAL CHARACTERS
                   1647: #
                   1648: #      THE NAMES OF THESE CHARACTERS ARE RELATED TO THEIR
                   1649: #      ORIGINAL REPRESENTATION IN THE EBCDIC SET CORRESPONDING
                   1650: #      TO THE DESCRIPTION IN STANDARD SNOBOL4 MANUALS AND TEXTS.
                   1651: #
                   1652:        .set    ch$am,38        # keyword operator (ampersand)
                   1653:        .set    ch$as,42        # multiplication symbol (asterisk)
                   1654:        .set    ch$at,64        # cursor position operator (at)
                   1655:        .set    ch$bb,60        # left array bracket (less than)
                   1656:        .set    ch$bl,32        # blank
                   1657:        .set    ch$br,124       # alternation operator (vertical bar)
                   1658:        .set    ch$cl,58        # goto symbol (colon)
                   1659:        .set    ch$cm,44        # comma
                   1660:        .set    ch$dl,36        # indirection operator (dollar)
                   1661:        .set    ch$dt,46        # name operator (dot)
                   1662:        .set    ch$dq,34        # double quote
                   1663:        .set    ch$eq,61        # equal sign
                   1664:        .set    ch$ex,33        # exponentiation operator (exclm)
                   1665:        .set    ch$mn,45        # minus sign
                   1666:        .set    ch$nm,35        # number sign
                   1667:        .set    ch$nt,126       # negation operator (not)
                   1668:        .set    ch$pc,37        # percent
                   1669:        .set    ch$pl,43        # plus sign
                   1670:        .set    ch$pp,40        # left parenthesis
                   1671:        .set    ch$rb,62        # right array bracket (grtr than)
                   1672:        .set    ch$rp,41        # right parenthesis
                   1673:        .set    ch$qu,63        # interrogation operator (question)
                   1674:        .set    ch$sl,47        # slash
                   1675:        .set    ch$sm,59        # semicolon
                   1676:        .set    ch$sq,39        # single quote
                   1677:        .set    ch$un,95        # special identifier char (underline)
                   1678:        .set    ch$ob,91        # opening bracket
                   1679:        .set    ch$cb,93        # closing bracket
                   1680:        #page   
                   1681: #
                   1682: #      REMAINING CHARS ARE OPTIONAL ADDITIONS TO THE STANDARDS.
                   1683: #
                   1684: #      TAB CHARACTERS - SYNTACTICALLY EQUIVALENT TO BLANK
                   1685: #
                   1686:        .set    ch$ht,9         # horizontal tab
                   1687: #
                   1688: #      LOWER CASE OR SHIFTED CASE ALPHABETIC CHARS
                   1689: #
                   1690:        .set    ch$$a,97        # shifted a
                   1691:        .set    ch$$b,98        # shifted b
                   1692:        .set    ch$$c,99        # shifted c
                   1693:        .set    ch$$d,100       # shifted d
                   1694:        .set    ch$$e,101       # shifted e
                   1695:        .set    ch$$f,102       # shifted f
                   1696:        .set    ch$$g,103       # shifted g
                   1697:        .set    ch$$h,104       # shifted h
                   1698:        .set    ch$$i,105       # shifted i
                   1699:        .set    ch$$j,106       # shifted j
                   1700:        .set    ch$$k,107       # shifted k
                   1701:        .set    ch$$l,108       # shifted l
                   1702:        .set    ch$$m,109       # shifted m
                   1703:        .set    ch$$n,110       # shifted n
                   1704:        .set    ch$$o,111       # shifted o
                   1705:        .set    ch$$p,112       # shifted p
                   1706:        .set    ch$$q,113       # shifted q
                   1707:        .set    ch$$r,114       # shifted r
                   1708:        .set    ch$$s,115       # shifted s
                   1709:        .set    ch$$t,116       # shifted t
                   1710:        .set    ch$$u,117       # shifted u
                   1711:        .set    ch$$v,118       # shifted v
                   1712:        .set    ch$$w,119       # shifted w
                   1713:        .set    ch$$x,120       # shifted x
                   1714:        .set    ch$$y,121       # shifted y
                   1715:        .set    ch$$$,122       # shifted z
                   1716: #      IF A DELIMITER OTHER THAN CH$CM MUST BE USED IN
                   1717: #      THE THIRD ARGUMENT OF INPUT(),OUTPUT() THEN .CIOD SHOULD
                   1718: #      BE DEFINED AND A PARAMETER SUPPLIED FOR IODEL.
                   1719: #
                   1720:        .set    iodel,0
                   1721:        #page   
                   1722: #
                   1723: #      DATA BLOCK FORMATS AND DEFINITIONS
                   1724: #
                   1725: #      THE FOLLOWING SECTIONS DESCRIBE THE DETAILED FORMAT OF
                   1726: #      ALL POSSIBLE DATA BLOCKS IN STATIC AND DYNAMIC MEMORY.
                   1727: #
                   1728: #      EVERY BLOCK HAS A NAME OF THE FORM XXBLK WHERE XX IS A
                   1729: #      UNIQUE TWO CHARACTER IDENTIFIER. THE FIRST WORD OF EVERY
                   1730: #      BLOCK MUST CONTAIN A POINTER TO A PROGRAM LOCATION IN THE
                   1731: #      INTERPRETOR WHICH IS IMMEDIATELY PRECEDED BY AN ADDRESS
                   1732: #      CONSTANT CONTAINING THE VALUE BL$XX WHERE XX IS THE BLOCK
                   1733: #      IDENTIFIER. THIS PROVIDES A UNIFORM MECHANISM FOR
                   1734: #      DISTINGUISHING BETWEEN THE VARIOUS BLOCK TYPES.
                   1735: #
                   1736: #      IN SOME CASES, THE CONTENTS OF THE FIRST WORD IS CONSTANT
                   1737: #      FOR A GIVEN BLOCK TYPE AND MERELY SERVES AS A POINTER
                   1738: #      TO THE IDENTIFYING ADDRESS CONSTANT. HOWEVER, IN OTHER
                   1739: #      CASES THERE ARE SEVERAL POSSIBILITIES FOR THE FIRST
                   1740: #      WORD IN WHICH CASE EACH OF THE SEVERAL PROGRAM ENTRY
                   1741: #      POINTS MUST BE PRECEDED BY THE APPROPRIATE CONSTANT.
                   1742: #
                   1743: #      IN EACH BLOCK, SOME OF THE FIELDS ARE RELOCATABLE. THIS
                   1744: #      MEANS THAT THEY MAY CONTAIN A POINTER TO ANOTHER BLOCK
                   1745: #      IN THE DYNAMIC AREA. (TO BE MORE PRECISE, IF THEY CONTAIN
                   1746: #      A POINTER WITHIN THE DYNAMIC AREA, THEN IT IS A POINTER
                   1747: #      TO A BLOCK). SUCH FIELDS MUST BE MODIFIED BY THE GARBAGE
                   1748: #      COLLECTOR (PROCEDURE GBCOL) WHENEVER BLOCKS ARE COMPACTED
                   1749: #      IN THE DYNAMIC REGION. THE GARBAGE COLLECTOR (ACTUALLY
                   1750: #      PROCEDURE GBCPF) REQUIRES THAT ALL SUCH RELOCATABLE
                   1751: #      FIELDS IN A BLOCK MUST BE CONTIGUOUS.
                   1752:        #page   
                   1753: #
                   1754: #      THE DESCRIPTION FORMAT USES THE FOLLOWING SCHEME.
                   1755: #
                   1756: #      1)   BLOCK TITLE AND TWO CHARACTER IDENTIFIER
                   1757: #
                   1758: #      2)   DESCRIPTION OF BASIC USE OF BLOCK AND INDICATION
                   1759: #           OF CIRCUMSTANCES UNDER WHICH IT IS CONSTRUCTED.
                   1760: #
                   1761: #      3)   PICTURE OF THE BLOCK FORMAT. IN THESE PICTURES LOW
                   1762: #           MEMORY ADDRESSES ARE AT THE TOP OF THE PAGE. FIXED
                   1763: #           LENGTH FIELDS ARE SURROUNDED BY I (LETTER I). FIELDS
                   1764: #           WHICH ARE FIXED LENGTH BUT WHOSE LENGTH IS DEPENDENT
                   1765: #           ON A CONFIGURATION PARAMETER ARE SURROUNDED BY *
                   1766: #           (ASTERISK). VARIABLE LENGTH FIELDS ARE SURROUNDED
                   1767: #           BY / (SLASH).
                   1768: #
                   1769: #      4)   DEFINITION OF SYMBOLIC OFFSETS TO FIELDS IN
                   1770: #           BLOCK AND OF THE SIZE OF THE BLOCK IF FIXED LENGTH
                   1771: #           OR OF THE SIZE OF THE FIXED LENGTH FIELDS IF THE
                   1772: #           BLOCK IS VARIABLE LENGTH.
                   1773: #           NOTE THAT SOME ROUTINES SUCH AS GBCPF ASSUME
                   1774: #           CERTAIN OFFSETS ARE EQUAL. THE DEFINITIONS
                   1775: #           GIVEN HERE ENFORCE THIS.  MAKE CHANGES TO
                   1776: #           THEM ONLY WITH DUE CARE.
                   1777: #
                   1778: #      DEFINITIONS OF COMMON OFFSETS
                   1779: #
                   1780:        .set    offs1,1
                   1781:        .set    offs2,2
                   1782:        .set    offs3,3
                   1783: #
                   1784: #      5)   DETAILED COMMENTS ON THE SIGNIFICANCE AND FORMATS
                   1785: #           OF THE VARIOUS FIELDS.
                   1786: #
                   1787: #      THE ORDER IS ALPHABETICAL BY IDENTIFICATION CODE.
                   1788:        #page   
                   1789: #
                   1790: #      DEFINITIONS OF BLOCK CODES
                   1791: #
                   1792: #      THIS TABLE PROVIDES A UNIQUE IDENTIFICATION CODE FOR
                   1793: #      EACH SEPARATE BLOCK TYPE. THE FIRST WORD OF A BLOCK IN
                   1794: #      THE DYNAMIC AREA ALWAYS CONTAINS THE ADDRESS OF A PROGRAM
                   1795: #      ENTRY POINT. THE BLOCK CODE IS USED AS THE ENTRY POINT ID
                   1796: #      THE ORDER OF THESE CODES DICTATES THE ORDER OF THE TABLE
                   1797: #      USED BY THE DATATYPE FUNCTION (SCNMT IN THE CONSTANT SEC)
                   1798: #
                   1799: #      BLOCK CODES FOR ACCESSIBLE DATATYPES
                   1800: #
                   1801:        .set    bl$ar,0         # arblk     array
                   1802:        .set    bl$bc,bl$ar+1   # bcblk     buffer
                   1803:        .set    bl$cd,bl$bc+1   # cdblk     code
                   1804:        .set    bl$ex,bl$cd+1   # exblk     expression
                   1805:        .set    bl$ic,bl$ex+1   # icblk     integer
                   1806:        .set    bl$nm,bl$ic+1   # nmblk     name
                   1807:        .set    bl$p0,bl$nm+1   # p0blk     pattern
                   1808:        .set    bl$p1,bl$p0+1   # p1blk     pattern
                   1809:        .set    bl$p2,bl$p1+1   # p2blk     pattern
                   1810:        .set    bl$rc,bl$p2+1   # rcblk     real
                   1811:        .set    bl$sc,bl$rc+1   # scblk     string
                   1812:        .set    bl$se,bl$sc+1   # seblk     expression
                   1813:        .set    bl$tb,bl$se+1   # tbblk     table
                   1814:        .set    bl$vc,bl$tb+1   # vcblk     array
                   1815:        .set    bl$xn,bl$vc+1   # xnblk     external
                   1816:        .set    bl$xr,bl$xn+1   # xrblk     external
                   1817:        .set    bl$pd,bl$xr+1   # pdblk     program defined datatype
                   1818: #
                   1819:        .set    bl$$d,bl$pd+1   # number of block codes for data
                   1820: #
                   1821: #      OTHER BLOCK CODES
                   1822: #
                   1823:        .set    bl$tr,bl$pd+1   # trblk
                   1824:        .set    bl$bf,bl$tr+1   # bfblk
                   1825:        .set    bl$cc,bl$bf+1   # ccblk
                   1826:        .set    bl$cm,bl$cc+1   # cmblk
                   1827:        .set    bl$ct,bl$cm+1   # ctblk
                   1828:        .set    bl$df,bl$ct+1   # dfblk
                   1829:        .set    bl$ef,bl$df+1   # efblk
                   1830:        .set    bl$ev,bl$ef+1   # evblk
                   1831:        .set    bl$ff,bl$ev+1   # ffblk
                   1832:        .set    bl$kv,bl$ff+1   # kvblk
                   1833:        .set    bl$pf,bl$kv+1   # pfblk
                   1834:        .set    bl$te,bl$pf+1   # teblk
                   1835: #
                   1836:        .set    bl$$i,0         # default identification code
                   1837:        .set    bl$$t,bl$tr+1   # code for data or trace block
                   1838:        .set    bl$$$,bl$te+1   # number of block codes
                   1839:        #page   
                   1840: #
                   1841: #      FIELD REFERENCES
                   1842: #
                   1843: #      REFERENCES TO THE FIELDS OF DATA BLOCKS ARE SYMBOLIC
                   1844: #      (I.E. USE THE SYMBOLIC OFFSETS) WITH THE FOLLOWING
                   1845: #      EXCEPTIONS.
                   1846: #
                   1847: #      1)   REFERENCES TO THE FIRST WORD ARE USUALLY NOT
                   1848: #           SYMBOLIC SINCE THEY USE THE (X) OPERAND FORMAT.
                   1849: #
                   1850: #      2)   THE CODE WHICH CONSTRUCTS A BLOCK IS OFTEN NOT
                   1851: #           SYMBOLIC AND SHOULD BE CHANGED IF THE CORRESPONDING
                   1852: #           BLOCK FORMAT IS MODIFIED.
                   1853: #
                   1854: #      3)   THE PLC AND PSC INSTRUCTIONS IMPLY AN OFFSET
                   1855: #           CORRESPONDING TO THE DEFINITION OF CFP$F.
                   1856: #
                   1857: #      4)   THERE ARE NON-SYMBOLIC REFERENCES (EASILY CHANGED)
                   1858: #           IN THE GARBAGE COLLECTOR (PROCEDURES GBCPF, BLKLN).
                   1859: #
                   1860: #      5)   THE FIELDS IDVAL, FARGS APPEAR IN SEVERAL BLOCKS
                   1861: #           AND ANY CHANGES MUST BE MADE IN PARALLEL TO ALL
                   1862: #           BLOCKS CONTAINING THE FIELDS. THE ACTUAL REFERENCES
                   1863: #           TO THESE FIELDS ARE SYMBOLIC WITH THE ABOVE
                   1864: #           LISTED EXCEPTIONS.
                   1865: #
                   1866: #      6)   SEVERAL SPOTS IN THE CODE ASSUME THAT THE
                   1867: #           DEFINITIONS OF THE FIELDS VRVAL, TEVAL, TRNXT ARE
                   1868: #           THE SAME (THESE ARE SECTIONS OF CODE WHICH SEARCH
                   1869: #           OUT ALONG A TRBLK CHAIN FROM A VARIABLE).
                   1870: #
                   1871: #      7)   REFERENCES TO THE FIELDS OF AN ARRAY BLOCK IN THE
                   1872: #           ARRAY REFERENCE ROUTINE ARREF ARE NON-SYMBOLIC.
                   1873: #
                   1874: #      APART FROM THE EXCEPTIONS LISTED, REFERENCES ARE SYMBOLIC
                   1875: #      AS FAR AS POSSIBLE AND MODIFYING THE ORDER OR NUMBER
                   1876: #      OF FIELDS WILL NOT REQUIRE CHANGES.
                   1877:        #page   
                   1878: #
                   1879: #      COMMON FIELDS FOR FUNCTION BLOCKS
                   1880: #
                   1881: #      BLOCKS WHICH REPRESENT CALLABLE FUNCTIONS HAVE TWO
                   1882: #      COMMON FIELDS AT THE START OF THE BLOCK AS FOLLOWS.
                   1883: #
                   1884: #           +------------------------------------+
                   1885: #           I                FCODE               I
                   1886: #           +------------------------------------+
                   1887: #           I                FARGS               I
                   1888: #           +------------------------------------+
                   1889: #           /                                    /
                   1890: #           /       REST OF FUNCTION BLOCK       /
                   1891: #           /                                    /
                   1892: #           +------------------------------------+
                   1893: #
                   1894:        .set    fcode,0         # pointer to code for function
                   1895:        .set    fargs,1         # number of arguments
                   1896: #
                   1897: #      FCODE IS A POINTER TO THE LOCATION IN THE INTERPRETOR
                   1898: #      PROGRAM WHICH PROCESSES THIS TYPE OF FUNCTION CALL.
                   1899: #
                   1900: #      FARGS IS THE EXPECTED NUMBER OF ARGUMENTS. THE ACTUAL
                   1901: #      NUMBER OF ARGUMENTS IS ADJUSTED TO THIS AMOUNT BY
                   1902: #      DELETING EXTRA ARGUMENTS OR SUPPLYING TRAILING NULLS
                   1903: #      FOR MISSING ONES BEFORE TRANSFERRING THOUGH FCODE.
                   1904: #      A VALUE OF 999 MAY BE USED IN THIS FIELD TO INDICATE A
                   1905: #      VARIABLE NUMBER OF ARGUMENTS (SEE SVBLK FIELD SVNAR).
                   1906: #
                   1907: #      THE BLOCK TYPES WHICH FOLLOW THIS SCHEME ARE.
                   1908: #
                   1909: #      FFBLK                 FIELD FUNCTION
                   1910: #      DFBLK                 DATATYPE FUNCTION
                   1911: #      PFBLK                 PROGRAM DEFINED FUNCTION
                   1912: #      EFBLK                 EXTERNAL LOADED FUNCTION
                   1913:        #page   
                   1914: #
                   1915: #      IDENTIFICATION FIELD
                   1916: #
                   1917: #
                   1918: #      ID   FIELD
                   1919: #
                   1920: #      CERTAIN PROGRAM ACCESSIBLE OBJECTS (THOSE WHICH CONTAIN
                   1921: #      OTHER DATA VALUES AND CAN BE COPIED) ARE GIVEN A UNIQUE
                   1922: #      IDENTIFICATION NUMBER (SEE EXSID). THIS ID VALUE IS AN
                   1923: #      ADDRESS INTEGER VALUE WHICH IS ALWAYS STORED IN WORD TWO.
                   1924: #
                   1925:        .set    idval,1         # id value field
                   1926: #
                   1927: #      THE BLOCKS CONTAINING AN IDVAL FIELD ARE.
                   1928: #
                   1929: #      ARBLK                 ARRAY
                   1930: #      BCBLK                 BUFFER CONTROL BLOCK
                   1931: #      PDBLK                 PROGRAM DEFINED DATATYPE
                   1932: #      TBBLK                 TABLE
                   1933: #      VCBLK                 VECTOR BLOCK (ARRAY)
                   1934: #
                   1935: #      NOTE THAT A ZERO IDVAL MEANS THAT THE BLOCK IS ONLY
                   1936: #      HALF BUILT AND SHOULD NOT BE DUMPED (SEE DUMPR).
                   1937:        #page   
                   1938: #
                   1939: #      ARRAY BLOCK (ARBLK)
                   1940: #
                   1941: #      AN ARRAY BLOCK REPRESENTS AN ARRAY VALUE OTHER THAN ONE
                   1942: #      WITH ONE DIMENSION WHOSE LOWER BOUND IS ONE (SEE VCBLK).
                   1943: #      AN ARBLK IS BUILT WITH A CALL TO THE FUNCTIONS CONVERT
                   1944: #      (S$CNV) OR ARRAY (S$ARR).
                   1945: #
                   1946: #           +------------------------------------+
                   1947: #           I                ARTYP               I
                   1948: #           +------------------------------------+
                   1949: #           I                IDVAL               I
                   1950: #           +------------------------------------+
                   1951: #           I                ARLEN               I
                   1952: #           +------------------------------------+
                   1953: #           I                AROFS               I
                   1954: #           +------------------------------------+
                   1955: #           I                ARNDM               I
                   1956: #           +------------------------------------+
                   1957: #           *                ARLBD               *
                   1958: #           +------------------------------------+
                   1959: #           *                ARDIM               *
                   1960: #           +------------------------------------+
                   1961: #           *                                    *
                   1962: #           * ABOVE 2 FLDS REPEATED FOR EACH DIM *
                   1963: #           *                                    *
                   1964: #           +------------------------------------+
                   1965: #           I                ARPRO               I
                   1966: #           +------------------------------------+
                   1967: #           /                                    /
                   1968: #           /                ARVLS               /
                   1969: #           /                                    /
                   1970: #           +------------------------------------+
                   1971:        #page   
                   1972: #
                   1973: #      ARRAY BLOCK (CONTINUED)
                   1974: #
                   1975:        .set    artyp,0         # pointer to dummy routine b$art
                   1976:        .set    arlen,idval+1   # length of arblk in bytes
                   1977:        .set    arofs,arlen+1   # offset in arblk to arpro field
                   1978:        .set    arndm,arofs+1   # number of dimensions
                   1979:        .set    arlbd,arndm+1   # low bound (first subscript)
                   1980:        .set    ardim,arlbd+cfp$i# dimension (first subscript)
                   1981:        .set    arlb2,ardim+cfp$i# low bound (second subscript)
                   1982:        .set    ardm2,arlb2+cfp$i# dimension (second subscript)
                   1983:        .set    arpro,ardim+cfp$i# array prototype (one dimension)
                   1984:        .set    arvls,arpro+1   # start of values (one dimension)
                   1985:        .set    arpr2,ardm2+cfp$i# array prototype (two dimensions)
                   1986:        .set    arvl2,arpr2+1   # start of values (two dimensions)
                   1987:        .set    arsi$,arlbd     # number of standard fields in block
                   1988:        .set    ardms,arlb2-arlbd# size of info for one set of bounds
                   1989: #
                   1990: #      THE BOUNDS AND DIMENSION FIELDS ARE SIGNED INTEGER
                   1991: #      VALUES AND EACH OCCUPY CFP$I WORDS IN THE ARBLK.
                   1992: #
                   1993: #      THE LENGTH OF AN ARBLK IN BYTES MAY NOT EXCEED MXLEN.
                   1994: #      THIS IS REQUIRED TO KEEP NAME OFFSETS GARBAGE COLLECTABLE
                   1995: #
                   1996: #      THE ACTUAL VALUES ARE ARRANGED IN ROW-WISE ORDER AND
                   1997: #      CAN CONTAIN A DATA POINTER OR A POINTER TO A TRBLK.
                   1998: #
                   1999: #      BUFFER CONTROL BLOCK (BCBLK)
                   2000: #
                   2001: #      A BCBLK IS BUILT FOR EVERY BFBLK.
                   2002: #
                   2003: #           +------------------------------------+
                   2004: #           I                BCTYP               I
                   2005: #           +------------------------------------+
                   2006: #           I                IDVAL               I
                   2007: #           +------------------------------------+
                   2008: #           I                BCLEN               I
                   2009: #           +------------------------------------+
                   2010: #           I                BCBUF               I
                   2011: #           +------------------------------------+
                   2012: #
                   2013:        .set    bctyp,0         # ptr to dummy routine b$bct
                   2014:        .set    bclen,idval+1   # defined buffer length
                   2015:        .set    bcbuf,bclen+1   # ptr to bfblk
                   2016:        .set    bcsi$,bcbuf+1   # size of bcblk
                   2017: #
                   2018: #      A BCBLK IS AN INDIRECT CONTROL HEADER FOR BFBLK.
                   2019: #      THE REASON FOR NOT STORING THIS DATA DIRECTLY
                   2020: #      IN THE RELATED BFBLK IS SO THAT THE BFBLK CAN
                   2021: #      MAINTAIN THE SAME SKELETAL STRUCTURE AS AN SCBLK
                   2022: #      THUS FACILITATING TRANSPARENT STRING OPERATIONS
                   2023: #      (FOR THE MOST PART).  SPECIFICALLY, CFP$F IS THE
                   2024: #      SAME FOR A BFBLK AS FOR AN SCBLK.  BY CONVENTION,
                   2025: #      WHEREEVER A BUFFER VALUE IS EMPLOYED, THE BCBLK
                   2026: #      IS POINTED TO.
                   2027: #
                   2028: #      THE CORRESPONDING BFBLK IS POINTED TO BY THE
                   2029: #      BCBUF POINTER IN THE BCBLK.
                   2030: #
                   2031: #      BCLEN IS THE CURRENT DEFINED SIZE OF THE CHARACTER
                   2032: #      ARRAY IN THE BFBLK.  CHARACTERS FOLLOWING THE OFFSET
                   2033: #      OF BCLEN ARE UNDEFINED.
                   2034: #
                   2035:        #page   
                   2036: #
                   2037: #      STRING BUFFER BLOCK (BFBLK)
                   2038: #
                   2039: #      A BFBLK IS BUILT BY A CALL TO BUFFER(...)
                   2040: #
                   2041: #           +------------------------------------+
                   2042: #           I                BFTYP               I
                   2043: #           +------------------------------------+
                   2044: #           I                BFALC               I
                   2045: #           +------------------------------------+
                   2046: #           /                                    /
                   2047: #           /                BFCHR               /
                   2048: #           /                                    /
                   2049: #           +------------------------------------+
                   2050: #
                   2051:        .set    bftyp,0         # ptr to dummy routine b$bft
                   2052:        .set    bfalc,bftyp+1   # allocated size of buffer
                   2053:        .set    bfchr,bfalc+1   # characters of string
                   2054:        .set    bfsi$,bfchr     # size of standard fields in bfblk
                   2055: #
                   2056: #      THE CHARACTERS IN THE BUFFER ARE STORED LEFT JUSTIFIED.
                   2057: #      THE FINAL WORD OF DEFINED CHARACTERS IS ALWAYS ZERO
                   2058: #      (CHARACTER) PADDED.  ANY TRAILING ALLOCATION PAST THE
                   2059: #      WORD CONTAINING THE LAST CHARACTER CONTAINS
                   2060: #      UNPREDICTABLE CONTENTS AND IS NEVER REFERENCED.
                   2061: #
                   2062: #      NOTE THAT THE OFFSET TO THE CHARACTERS OF THE STRING
                   2063: #      IS GIVEN BY CFP$F, AS WITH AN SCBLK.  HOWEVER, THE
                   2064: #      OFFSET WHICH IS OCCUPIED BY THE LENGTH FOR AN SCBLK
                   2065: #      IS THE TOTAL CHAR SPACE FOR BFBLKS, AND ROUTINES WHICH
                   2066: #      DEAL WITH BOTH MUST ACCOUNT FOR THIS DIFFERENCE.
                   2067: #
                   2068: #      THE VALUE OF BFALC MAY NOT EXCEED MXLEN.  THE VALUE OF
                   2069: #      BCLEN IS ALWAYS LESS THAN OR EQUAL TO BFALC.
                   2070: #
                   2071:        #page   
                   2072: #
                   2073: #      CODE CONSTRUCTION BLOCK (CCBLK)
                   2074: #
                   2075: #      AT ANY ONE MOMENT THERE IS AT MOST ONE CCBLK INTO
                   2076: #      WHICH THE COMPILER IS CURRENTLY STORING CODE (CDWRD).
                   2077: #
                   2078: #           +------------------------------------+
                   2079: #           I                CCTYP               I
                   2080: #           +------------------------------------+
                   2081: #           I                CCLEN               I
                   2082: #           +------------------------------------+
                   2083: #           I                CCUSE               I
                   2084: #           +------------------------------------+
                   2085: #           /                                    /
                   2086: #           /                CCCOD               /
                   2087: #           /                                    /
                   2088: #           +------------------------------------+
                   2089: #
                   2090:        .set    cctyp,0         # pointer to dummy routine b$cct
                   2091:        .set    cclen,cctyp+1   # length of ccblk in bytes
                   2092:        .set    ccuse,cclen+1   # offset past last used word (bytes)
                   2093:        .set    cccod,ccuse+1   # start of generated code in block
                   2094: #
                   2095: #      THE REASON THAT THE CCBLK IS A SEPARATE BLOCK TYPE FROM
                   2096: #      THE USUAL CDBLK IS THAT THE GARBAGE COLLECTOR MUST
                   2097: #      ONLY PROCESS THOSE FIELDS WHICH HAVE BEEN SET (SEE GBCPF)
                   2098:        #page   
                   2099: #
                   2100: #      CODE BLOCK (CDBLK)
                   2101: #
                   2102: #      A CODE BLOCK IS BUILT FOR EACH STATEMENT COMPILED DURING
                   2103: #      THE INITIAL COMPILATION OR BY SUBSEQUENT CALLS TO CODE.
                   2104: #
                   2105: #           +------------------------------------+
                   2106: #           I                CDJMP               I
                   2107: #           +------------------------------------+
                   2108: #           I                CDSTM               I
                   2109: #           +------------------------------------+
                   2110: #           I                CDLEN               I
                   2111: #           +------------------------------------+
                   2112: #           I                CDFAL               I
                   2113: #           +------------------------------------+
                   2114: #           /                                    /
                   2115: #           /                CDCOD               /
                   2116: #           /                                    /
                   2117: #           +------------------------------------+
                   2118: #
                   2119:        .set    cdjmp,0         # ptr to routine to execute statement
                   2120:        .set    cdstm,cdjmp+1   # statement number
                   2121:        .set    cdlen,offs2     # length of cdblk in bytes
                   2122:        .set    cdfal,offs3     # failure exit (see below)
                   2123:        .set    cdcod,cdfal+1   # executable pseudo-code
                   2124:        .set    cdsi$,cdcod     # number of standard fields in cdblk
                   2125: #
                   2126: #      CDSTM IS THE STATEMENT NUMBER OF THE CURRENT STATEMENT.
                   2127: #
                   2128: #      CDJMP, CDFAL ARE SET AS FOLLOWS.
                   2129: #
                   2130: #      1)   IF THE FAILURE EXIT IS THE NEXT STATEMENT
                   2131: #
                   2132: #           CDJMP = B$CDS
                   2133: #           CDFAL = PTR TO CDBLK FOR NEXT STATEMENT
                   2134: #
                   2135: #      2)   IF THE FAILURE EXIT IS A SIMPLE LABEL NAME
                   2136: #
                   2137: #           CDJMP = B$CDS
                   2138: #           CDFAL IS A PTR TO THE VRTRA FIELD OF THE VRBLK
                   2139: #
                   2140: #      3)   IF THERE IS NO FAILURE EXIT (-NOFAIL MODE)
                   2141: #
                   2142: #           CDJMP = B$CDS
                   2143: #           CDFAL = O$UNF
                   2144: #
                   2145: #      4)   IF THE FAILURE EXIT IS COMPLEX OR DIRECT
                   2146: #
                   2147: #           CDJMP = B$CDC
                   2148: #           CDFAL IS THE OFFSET TO THE O$GOF WORD
                   2149:        #page   
                   2150: #
                   2151: #      CODE BLOCK (CONTINUED)
                   2152: #
                   2153: #      CDCOD IS THE START OF THE ACTUAL CODE. FIRST WE DESCRIBE
                   2154: #      THE CODE GENERATED FOR AN EXPRESSION. IN AN EXPRESSION,
                   2155: #      ELEMENTS ARE FETCHED BY NAME OR BY VALUE. FOR EXAMPLE,
                   2156: #      THE BINARY EQUAL OPERATOR FETCHES ITS LEFT ARGUMENT
                   2157: #      BY NAME AND ITS RIGHT ARGUMENT BY VALUE. THESE TWO
                   2158: #      CASES GENERATE QUITE DIFFERENT CODE AND ARE DESCRIBED
                   2159: #      SEPARATELY. FIRST WE CONSIDER THE CODE BY VALUE CASE.
                   2160: #
                   2161: #      GENERATION OF CODE BY VALUE FOR EXPRESSIONS ELEMENTS.
                   2162: #
                   2163: #      EXPRESSION            POINTER TO EXBLK OR SEBLK
                   2164: #
                   2165: #      INTEGER CONSTANT      POINTER TO ICBLK
                   2166: #
                   2167: #      NULL CONSTANT         POINTER TO NULLS
                   2168: #
                   2169: #      PATTERN               (RESULTING FROM PREEVALUATION)
                   2170: #                            =O$LPT
                   2171: #                            POINTER TO P0BLK,P1BLK OR P2BLK
                   2172: #
                   2173: #      REAL CONSTANT         POINTER TO RCBLK
                   2174: #
                   2175: #      STRING CONSTANT       POINTER TO SCBLK
                   2176: #
                   2177: #      VARIABLE              POINTER TO VRGET FIELD OF VRBLK
                   2178: #
                   2179: #      ADDITION              VALUE CODE FOR LEFT OPERAND
                   2180: #                            VALUE CODE FOR RIGHT OPERAND
                   2181: #                            =O$ADD
                   2182: #
                   2183: #      AFFIRMATION           VALUE CODE FOR OPERAND
                   2184: #                            =O$AFF
                   2185: #
                   2186: #      ALTERNATION           VALUE CODE FOR LEFT OPERAND
                   2187: #                            VALUE CODE FOR RIGHT OPERAND
                   2188: #                            =O$ALT
                   2189: #
                   2190: #      ARRAY REFERENCE       (CASE OF ONE SUBSCRIPT)
                   2191: #                            VALUE CODE FOR ARRAY OPERAND
                   2192: #                            VALUE CODE FOR SUBSCRIPT OPERAND
                   2193: #                            =O$AOV
                   2194: #
                   2195: #                            (CASE OF MORE THAN ONE SUBSCRIPT)
                   2196: #                            VALUE CODE FOR ARRAY OPERAND
                   2197: #                            VALUE CODE FOR FIRST SUBSCRIPT
                   2198: #                            VALUE CODE FOR SECOND SUBSCRIPT
                   2199: #                            ...
                   2200: #                            VALUE CODE FOR LAST SUBSCRIPT
                   2201: #                            =O$AMV
                   2202: #                            NUMBER OF SUBSCRIPTS
                   2203:        #page   
                   2204: #
                   2205: #      CODE BLOCK (CONTINUED)
                   2206: #
                   2207: #      ASSIGNMENT            (TO NATURAL VARIABLE)
                   2208: #                            VALUE CODE FOR RIGHT OPERAND
                   2209: #                            POINTER TO VRSTO FIELD OF VRBLK
                   2210: #
                   2211: #                            (TO ANY OTHER VARIABLE)
                   2212: #                            NAME CODE FOR LEFT OPERAND
                   2213: #                            VALUE CODE FOR RIGHT OPERAND
                   2214: #                            =O$ASS
                   2215: #
                   2216: #      COMPILE ERROR         =O$CER
                   2217: #
                   2218: #
                   2219: #      COMPLEMENTATION       VALUE CODE FOR OPERAND
                   2220: #                            =O$COM
                   2221: #
                   2222: #      CONCATENATION         (CASE OF PRED FUNC LEFT OPERAND)
                   2223: #                            VALUE CODE FOR LEFT OPERAND
                   2224: #                            =O$POP
                   2225: #                            VALUE CODE FOR RIGHT OPERAND
                   2226: #
                   2227: #                            (ALL OTHER CASES)
                   2228: #                            VALUE CODE FOR LEFT OPERAND
                   2229: #                            VALUE CODE FOR RIGHT OPERAND
                   2230: #                            =O$CNC
                   2231: #
                   2232: #      CURSOR ASSIGNMENT     NAME CODE FOR OPERAND
                   2233: #                            =O$CAS
                   2234: #
                   2235: #      DIVISION              VALUE CODE FOR LEFT OPERAND
                   2236: #                            VALUE CODE FOR RIGHT OPERAND
                   2237: #                            =O$DVD
                   2238: #
                   2239: #      EXPONENTIATION        VALUE CODE FOR LEFT OPERAND
                   2240: #                            VALUE CODE FOR RIGHT OPERAND
                   2241: #                            =O$EXP
                   2242: #
                   2243: #      FUNCTION CALL         (CASE OF CALL TO SYSTEM FUNCTION)
                   2244: #                            VALUE CODE FOR FIRST ARGUMENT
                   2245: #                            VALUE CODE FOR SECOND ARGUMENT
                   2246: #                            ...
                   2247: #                            VALUE CODE FOR LAST ARGUMENT
                   2248: #                            POINTER TO SVFNC FIELD OF SVBLK
                   2249: #
                   2250:        #page   
                   2251: #
                   2252: #      CODE BLOCK (CONTINUED)
                   2253: #
                   2254: #      FUNCTION CALL         (CASE OF NON-SYSTEM FUNCTION 1 ARG)
                   2255: #                            VALUE CODE FOR ARGUMENT
                   2256: #                            =O$FNS
                   2257: #                            POINTER TO VRBLK FOR FUNCTION
                   2258: #
                   2259: #                            (NON-SYSTEM FUNCTION, GT 1 ARG)
                   2260: #                            VALUE CODE FOR FIRST ARGUMENT
                   2261: #                            VALUE CODE FOR SECOND ARGUMENT
                   2262: #                            ...
                   2263: #                            VALUE CODE FOR LAST ARGUMENT
                   2264: #                            =O$FNC
                   2265: #                            NUMBER OF ARGUMENTS
                   2266: #                            POINTER TO VRBLK FOR FUNCTION
                   2267: #
                   2268: #      IMMEDIATE ASSIGNMENT  VALUE CODE FOR LEFT OPERAND
                   2269: #                            NAME CODE FOR RIGHT OPERAND
                   2270: #                            =O$IMA
                   2271: #
                   2272: #      INDIRECTION           VALUE CODE FOR OPERAND
                   2273: #                            =O$INV
                   2274: #
                   2275: #      INTERROGATION         VALUE CODE FOR OPERAND
                   2276: #                            =O$INT
                   2277: #
                   2278: #      KEYWORD REFERENCE     NAME CODE FOR OPERAND
                   2279: #                            =O$KWV
                   2280: #
                   2281: #      MULTIPLICATION        VALUE CODE FOR LEFT OPERAND
                   2282: #                            VALUE CODE FOR RIGHT OPERAND
                   2283: #                            =O$MLT
                   2284: #
                   2285: #      NAME REFERENCE        (NATURAL VARIABLE CASE)
                   2286: #                            POINTER TO NMBLK FOR NAME
                   2287: #
                   2288: #                            (ALL OTHER CASES)
                   2289: #                            NAME CODE FOR OPERAND
                   2290: #                            =O$NAM
                   2291: #
                   2292: #      NEGATION              =O$NTA
                   2293: #                            CDBLK OFFSET OF O$NTC WORD
                   2294: #                            VALUE CODE FOR OPERAND
                   2295: #                            =O$NTB
                   2296: #                            =O$NTC
                   2297:        #page   
                   2298: #
                   2299: #      CODE BLOCK (CONTINUED)
                   2300: #
                   2301: #      PATTERN ASSIGNMENT    VALUE CODE FOR LEFT OPERAND
                   2302: #                            NAME CODE FOR RIGHT OPERAND
                   2303: #                            =O$PAS
                   2304: #
                   2305: #      PATTERN MATCH         VALUE CODE FOR LEFT OPERAND
                   2306: #                            VALUE CODE FOR RIGHT OPERAND
                   2307: #                            =O$PMV
                   2308: #
                   2309: #      PATTERN REPLACEMENT   NAME CODE FOR SUBJECT
                   2310: #                            VALUE CODE FOR PATTERN
                   2311: #                            =O$PMN
                   2312: #                            VALUE CODE FOR REPLACEMENT
                   2313: #                            =O$RPL
                   2314: #
                   2315: #      SELECTION             (FOR FIRST ALTERNATIVE)
                   2316: #                            =O$SLA
                   2317: #                            CDBLK OFFSET TO NEXT O$SLC WORD
                   2318: #                            VALUE CODE FOR FIRST ALTERNATIVE
                   2319: #                            =O$SLB
                   2320: #                            CDBLK OFFSET PAST ALTERNATIVES
                   2321: #
                   2322: #                            (FOR SUBSEQUENT ALTERNATIVES)
                   2323: #                            =O$SLC
                   2324: #                            CDBLK OFFSET TO NEXT O$SLC,O$SLD
                   2325: #                            VALUE CODE FOR ALTERNATIVE
                   2326: #                            =O$SLB
                   2327: #                            OFFSET IN CDBLK PAST ALTERNATIVES
                   2328: #
                   2329: #                            (FOR LAST ALTERNATIVE)
                   2330: #                            =O$SLD
                   2331: #                            VALUE CODE FOR LAST ALTERNATIVE
                   2332: #
                   2333: #      SUBTRACTION           VALUE CODE FOR LEFT OPERAND
                   2334: #                            VALUE CODE FOR RIGHT OPERAND
                   2335: #                            =O$SUB
                   2336:        #page   
                   2337: #
                   2338: #      CODE BLOCK (CONTINUED)
                   2339: #
                   2340: #      GENERATION OF CODE BY NAME FOR EXPRESSION ELEMENTS.
                   2341: #
                   2342: #      VARIABLE              =O$LVN
                   2343: #                            POINTER TO VRBLK
                   2344: #
                   2345: #      EXPRESSION            (CASE OF *NATURAL VARIABLE)
                   2346: #                            =O$LVN
                   2347: #                            POINTER TO VRBLK
                   2348: #
                   2349: #                            (ALL OTHER CASES)
                   2350: #                            =O$LEX
                   2351: #                            POINTER TO EXBLK
                   2352: #
                   2353: #
                   2354: #      ARRAY REFERENCE       (CASE OF ONE SUBSCRIPT)
                   2355: #                            VALUE CODE FOR ARRAY OPERAND
                   2356: #                            VALUE CODE FOR SUBSCRIPT OPERAND
                   2357: #                            =O$AON
                   2358: #
                   2359: #                            (CASE OF MORE THAN ONE SUBSCRIPT)
                   2360: #                            VALUE CODE FOR ARRAY OPERAND
                   2361: #                            VALUE CODE FOR FIRST SUBSCRIPT
                   2362: #                            VALUE CODE FOR SECOND SUBSCRIPT
                   2363: #                            ...
                   2364: #                            VALUE CODE FOR LAST SUBSCRIPT
                   2365: #                            =O$AMN
                   2366: #                            NUMBER OF SUBSCRIPTS
                   2367: #
                   2368: #      COMPILE ERROR         =O$CER
                   2369: #
                   2370: #      FUNCTION CALL         (SAME CODE AS FOR VALUE CALL)
                   2371: #                            =O$FNE
                   2372: #
                   2373: #      INDIRECTION           VALUE CODE FOR OPERAND
                   2374: #                            =O$INN
                   2375: #
                   2376: #      KEYWORD REFERENCE     NAME CODE FOR OPERAND
                   2377: #                            =O$KWN
                   2378: #
                   2379: #      ANY OTHER OPERAND IS AN ERROR IN A NAME POSITION
                   2380: #
                   2381: #      NOTE THAT IN THIS DESCRIPTION, =O$XXX REFERS TO THE
                   2382: #      GENERATION OF A WORD CONTAINING THE ADDRESS OF ANOTHER
                   2383: #      WORD WHICH CONTAINS THE ENTRY POINT ADDRESS O$XXX.
                   2384:        #page   
                   2385: #
                   2386: #      CODE BLOCK (CONTINUED)
                   2387: #
                   2388: #      NOW WE CONSIDER THE OVERALL STRUCTURE OF THE CODE BLOCK
                   2389: #      FOR A STATEMENT WITH POSSIBLE GOTO FIELDS.
                   2390: #
                   2391: #      FIRST COMES THE CODE FOR THE STATEMENT BODY.
                   2392: #      THE STATEMENT BODY IS AN EXPRESSION TO BE EVALUATED
                   2393: #      BY VALUE ALTHOUGH THE VALUE IS NOT ACTUALLY REQUIRED.
                   2394: #      NORMAL VALUE CODE IS GENERATED FOR THE BODY OF THE
                   2395: #      STATEMENT EXCEPT IN THE CASE OF A PATTERN MATCH BY
                   2396: #      VALUE, IN WHICH CASE THE FOLLOWING IS GENERATED.
                   2397: #
                   2398: #                            VALUE CODE FOR LEFT OPERAND
                   2399: #                            VALUE CODE FOR RIGHT OPERAND
                   2400: #                            =O$PMS
                   2401: #
                   2402: #      NEXT WE HAVE THE CODE FOR THE SUCCESS GOTO. THERE ARE
                   2403: #      SEVERAL CASES AS FOLLOWS.
                   2404: #
                   2405: #      1)   NO SUCCESS GOTO  PTR TO CDBLK FOR NEXT STATEMENT
                   2406: #
                   2407: #      2)   SIMPLE LABEL     PTR TO VRTRA FIELD OF VRBLK
                   2408: #
                   2409: #      3)   COMPLEX GOTO     (CODE BY NAME FOR GOTO OPERAND)
                   2410: #                            =O$GOC
                   2411: #
                   2412: #      4)   DIRECT GOTO      (CODE BY VALUE FOR GOTO OPERAND)
                   2413: #                            =O$GOD
                   2414: #
                   2415: #      FOLLOWING THIS WE GENERATE CODE FOR THE FAILURE GOTO IF
                   2416: #      IT IS DIRECT OR IF IT IS COMPLEX, SIMPLE FAILURE GOTOS
                   2417: #      HAVING BEEN HANDLED BY AN APPROPRIATE SETTING OF THE
                   2418: #      CDFAL FIELD OF THE CDBLK. THE GENERATED CODE IS ONE
                   2419: #      OF THE FOLLOWING.
                   2420: #
                   2421: #      1)   COMPLEX FGOTO    =O$FIF
                   2422: #                            =O$GOF
                   2423: #                            NAME CODE FOR GOTO OPERAND
                   2424: #                            =O$GOC
                   2425: #
                   2426: #      2)   DIRECT FGOTO     =O$FIF
                   2427: #                            =O$GOF
                   2428: #                            VALUE CODE FOR GOTO OPERAND
                   2429: #                            =O$GOD
                   2430: #
                   2431: #      AN OPTIMIZATION OCCURS IF THE SUCCESS AND FAILURE GOTOS
                   2432: #      ARE IDENTICAL AND EITHER COMPLEX OR DIRECT. IN THIS CASE,
                   2433: #      NO CODE IS GENERATED FOR THE SUCCESS GOTO AND CONTROL
                   2434: #      IS ALLOWED TO FALL INTO THE FAILURE GOTO ON SUCCESS.
                   2435:        #page   
                   2436: #
                   2437: #      COMPILER BLOCK (CMBLK)
                   2438: #
                   2439: #      A COMPILER BLOCK (CMBLK) IS BUILT BY EXPAN TO REPRESENT
                   2440: #      ONE NODE OF A TREE STRUCTURED EXPRESSION REPRESENTATION.
                   2441: #
                   2442: #           +------------------------------------+
                   2443: #           I                CMIDN               I
                   2444: #           +------------------------------------+
                   2445: #           I                CMLEN               I
                   2446: #           +------------------------------------+
                   2447: #           I                CMTYP               I
                   2448: #           +------------------------------------+
                   2449: #           I                CMOPN               I
                   2450: #           +------------------------------------+
                   2451: #           /           CMVLS OR CMROP           /
                   2452: #           /                                    /
                   2453: #           /                CMLOP               /
                   2454: #           /                                    /
                   2455: #           +------------------------------------+
                   2456: #
                   2457:        .set    cmidn,0         # pointer to dummy routine b$cmt
                   2458:        .set    cmlen,cmidn+1   # length of cmblk in bytes
                   2459:        .set    cmtyp,cmlen+1   # type (c$xxx, see list below)
                   2460:        .set    cmopn,cmtyp+1   # operand pointer (see below)
                   2461:        .set    cmvls,cmopn+1   # operand value pointers (see below)
                   2462:        .set    cmrop,cmvls     # right (only) operator operand
                   2463:        .set    cmlop,cmvls+1   # left operator operand
                   2464:        .set    cmsi$,cmvls     # number of standard fields in cmblk
                   2465:        .set    cmus$,cmsi$+1   # size of unary operator cmblk
                   2466:        .set    cmbs$,cmsi$+2   # size of binary operator cmblk
                   2467:        .set    cmar1,cmvls+1   # array subscript pointers
                   2468: #
                   2469: #      THE CMOPN AND CMVLS FIELDS ARE SET AS FOLLOWS
                   2470: #
                   2471: #      ARRAY REFERENCE       CMOPN = PTR TO ARRAY OPERAND
                   2472: #                            CMVLS = PTRS TO SUBSCRIPT OPERANDS
                   2473: #
                   2474: #      FUNCTION CALL         CMOPN = PTR TO VRBLK FOR FUNCTION
                   2475: #                            CMVLS = PTRS TO ARGUMENT OPERANDS
                   2476: #
                   2477: #      SELECTION             CMOPN = ZERO
                   2478: #                            CMVLS = PTRS TO ALTERNATE OPERANDS
                   2479: #
                   2480: #      UNARY OPERATOR        CMOPN = PTR TO OPERATOR DVBLK
                   2481: #                            CMROP = PTR TO OPERAND
                   2482: #
                   2483: #      BINARY OPERATOR       CMOPN = PTR TO OPERATOR DVBLK
                   2484: #                            CMROP = PTR TO RIGHT OPERAND
                   2485: #                            CMLOP = PTR TO LEFT OPERAND
                   2486:        #page   
                   2487: #
                   2488: #      CMTYP IS SET TO INDICATE THE TYPE OF EXPRESSION ELEMENT
                   2489: #      AS SHOWN BY THE FOLLOWING TABLE OF DEFINITIONS.
                   2490: #
                   2491:        .set    c$arr,0         # array reference
                   2492:        .set    c$fnc,c$arr+1   # function call
                   2493:        .set    c$def,c$fnc+1   # deferred expression (unary *)
                   2494:        .set    c$ind,c$def+1   # indirection (unary $)
                   2495:        .set    c$key,c$ind+1   # keyword reference (unary ampersand)
                   2496:        .set    c$ubo,c$key+1   # undefined binary operator
                   2497:        .set    c$uuo,c$ubo+1   # undefined unary operator
                   2498:        .set    c$uo$,c$uuo+1   # test value (=c$uuo+1=c$ubo+2)
                   2499:        .set    c$$nm,c$uuo+1   # number of codes for name operands
                   2500: #
                   2501: #      THE REMAINING TYPES INDICATE EXPRESSION ELEMENTS WHICH
                   2502: #      CAN ONLY BE EVALUATED BY VALUE (NOT BY NAME).
                   2503: #
                   2504:        .set    c$bvl,c$uuo+1   # binary op with value operands
                   2505:        .set    c$uvl,c$bvl+1   # unary operator with value operand
                   2506:        .set    c$alt,c$uvl+1   # alternation (binary bar)
                   2507:        .set    c$cnc,c$alt+1   # concatenation
                   2508:        .set    c$cnp,c$cnc+1   # concatenation, not pattern match
                   2509:        .set    c$unm,c$cnp+1   # unary op with name operand
                   2510:        .set    c$bvn,c$unm+1   # binary op (operands by value, name)
                   2511:        .set    c$ass,c$bvn+1   # assignment
                   2512:        .set    c$int,c$ass+1   # interrogation
                   2513:        .set    c$neg,c$int+1   # negation (unary not)
                   2514:        .set    c$sel,c$neg+1   # selection
                   2515:        .set    c$pmt,c$sel+1   # pattern match
                   2516: #
                   2517:        .set    c$pr$,c$bvn     # last preevaluable code
                   2518:        .set    c$$nv,c$pmt+1   # number of different cmblk types
                   2519:        #page   
                   2520: #
                   2521: #      CHARACTER TABLE BLOCK (CTBLK)
                   2522: #
                   2523: #      A CHARACTER TABLE BLOCK IS USED TO HOLD LOGICAL CHARACTER
                   2524: #      TABLES FOR USE WITH ANY,NOTANY,SPAN,BREAK,BREAKX
                   2525: #      PATTERNS. EACH CHARACTER TABLE CAN BE USED TO STORE
                   2526: #      CFP$N DISTINCT TABLES AS BIT COLUMNS. A BIT COLUMN
                   2527: #      ALLOCATED FOR EACH ARGUMENT OF MORE THAN ONE CHARACTER
                   2528: #      IN LENGTH TO ONE OF THE ABOVE LISTED PATTERN PRIMITIVES.
                   2529: #
                   2530: #           +------------------------------------+
                   2531: #           I                CTTYP               I
                   2532: #           +------------------------------------+
                   2533: #           *                                    *
                   2534: #           *                                    *
                   2535: #           *                CTCHS               *
                   2536: #           *                                    *
                   2537: #           *                                    *
                   2538: #           +------------------------------------+
                   2539: #
                   2540:        .set    cttyp,0         # pointer to dummy routine b$ctt
                   2541:        .set    ctchs,cttyp+1   # start of character table words
                   2542:        .set    ctsi$,ctchs+cfp$a# number of words in ctblk
                   2543: #
                   2544: #      CTCHS IS CFP$A WORDS LONG AND CONSISTS OF A ONE WORD
                   2545: #      BIT STRING VALUE FOR EACH POSSIBLE CHARACTER IN THE
                   2546: #      INTERNAL ALPHABET. EACH OF THE CFP$N POSSIBLE BITS IN
                   2547: #      A BITSTRING IS USED TO FORM A COLUMN OF BIT INDICATORS.
                   2548: #      A BIT IS SET ON IF THE CHARACTER IS IN THE TABLE AND OFF
                   2549: #      IF THE CHARACTER IS NOT PRESENT.
                   2550:        #page   
                   2551: #
                   2552: #      DATATYPE FUNCTION BLOCK (DFBLK)
                   2553: #
                   2554: #      A DATATYPE FUNCTION IS USED TO CONTROL THE CONSTRUCTION
                   2555: #      OF A PROGRAM DEFINED DATATYPE OBJECT. A CALL TO THE
                   2556: #      SYSTEM FUNCTION DATA BUILDS A DFBLK FOR THE DATATYPE NAME
                   2557: #
                   2558: #      NOTE THAT THESE BLOCKS ARE BUILT IN STATIC BECAUSE PDBLK
                   2559: #      LENGTH IS GOT FROM DFLEN FIELD.  IF DFBLK WAS IN DYNAMIC
                   2560: #      STORE THIS WOULD CAUSE TROUBLE DURING PASS TWO OF GARBAGE
                   2561: #      COLLECTION.  SCBLK REFERRED TO BY DFNAM FIELD IS ALSO PUT
                   2562: #      IN STATIC SO THAT THERE ARE NO RELOC. FIELDS. THIS CUTS
                   2563: #      GARBAGE COLLECTION TASK APPRECIABLY FOR PDBLKS WHICH ARE
                   2564: #      LIKELY TO BE PRESENT IN LARGE NUMBERS.
                   2565: #
                   2566: #           +------------------------------------+
                   2567: #           I                FCODE               I
                   2568: #           +------------------------------------+
                   2569: #           I                FARGS               I
                   2570: #           +------------------------------------+
                   2571: #           I                DFLEN               I
                   2572: #           +------------------------------------+
                   2573: #           I                DFPDL               I
                   2574: #           +------------------------------------+
                   2575: #           I                DFNAM               I
                   2576: #           +------------------------------------+
                   2577: #           /                                    /
                   2578: #           /                DFFLD               /
                   2579: #           /                                    /
                   2580: #           +------------------------------------+
                   2581: #
                   2582:        .set    dflen,fargs+1   # length of dfblk in bytes
                   2583:        .set    dfpdl,dflen+1   # length of corresponding pdblk
                   2584:        .set    dfnam,dfpdl+1   # pointer to scblk for datatype name
                   2585:        .set    dffld,dfnam+1   # start of vrblk ptrs for field names
                   2586:        .set    dfflb,dffld-1   # offset behind dffld for field func
                   2587:        .set    dfsi$,dffld     # number of standard fields in dfblk
                   2588: #
                   2589: #      THE FCODE FIELD POINTS TO THE ROUTINE B$DFC
                   2590: #
                   2591: #      FARGS (THE NUMBER OF ARGUMENTS) IS THE NUMBER OF FIELDS.
                   2592:        #page   
                   2593: #
                   2594: #      DOPE VECTOR BLOCK (DVBLK)
                   2595: #
                   2596: #      A DOPE VECTOR IS ASSEMBLED FOR EACH POSSIBLE OPERATOR IN
                   2597: #      THE SNOBOL4 LANGUAGE AS PART OF THE CONSTANT SECTION.
                   2598: #
                   2599: #           +------------------------------------+
                   2600: #           I                DVOPN               I
                   2601: #           +------------------------------------+
                   2602: #           I                DVTYP               I
                   2603: #           +------------------------------------+
                   2604: #           I                DVLPR               I
                   2605: #           +------------------------------------+
                   2606: #           I                DVRPR               I
                   2607: #           +------------------------------------+
                   2608: #
                   2609:        .set    dvopn,0         # entry address (ptr to o$xxx)
                   2610:        .set    dvtyp,dvopn+1   # type code (c$xxx, see cmblk)
                   2611:        .set    dvlpr,dvtyp+1   # left precedence (llxxx, see below)
                   2612:        .set    dvrpr,dvlpr+1   # right precedence (rrxxx, see below)
                   2613:        .set    dvus$,dvlpr+1   # size of unary operator dv
                   2614:        .set    dvbs$,dvrpr+1   # size of binary operator dv
                   2615:        .set    dvubs,dvus$+dvbs$# size of unop + binop (see scane)
                   2616: #
                   2617: #      THE CONTENTS OF THE DVTYP FIELD IS COPIED INTO THE CMTYP
                   2618: #      FIELD OF THE CMBLK FOR THE OPERATOR IF IT IS USED.
                   2619: #
                   2620: #      THE CMOPN FIELD OF AN OPERATOR CMBLK POINTS TO THE DVBLK
                   2621: #      ITSELF, PROVIDING THE REQUIRED ENTRY ADDRESS POINTER PTR.
                   2622: #
                   2623: #      FOR NORMALLY UNDEFINED OPERATORS, THE DVOPN (AND CMOPN)
                   2624: #      FIELDS CONTAIN A WORD OFFSET FROM R$UBA OF THE FUNCTION
                   2625: #      BLOCK POINTER FOR THE OPERATOR (INSTEAD OF O$XXX PTR).
                   2626: #      FOR CERTAIN SPECIAL OPERATORS, THE DVOPN FIELD IS NOT
                   2627: #      REQUIRED AT ALL AND IS ASSEMBLED AS ZERO.
                   2628: #
                   2629: #      THE LEFT PRECEDENCE IS USED IN COMPARING AN OPERATOR TO
                   2630: #      THE LEFT OF SOME OTHER OPERATOR. IT THEREFORE GOVERNS THE
                   2631: #      PRECEDENCE OF THE OPERATOR TOWARDS ITS RIGHT OPERAND.
                   2632: #
                   2633: #      THE RIGHT PRECEDENCE IS USED IN COMPARING AN OPERATOR TO
                   2634: #      THE RIGHT OF SOME OTHER OPERATOR. IT THEREFORE GOVERNS
                   2635: #      THE PRECEDENCE OF THE OPERATOR TOWARDS ITS LEFT OPERAND.
                   2636: #
                   2637: #      HIGHER PRECEDENCE VALUES CORRESPOND TO A TIGHTER BINDING
                   2638: #      CAPABILITY. THUS WE HAVE THE LEFT PRECEDENCE LOWER
                   2639: #      (HIGHER) THAN THE RIGHT PRECEDENCE FOR RIGHT (LEFT)
                   2640: #      ASSOCIATIVE BINARY OPERATORS.
                   2641: #
                   2642: #      THE LEFT PRECEDENCE OF UNARY OPERATORS IS SET TO AN
                   2643: #      ARBITRARY HIGH VALUE. THE RIGHT VALUE IS NOT REQUIRED AND
                   2644: #      CONSEQUENTLY THE DVRPR FIELD IS OMITTED FOR UNARY OPS.
                   2645:        #page   
                   2646: #
                   2647: #      TABLE OF OPERATOR PRECEDENCE VALUES
                   2648: #
                   2649:        .set    rrass,10        # right     equal
                   2650:        .set    llass,00        # left      equal
                   2651:        .set    rrpmt,20        # right     question mark
                   2652:        .set    llpmt,30        # left      question mark
                   2653:        .set    rramp,40        # right     ampersand
                   2654:        .set    llamp,50        # left      ampersand
                   2655:        .set    rralt,70        # right     vertical bar
                   2656:        .set    llalt,60        # left      vertical bar
                   2657:        .set    rrcnc,90        # right     blank
                   2658:        .set    llcnc,80        # left      blank
                   2659:        .set    rrats,110       # right     at
                   2660:        .set    llats,100       # left      at
                   2661:        .set    rrplm,120       # right     plus, minus
                   2662:        .set    llplm,130       # left      plus, minus
                   2663:        .set    rrnum,140       # right     number
                   2664:        .set    llnum,150       # left      number
                   2665:        .set    rrdvd,160       # right     slash
                   2666:        .set    lldvd,170       # left      slash
                   2667:        .set    rrmlt,180       # right     asterisk
                   2668:        .set    llmlt,190       # left      asterisk
                   2669:        .set    rrpct,200       # right     percent
                   2670:        .set    llpct,210       # left      percent
                   2671:        .set    rrexp,230       # right     exclamation
                   2672:        .set    llexp,220       # left      exclamation
                   2673:        .set    rrdld,240       # right     dollar, dot
                   2674:        .set    lldld,250       # left      dollar, dot
                   2675:        .set    rrnot,270       # right     not
                   2676:        .set    llnot,260       # left      not
                   2677:        .set    lluno,999       # left      all unary operators
                   2678: #
                   2679: #      PRECEDENCES ARE THE SAME AS IN BTL SNOBOL4 WITH THE
                   2680: #      FOLLOWING EXCEPTIONS.
                   2681: #
                   2682: #      1)   BINARY QUESTION MARK IS LOWERED AND MADE LEFT ASSOC-
                   2683: #           IATIVE TO REFLECT ITS NEW USE FOR PATTERN MATCHING.
                   2684: #
                   2685: #      2)   ALTERNATION AND CONCATENATION ARE MADE RIGHT
                   2686: #           ASSOCIATIVE FOR GREATER EFFICIENCY IN PATTERN
                   2687: #           CONSTRUCTION AND MATCHING RESPECTIVELY. THIS CHANGE
                   2688: #           IS TRANSPARENT TO THE SNOBOL4 PROGRAMMER.
                   2689: #
                   2690: #      3)   THE EQUAL SIGN HAS BEEN ADDED AS A LOW PRECEDENCE
                   2691: #           OPERATOR WHICH IS RIGHT ASSOCIATIVE TO REFLECT ITS
                   2692: #           MORE GENERAL USAGE IN THIS VERSION OF SNOBOL4.
                   2693:        #page   
                   2694: #
                   2695: #      EXTERNAL FUNCTION BLOCK (EFBLK)
                   2696: #
                   2697: #      AN EXTERNAL FUNCTION BLOCK IS USED TO CONTROL THE CALLING
                   2698: #      OF AN EXTERNAL FUNCTION. IT IS BUILT BY A CALL TO LOAD.
                   2699: #
                   2700: #           +------------------------------------+
                   2701: #           I                FCODE               I
                   2702: #           +------------------------------------+
                   2703: #           I                FARGS               I
                   2704: #           +------------------------------------+
                   2705: #           I                EFLEN               I
                   2706: #           +------------------------------------+
                   2707: #           I                EFUSE               I
                   2708: #           +------------------------------------+
                   2709: #           I                EFCOD               I
                   2710: #           +------------------------------------+
                   2711: #           I                EFVAR               I
                   2712: #           +------------------------------------+
                   2713: #           I                EFRSL               I
                   2714: #           +------------------------------------+
                   2715: #           /                                    /
                   2716: #           /                EFTAR               /
                   2717: #           /                                    /
                   2718: #           +------------------------------------+
                   2719: #
                   2720:        .set    eflen,fargs+1   # length of efblk in bytes
                   2721:        .set    efuse,eflen+1   # use count (for opsyn)
                   2722:        .set    efcod,efuse+1   # ptr to code (from sysld)
                   2723:        .set    efvar,efcod+1   # ptr to associated vrblk
                   2724:        .set    efrsl,efvar+1   # result type (see below)
                   2725:        .set    eftar,efrsl+1   # argument types (see below)
                   2726:        .set    efsi$,eftar     # number of standard fields in efblk
                   2727: #
                   2728: #      THE FCODE FIELD POINTS TO THE ROUTINE B$EFC.
                   2729: #
                   2730: #      EFUSE IS USED TO KEEP TRACK OF MULTIPLE USE WHEN OPSYN
                   2731: #      IS EMPLOYED. THE FUNCTION IS AUTOMATICALLY UNLOADED
                   2732: #      WHEN THERE ARE NO MORE REFERENCES TO THE FUNCTION.
                   2733: #
                   2734: #      EFRSL AND EFTAR ARE TYPE CODES AS FOLLOWS.
                   2735: #
                   2736: #           0                TYPE IS UNCONVERTED
                   2737: #           1                TYPE IS STRING
                   2738: #           2                TYPE IS INTEGER
                   2739: #           3                TYPE IS REAL
                   2740:        #page   
                   2741: #
                   2742: #      EXPRESSION VARIABLE BLOCK (EVBLK)
                   2743: #
                   2744: #      IN THIS VERSION OF SPITBOL, AN EXPRESSION CAN BE USED IN
                   2745: #      ANY POSITION WHICH WOULD NORMALLY EXPECT A NAME (FOR
                   2746: #      EXAMPLE ON THE LEFT SIDE OF EQUALS OR AS THE RIGHT
                   2747: #      ARGUMENT OF BINARY DOT). THIS CORRESPONDS TO THE CREATION
                   2748: #      OF A PSEUDO-VARIABLE WHICH IS REPRESENTED BY A POINTER TO
                   2749: #      AN EXPRESSION VARIABLE BLOCK AS FOLLOWS.
                   2750: #
                   2751: #           +------------------------------------+
                   2752: #           I                EVTYP               I
                   2753: #           +------------------------------------+
                   2754: #           I                EVEXP               I
                   2755: #           +------------------------------------+
                   2756: #           I                EVVAR               I
                   2757: #           +------------------------------------+
                   2758: #
                   2759:        .set    evtyp,0         # pointer to dummy routine b$evt
                   2760:        .set    evexp,evtyp+1   # pointer to exblk for expression
                   2761:        .set    evvar,evexp+1   # pointer to trbev dummy trblk
                   2762:        .set    evsi$,evvar+1   # size of evblk
                   2763: #
                   2764: #      THE NAME OF AN EXPRESSION VARIABLE IS REPRESENTED BY A
                   2765: #      BASE POINTER TO THE EVBLK AND AN OFFSET OF EVVAR. THIS
                   2766: #      VALUE APPEARS TO BE TRAPPED BY THE DUMMY TRBEV BLOCK.
                   2767: #
                   2768: #      NOTE THAT THERE IS NO NEED TO ALLOW FOR THE CASE OF AN
                   2769: #      EXPRESSION VARIABLE WHICH REFERENCES AN SEBLK SINCE A
                   2770: #      VARIABLE WHICH IS OF THE FORM *VAR IS EQUIVALENT TO VAR.
                   2771:        #page   
                   2772: #
                   2773: #      EXPRESSION BLOCK (EXBLK)
                   2774: #
                   2775: #      AN EXPRESSION BLOCK IS BUILT FOR EACH EXPRESSION
                   2776: #      REFERENCED IN A PROGRAM OR CREATED BY EVAL OR CONVERT
                   2777: #      DURING EXECUTION OF A PROGRAM.
                   2778: #
                   2779: #           +------------------------------------+
                   2780: #           I                EXTYP               I
                   2781: #           +------------------------------------+
                   2782: #           I                EXSTM               I
                   2783: #           +------------------------------------+
                   2784: #           I                EXLEN               I
                   2785: #           +------------------------------------+
                   2786: #           I                EXFLC               I
                   2787: #           +------------------------------------+
                   2788: #           /                                    /
                   2789: #           /                EXCOD               /
                   2790: #           /                                    /
                   2791: #           +------------------------------------+
                   2792: #
                   2793:        .set    extyp,0         # ptr to routine b$exl to load expr
                   2794:        .set    exstm,cdstm     # stores stmnt no. during evaluation
                   2795:        .set    exlen,exstm+1   # length of exblk in bytes
                   2796:        .set    exflc,exlen+1   # failure code (=o$fex)
                   2797:        .set    excod,exflc+1   # pseudo-code for expression
                   2798:        .set    exsi$,excod     # number of standard fields in exblk
                   2799: #
                   2800: #      THERE ARE TWO CASES FOR EXCOD DEPENDING ON WHETHER THE
                   2801: #      EXPRESSION CAN BE EVALUATED BY NAME (SEE DESCRIPTION
                   2802: #      OF CDBLK FOR DETAILS OF CODE FOR EXPRESSIONS).
                   2803: #
                   2804: #      IF THE EXPRESSION CAN BE EVALUATED BY NAME WE HAVE.
                   2805: #
                   2806: #                            (CODE FOR EXPR BY NAME)
                   2807: #                            =O$RNM
                   2808: #
                   2809: #      IF THE EXPRESSION CAN ONLY BE EVALUATED BY VALUE.
                   2810: #
                   2811: #                            (CODE FOR EXPR BY VALUE)
                   2812: #                            =O$RVL
                   2813:        #page   
                   2814: #
                   2815: #      FIELD FUNCTION BLOCK (FFBLK)
                   2816: #
                   2817: #      A FIELD FUNCTION BLOCK IS USED TO CONTROL THE SELECTION
                   2818: #      OF A FIELD FROM A PROGRAM DEFINED DATATYPE BLOCK.
                   2819: #      A CALL TO DATA CREATES AN FFBLK FOR EACH FIELD.
                   2820: #
                   2821: #           +------------------------------------+
                   2822: #           I                FCODE               I
                   2823: #           +------------------------------------+
                   2824: #           I                FARGS               I
                   2825: #           +------------------------------------+
                   2826: #           I                FFDFP               I
                   2827: #           +------------------------------------+
                   2828: #           I                FFNXT               I
                   2829: #           +------------------------------------+
                   2830: #           I                FFOFS               I
                   2831: #           +------------------------------------+
                   2832: #
                   2833:        .set    ffdfp,fargs+1   # pointer to associated dfblk
                   2834:        .set    ffnxt,ffdfp+1   # ptr to next ffblk on chain or zero
                   2835:        .set    ffofs,ffnxt+1   # offset (bytes) to field in pdblk
                   2836:        .set    ffsi$,ffofs+1   # size of ffblk in words
                   2837: #
                   2838: #      THE FCODE FIELD POINTS TO THE ROUTINE B$FFC.
                   2839: #
                   2840: #      FARGS ALWAYS CONTAINS ONE.
                   2841: #
                   2842: #      FFDFP IS USED TO VERIFY THAT THE CORRECT PROGRAM DEFINED
                   2843: #      DATATYPE IS BEING ACCESSED BY THIS CALL.
                   2844: #      FFDFP IS NON-RELOC. BECAUSE DFBLK IS IN STATIC
                   2845: #
                   2846: #      FFOFS IS USED TO SELECT THE APPROPRIATE FIELD. NOTE THAT
                   2847: #      IT IS AN ACTUAL OFFSET (NOT A FIELD NUMBER)
                   2848: #
                   2849: #      FFNXT IS USED TO POINT TO THE NEXT FFBLK OF THE SAME NAME
                   2850: #      IN THE CASE WHERE THERE ARE SEVERAL FIELDS OF THE SAME
                   2851: #      NAME FOR DIFFERENT DATATYPES. ZERO MARKS THE END OF CHAIN
                   2852:        #page   
                   2853: #
                   2854: #      INTEGER CONSTANT BLOCK (ICBLK)
                   2855: #
                   2856: #      AN ICBLK IS CREATED FOR EVERY INTEGER REFERENCED OR
                   2857: #      CREATED BY A PROGRAM. NOTE HOWEVER THAT CERTAIN INTERNAL
                   2858: #      INTEGER VALUES ARE STORED AS ADDRESSES (E.G. THE LENGTH
                   2859: #      FIELD IN A STRING CONSTANT BLOCK)
                   2860: #
                   2861: #           +------------------------------------+
                   2862: #           I                ICGET               I
                   2863: #           +------------------------------------+
                   2864: #           *                ICVAL               *
                   2865: #           +------------------------------------+
                   2866: #
                   2867:        .set    icget,0         # ptr to routine b$icl to load int
                   2868:        .set    icval,icget+1   # integer value
                   2869:        .set    icsi$,icval+cfp$i# size of icblk
                   2870: #
                   2871: #      THE LENGTH OF THE ICVAL FIELD IS CFP$I.
                   2872:        #page   
                   2873: #
                   2874: #      KEYWORD VARIABLE BLOCK (KVBLK)
                   2875: #
                   2876: #      A KVBLK IS USED TO REPRESENT A KEYWORD PSEUDO-VARIABLE.
                   2877: #      A KVBLK IS BUILT FOR EACH KEYWORD REFERENCE (KWNAM).
                   2878: #
                   2879: #           +------------------------------------+
                   2880: #           I                KVTYP               I
                   2881: #           +------------------------------------+
                   2882: #           I                KVVAR               I
                   2883: #           +------------------------------------+
                   2884: #           I                KVNUM               I
                   2885: #           +------------------------------------+
                   2886: #
                   2887:        .set    kvtyp,0         # pointer to dummy routine b$kvt
                   2888:        .set    kvvar,kvtyp+1   # pointer to dummy block trbkv
                   2889:        .set    kvnum,kvvar+1   # keyword number
                   2890:        .set    kvsi$,kvnum+1   # size of kvblk
                   2891: #
                   2892: #      THE NAME OF A KEYWORD VARIABLE IS REPRESENTED BY A
                   2893: #      BASE POINTER TO THE KVBLK AND AN OFFSET OF KVVAR. THE
                   2894: #      VALUE APPEARS TO BE TRAPPED BY THE POINTER TO TRBKV.
                   2895:        #page   
                   2896: #
                   2897: #      NAME BLOCK (NMBLK)
                   2898: #
                   2899: #      A NAME BLOCK IS USED WHEREVER A NAME MUST BE STORED AS
                   2900: #      A VALUE FOLLOWING USE OF THE UNARY DOT OPERATOR.
                   2901: #
                   2902: #           +------------------------------------+
                   2903: #           I                NMTYP               I
                   2904: #           +------------------------------------+
                   2905: #           I                NMBAS               I
                   2906: #           +------------------------------------+
                   2907: #           I                NMOFS               I
                   2908: #           +------------------------------------+
                   2909: #
                   2910:        .set    nmtyp,0         # ptr to routine b$nml to load name
                   2911:        .set    nmbas,nmtyp+1   # base pointer for variable
                   2912:        .set    nmofs,nmbas+1   # offset for variable
                   2913:        .set    nmsi$,nmofs+1   # size of nmblk
                   2914: #
                   2915: #      THE ACTUAL FIELD REPRESENTING THE CONTENTS OF THE NAME
                   2916: #      IS FOUND NMOFS BYTES PAST THE ADDRESS IN NMBAS.
                   2917: #
                   2918: #      THE NAME IS SPLIT INTO BASE AND OFFSET FORM TO AVOID
                   2919: #      CREATION OF A POINTER INTO THE MIDDLE OF A BLOCK WHICH
                   2920: #      COULD NOT BE HANDLED PROPERLY BY THE GARBAGE COLLECTOR.
                   2921: #
                   2922: #      A NAME MAY BE BUILT FOR ANY VARIABLE (SEE SECTION ON
                   2923: #      REPRESENTATIONS OF VARIABLES) THIS INCLUDES THE
                   2924: #      CASES OF PSEUDO-VARIABLES.
                   2925:        #page   
                   2926: #
                   2927: #      PATTERN BLOCK, NO PARAMETERS (P0BLK)
                   2928: #
                   2929: #      A P0BLK IS USED TO REPRESENT PATTERN NODES WHICH DO
                   2930: #      NOT REQUIRE THE USE OF ANY PARAMETER VALUES.
                   2931: #
                   2932: #           +------------------------------------+
                   2933: #           I                PCODE               I
                   2934: #           +------------------------------------+
                   2935: #           I                PTHEN               I
                   2936: #           +------------------------------------+
                   2937: #
                   2938:        .set    pcode,0         # ptr to match routine (p$xxx)
                   2939:        .set    pthen,pcode+1   # pointer to subsequent node
                   2940:        .set    pasi$,pthen+1   # size of p0blk
                   2941: #
                   2942: #      PTHEN POINTS TO THE PATTERN BLOCK FOR THE SUBSEQUENT
                   2943: #      NODE TO BE MATCHED. THIS IS A POINTER TO THE PATTERN
                   2944: #      BLOCK NDNTH IF THERE IS NO SUBSEQUENT (END OF PATTERN)
                   2945: #
                   2946: #      PCODE IS A POINTER TO THE MATCH ROUTINE FOR THE NODE.
                   2947:        #page   
                   2948: #
                   2949: #      PATTERN BLOCK (ONE PARAMETER)
                   2950: #
                   2951: #      A P1BLK IS USED TO REPRESENT PATTERN NODES WHICH
                   2952: #      REQUIRE ONE PARAMETER VALUE.
                   2953: #
                   2954: #           +------------------------------------+
                   2955: #           I                PCODE               I
                   2956: #           +------------------------------------+
                   2957: #           I                PTHEN               I
                   2958: #           +------------------------------------+
                   2959: #           I                PARM1               I
                   2960: #           +------------------------------------+
                   2961: #
                   2962:        .set    parm1,pthen+1   # first parameter value
                   2963:        .set    pbsi$,parm1+1   # size of p1blk in words
                   2964: #
                   2965: #      SEE P0BLK FOR DEFINITIONS OF PCODE, PTHEN
                   2966: #
                   2967: #      PARM1 CONTAINS A PARAMETER VALUE USED IN MATCHING THE
                   2968: #      NODE. FOR EXAMPLE, IN A LEN PATTERN, IT IS THE INTEGER
                   2969: #      ARGUMENT TO LEN. THE DETAILS OF THE USE OF THE PARAMETER
                   2970: #      FIELD ARE INCLUDED IN THE DESCRIPTION OF THE INDIVIDUAL
                   2971: #      MATCH ROUTINES. PARM1 IS ALWAYS AN ADDRESS POINTER WHICH
                   2972: #      IS PROCESSED BY THE GARBAGE COLLECTOR.
                   2973:        #page   
                   2974: #
                   2975: #      PATTERN BLOCK (TWO PARAMETERS)
                   2976: #
                   2977: #      A P2BLK IS USED TO REPRESENT PATTERN NODES WHICH
                   2978: #      REQUIRE TWO PARAMETER VALUES.
                   2979: #
                   2980: #           +------------------------------------+
                   2981: #           I                PCODE               I
                   2982: #           +------------------------------------+
                   2983: #           I                PTHEN               I
                   2984: #           +------------------------------------+
                   2985: #           I                PARM1               I
                   2986: #           +------------------------------------+
                   2987: #           I                PARM2               I
                   2988: #           +------------------------------------+
                   2989: #
                   2990:        .set    parm2,parm1+1   # second parameter value
                   2991:        .set    pcsi$,parm2+1   # size of p2blk in words
                   2992: #
                   2993: #      SEE P1BLK FOR DEFINITIONS OF PCODE, PTHEN, PARM1
                   2994: #
                   2995: #      PARM2 IS A PARAMETER WHICH PERFORMS THE SAME SORT OF
                   2996: #      FUNCTION AS PARM1 (SEE DESCRIPTION OF P1BLK).
                   2997: #
                   2998: #      PARM2 IS A NON-RELOCATABLE FIELD AND IS NOT
                   2999: #      PROCESSED BY THE GARBAGE COLLECTOR. ACCORDINGLY, IT MAY
                   3000: #      NOT CONTAIN A POINTER TO A BLOCK IN DYNAMIC MEMORY.
                   3001:        #page   
                   3002: #
                   3003: #      PROGRAM-DEFINED DATATYPE BLOCK
                   3004: #
                   3005: #      A PDBLK REPRESENTS THE DATA ITEM FORMED BY A CALL TO A
                   3006: #      DATATYPE FUNCTION AS DEFINED BY THE SYSTEM FUNCTION DATA.
                   3007: #
                   3008: #           +------------------------------------+
                   3009: #           I                PDTYP               I
                   3010: #           +------------------------------------+
                   3011: #           I                IDVAL               I
                   3012: #           +------------------------------------+
                   3013: #           I                PDDFP               I
                   3014: #           +------------------------------------+
                   3015: #           /                                    /
                   3016: #           /                PDFLD               /
                   3017: #           /                                    /
                   3018: #           +------------------------------------+
                   3019: #
                   3020:        .set    pdtyp,0         # ptr to dummy routine b$pdt
                   3021:        .set    pddfp,idval+1   # ptr to associated dfblk
                   3022:        .set    pdfld,pddfp+1   # start of field value pointers
                   3023:        .set    pdfof,dffld-pdfld# difference in offset to field ptrs
                   3024:        .set    pdsi$,pdfld     # size of standard fields in pdblk
                   3025:        .set    pddfs,dfsi$-pdsi$# difference in dfblk, pdblk sizes
                   3026: #
                   3027: #      THE PDDFP POINTER MAY BE USED TO DETERMINE THE DATATYPE
                   3028: #      AND THE NAMES OF THE FIELDS IF REQUIRED. THE DFBLK ALSO
                   3029: #      CONTAINS THE LENGTH OF THE PDBLK IN BYTES (FIELD DFPDL).
                   3030: #      PDDFP IS NON-RELOC. BECAUSE DFBLK IS IN STATIC
                   3031: #
                   3032: #      PDFLD VALUES ARE STORED IN ORDER FROM LEFT TO RIGHT.
                   3033: #      THEY CONTAIN VALUES OR POINTERS TO TRBLK CHAINS.
                   3034:        #page   
                   3035: #
                   3036: #      PROGRAM DEFINED FUNCTION BLOCK (PFBLK)
                   3037: #
                   3038: #      A PFBLK IS CREATED FOR EACH CALL TO THE DEFINE FUNCTION
                   3039: #      AND A POINTER TO THE PFBLK PLACED IN THE PROPER VRBLK.
                   3040: #
                   3041: #           +------------------------------------+
                   3042: #           I                FCODE               I
                   3043: #           +------------------------------------+
                   3044: #           I                FARGS               I
                   3045: #           +------------------------------------+
                   3046: #           I                PFLEN               I
                   3047: #           +------------------------------------+
                   3048: #           I                PFVBL               I
                   3049: #           +------------------------------------+
                   3050: #           I                PFNLO               I
                   3051: #           +------------------------------------+
                   3052: #           I                PFCOD               I
                   3053: #           +------------------------------------+
                   3054: #           I                PFCTR               I
                   3055: #           +------------------------------------+
                   3056: #           I                PFRTR               I
                   3057: #           +------------------------------------+
                   3058: #           /                                    /
                   3059: #           /                PFARG               /
                   3060: #           /                                    /
                   3061: #           +------------------------------------+
                   3062: #
                   3063:        .set    pflen,fargs+1   # length of pfblk in bytes
                   3064:        .set    pfvbl,pflen+1   # pointer to vrblk for function name
                   3065:        .set    pfnlo,pfvbl+1   # number of locals
                   3066:        .set    pfcod,pfnlo+1   # ptr to cdblk for first statement
                   3067:        .set    pfctr,pfcod+1   # trblk ptr if call traced else 0
                   3068:        .set    pfrtr,pfctr+1   # trblk ptr if return traced else 0
                   3069:        .set    pfarg,pfrtr+1   # vrblk ptrs for arguments and locals
                   3070:        .set    pfagb,pfarg-1   # offset behind pfarg for arg, local
                   3071:        .set    pfsi$,pfarg     # number of standard fields in pfblk
                   3072: #
                   3073: #      THE FCODE FIELD POINTS TO THE ROUTINE B$PFC.
                   3074: #
                   3075: #      PFARG IS STORED IN THE FOLLOWING ORDER.
                   3076: #
                   3077: #           ARGUMENTS (LEFT TO RIGHT)
                   3078: #           LOCALS (LEFT TO RIGHT)
                   3079:        #page   
                   3080: #
                   3081: #      REAL CONSTANT BLOCK (RCBLK)
                   3082: #
                   3083: #      AN RCBLK IS CREATED FOR EVERY REAL REFERENCED OR
                   3084: #      CREATED BY A PROGRAM.
                   3085: #
                   3086: #           +------------------------------------+
                   3087: #           I                RCGET               I
                   3088: #           +------------------------------------+
                   3089: #           *                RCVAL               *
                   3090: #           +------------------------------------+
                   3091: #
                   3092:        .set    rcget,0         # ptr to routine b$rcl to load real
                   3093:        .set    rcval,rcget+1   # real value
                   3094:        .set    rcsi$,rcval+cfp$r# size of rcblk
                   3095: #
                   3096: #      THE LENGTH OF THE RCVAL FIELD IS CFP$R.
                   3097:        #page   
                   3098: #
                   3099: #      STRING CONSTANT BLOCK (SCBLK)
                   3100: #
                   3101: #      AN SCBLK IS BUILT FOR EVERY STRING REFERENCED OR CREATED
                   3102: #      BY A PROGRAM.
                   3103: #
                   3104: #           +------------------------------------+
                   3105: #           I                SCGET               I
                   3106: #           +------------------------------------+
                   3107: #           I                SCLEN               I
                   3108: #           +------------------------------------+
                   3109: #           /                                    /
                   3110: #           /                SCHAR               /
                   3111: #           /                                    /
                   3112: #           +------------------------------------+
                   3113: #
                   3114:        .set    scget,0         # ptr to routine b$scl to load string
                   3115:        .set    sclen,scget+1   # length of string in characters
                   3116:        .set    schar,sclen+1   # characters of string
                   3117:        .set    scsi$,schar     # size of standard fields in scblk
                   3118: #
                   3119: #      THE CHARACTERS OF THE STRING ARE STORED LEFT JUSTIFIED.
                   3120: #      THE FINAL WORD IS PADDED ON THE RIGHT WITH ZEROS.
                   3121: #      (I.E. THE CHARACTER WHOSE INTERNAL CODE IS ZERO).
                   3122: #
                   3123: #      THE VALUE OF SCLEN MAY NOT EXCEED MXLEN. THIS ENSURES
                   3124: #      THAT CHARACTER OFFSETS (E.G. THE PATTERN MATCH CURSOR)
                   3125: #      CAN BE CORRECTLY PROCESSED BY THE GARBAGE COLLECTOR.
                   3126: #
                   3127: #      NOTE THAT THE OFFSET TO THE CHARACTERS OF THE STRING
                   3128: #      IS GIVEN IN BYTES BY CFP$F AND THAT THIS VALUE IS
                   3129: #      AUTOMATICALLY ALLOWED FOR IN PLC, PSC.
                   3130: #      NOTE THAT FOR A SPITBOL SCBLK, THE VALUE OF CFP$F
                   3131: #      IS GIVEN BY CFP$B*SCHAR.
                   3132:        #page   
                   3133: #
                   3134: #      SIMPLE EXPRESSION BLOCK (SEBLK)
                   3135: #
                   3136: #      AN SEBLK IS USED TO REPRESENT AN EXPRESSION OF THE FORM
                   3137: #      *(NATURAL VARIABLE). ALL OTHER EXPRESSIONS ARE EXBLKS.
                   3138: #
                   3139: #           +------------------------------------+
                   3140: #           I                SETYP               I
                   3141: #           +------------------------------------+
                   3142: #           I                SEVAR               I
                   3143: #           +------------------------------------+
                   3144: #
                   3145:        .set    setyp,0         # ptr to routine b$sel to load expr
                   3146:        .set    sevar,setyp+1   # ptr to vrblk for variable
                   3147:        .set    sesi$,sevar+1   # length of seblk in words
                   3148:        #page   
                   3149: #
                   3150: #      STANDARD VARIABLE BLOCK (SVBLK)
                   3151: #
                   3152: #      AN SVBLK IS ASSEMBLED IN THE CONSTANT SECTION FOR EACH
                   3153: #      VARIABLE WHICH SATISFIES ONE OF THE FOLLOWING CONDITIONS.
                   3154: #
                   3155: #      1)   IT IS THE NAME OF A SYSTEM FUNCTION
                   3156: #      2)   IT HAS AN INITIAL VALUE
                   3157: #      3)   IT HAS A KEYWORD ASSOCIATION
                   3158: #      4)   IT HAS A STANDARD I/O ASSOCIATION
                   3159: #      6)   IT HAS A STANDARD LABEL ASSOCIATION
                   3160: #
                   3161: #      IF VRBLKS ARE CONSTRUCTED FOR ANY OF THESE VARIABLES,
                   3162: #      THEN THE VRSVP FIELD POINTS TO THE SVBLK (SEE VRBLK)
                   3163: #
                   3164: #           +------------------------------------+
                   3165: #           I                SVBIT               I
                   3166: #           +------------------------------------+
                   3167: #           I                SVLEN               I
                   3168: #           +------------------------------------+
                   3169: #           I                SVCHS               I
                   3170: #           +------------------------------------+
                   3171: #           I                SVKNM               I
                   3172: #           +------------------------------------+
                   3173: #           I                SVFNC               I
                   3174: #           +------------------------------------+
                   3175: #           I                SVNAR               I
                   3176: #           +------------------------------------+
                   3177: #           I                SVLBL               I
                   3178: #           +------------------------------------+
                   3179: #           I                SVVAL               I
                   3180: #           +------------------------------------+
                   3181:        #page   
                   3182: #
                   3183: #      STANDARD VARIABLE BLOCK (CONTINUED)
                   3184: #
                   3185:        .set    svbit,0         # bit string indicating attributes
                   3186:        .set    svlen,1         # (=sclen) length of name in chars
                   3187:        .set    svchs,2         # (=schar) characters of name
                   3188:        .set    svsi$,2         # number of standard fields in svblk
                   3189:        .set    svpre,1         # set if preevaluation permitted
                   3190:        .set    svffc,svpre+svpre# set on if fast call permitted
                   3191:        .set    svckw,svffc+svffc# set on if keyword value constant
                   3192:        .set    svprd,svckw+svckw# set on if predicate function
                   3193:        .set    svnbt,4         # number of bits to right of svknm
                   3194:        .set    svknm,svprd+svprd# set on if keyword association
                   3195:        .set    svfnc,svknm+svknm# set on if system function
                   3196:        .set    svnar,svfnc+svfnc# set on if system function
                   3197:        .set    svlbl,svnar+svnar# set on if system label
                   3198:        .set    svval,svlbl+svlbl# set on if predefined value
                   3199: #
                   3200: #      NOTE THAT THE LAST FIVE BITS CORRESPOND IN ORDER
                   3201: #      TO THE FIELDS WHICH ARE PRESENT (SEE PROCEDURE GTNVR).
                   3202: #
                   3203: #      THE FOLLOWING DEFINITIONS ARE USED IN THE SVBLK TABLE
                   3204: #
                   3205:        .set    svfnf,svfnc+svnar# function with no fast call
                   3206:        .set    svfnn,svfnf+svffc# function with fast call, no preeval
                   3207:        .set    svfnp,svfnn+svpre# function allowing preevaluation
                   3208:        .set    svfpr,svfnn+svprd# predicate function
                   3209:        .set    svfnk,svfnn+svknm# no preeval func + keyword
                   3210:        .set    svkwv,svknm+svval# keyword + value
                   3211:        .set    svkwc,svckw+svknm# keyword with constant value
                   3212:        .set    svkvc,svkwv+svckw# constant keyword + value
                   3213:        .set    svkvl,svkvc+svlbl# constant keyword + value + label
                   3214:        .set    svfpk,svfnp+svkvc# preeval fcn + const keywd + val
                   3215: #
                   3216: #      THE SVPRE BIT ALLOWS THE COMPILER TO PREEVALUATE A CALL
                   3217: #      TO THE ASSOCIATED SYSTEM FUNCTION IF ALL THE ARGUMENTS
                   3218: #      ARE THEMSELVES CONSTANTS. FUNCTIONS IN THIS CATEGORY
                   3219: #      MUST HAVE NO SIDE EFFECTS AND MUST NEVER CAUSE FAILURE.
                   3220: #      THE CALL MAY GENERATE AN ERROR CONDITION.
                   3221: #
                   3222: #      THE SVFFC BIT ALLOWS THE COMPILER TO GENERATE THE SPECIAL
                   3223: #      FAST CALL AFTER ADJUSTING THE NUMBER OF ARGUMENTS. ONLY
                   3224: #      THE ITEM AND APPLY FUNCTIONS FALL OUTSIDE THIS CATEGORY.
                   3225: #
                   3226: #      THE SVCKW BIT IS SET IF THE ASSOCIATED KEYWORD VALUE IS
                   3227: #      A CONSTANT, THUS ALLOWING PREEVALUATION FOR A VALUE CALL.
                   3228: #
                   3229: #      THE SVPRD BIT IS SET ON FOR ALL PREDICATE FUNCTIONS TO
                   3230: #      ENABLE THE SPECIAL CONCATENATION CODE OPTIMIZATION.
                   3231:        #page   
                   3232: #
                   3233: #      SVBLK (CONTINUED)
                   3234: #
                   3235: #      SVKNM                 KEYWORD NUMBER
                   3236: #
                   3237: #           SVKNM IS PRESENT ONLY FOR A STANDARD KEYWORD ASSOC.
                   3238: #           IT CONTAINS A KEYWORD NUMBER AS DEFINED BY THE
                   3239: #           KEYWORD NUMBER TABLE GIVEN LATER ON.
                   3240: #
                   3241: #      SVFNC                 SYSTEM FUNCTION POINTER
                   3242: #
                   3243: #           SVFNC IS PRESENT ONLY FOR A SYSTEM FUNCTION ASSOC.
                   3244: #           IT IS A POINTER TO THE ACTUAL CODE FOR THE SYSTEM
                   3245: #           FUNCTION. THE GENERATED CODE FOR A FAST CALL IS A
                   3246: #           POINTER TO THE SVFNC FIELD OF THE SVBLK FOR THE
                   3247: #           FUNCTION. THE VRFNC FIELD OF THE VRBLK POINTS TO
                   3248: #           THIS SAME FIELD, IN WHICH CASE, IT SERVES AS THE
                   3249: #           FCODE FIELD FOR THE FUNCTION CALL.
                   3250: #
                   3251: #      SVNAR                 NUMBER OF FUNCTION ARGUMENTS
                   3252: #
                   3253: #           SVNAR IS PRESENT ONLY FOR A SYSTEM FUNCTION ASSOC.
                   3254: #           IT IS THE NUMBER OF ARGUMENTS REQUIRED FOR A CALL
                   3255: #           TO THE SYSTEM FUNCTION. THE COMPILER USES THIS
                   3256: #           VALUE TO ADJUST THE NUMBER OF ARGUMENTS IN A FAST
                   3257: #           CALL AND IN THE CASE OF A FUNCTION CALLED THROUGH
                   3258: #           THE VRFNC FIELD OF THE VRBLK, THE SVNAR FIELD
                   3259: #           SERVES AS THE FARGS FIELD FOR O$FNC. A SPECIAL
                   3260: #           CASE OCCURS IF THIS VALUE IS SET TO 999. THIS IS
                   3261: #           USED TO INDICATE THAT THE FUNCTION HAS A VARIABLE
                   3262: #           NUMBER OF ARGUMENTS AND CAUSES O$FNC TO PASS CONTROL
                   3263: #           WITHOUT ADJUSTING THE ARGUMENT COUNT. THE ONLY
                   3264: #           PREDEFINED FUNCTIONS USING THIS ARE APPLY AND ITEM.
                   3265: #
                   3266: #      SVLBL                 SYSTEM LABEL POINTER
                   3267: #
                   3268: #           SVLBL IS PRESENT ONLY FOR A STANDARD LABEL ASSOC.
                   3269: #           IT IS A POINTER TO A SYSTEM LABEL ROUTINE (L$XXX).
                   3270: #           THE VRLBL FIELD OF THE CORRESPONDING VRBLK POINTS TO
                   3271: #           THE SVLBL FIELD OF THE SVBLK.
                   3272: #
                   3273: #      SVVAL                 SYSTEM VALUE POINTER
                   3274: #
                   3275: #           SVVAL IS PRESENT ONLY FOR A STANDARD VALUE.
                   3276: #           IT IS A POINTER TO THE PATTERN NODE (NDXXX) WHICH
                   3277: #           IS THE STANDARD INITIAL VALUE OF THE VARIABLE.
                   3278: #           THIS VALUE IS COPIED TO THE VRVAL FIELD OF THE VRBLK
                   3279:        #page   
                   3280: #
                   3281: #      SVBLK (CONTINUED)
                   3282: #
                   3283: #      KEYWORD NUMBER TABLE
                   3284: #
                   3285: #      THE FOLLOWING TABLE GIVES SYMBOLIC NAMES FOR KEYWORD
                   3286: #      NUMBERS. THESE VALUES ARE STORED IN THE SVKNM FIELD OF
                   3287: #      SVBLKS AND IN THE KVNUM FIELD OF KVBLKS. SEE ALSO
                   3288: #      PROCEDURES ASIGN, ACESS AND KWNAM.
                   3289: #
                   3290: #      UNPROTECTED KEYWORDS WITH ONE WORD INTEGER VALUES
                   3291: #
                   3292:        .set    k$abe,0         # abend
                   3293:        .set    k$anc,k$abe+cfp$b# anchor
                   3294:        .set    k$cas,k$anc+cfp$b# case
                   3295:        .set    k$cod,k$cas+cfp$b# code
                   3296:        .set    k$dmp,k$cod+cfp$b# dump
                   3297:        .set    k$erl,k$dmp+cfp$b# errlimit
                   3298:        .set    k$ert,k$erl+cfp$b# errtype
                   3299:        .set    k$ftr,k$ert+cfp$b# ftrace
                   3300:        .set    k$inp,k$ftr+cfp$b# input
                   3301:        .set    k$mxl,k$inp+cfp$b# maxlength
                   3302:        .set    k$oup,k$mxl+cfp$b# output
                   3303:        .set    k$pfl,k$oup+cfp$b# profile
                   3304:        .set    k$tra,k$pfl+cfp$b# trace
                   3305:        .set    k$trm,k$tra+cfp$b# trim
                   3306: #
                   3307: #      PROTECTED KEYWORDS WITH ONE WORD INTEGER VALUES
                   3308: #
                   3309:        .set    k$fnc,k$trm+cfp$b# fnclevel
                   3310:        .set    k$lst,k$fnc+cfp$b# lastno
                   3311:        .set    k$stn,k$lst+cfp$b# stno
                   3312: #
                   3313: #      KEYWORDS WITH CONSTANT PATTERN VALUES
                   3314: #
                   3315:        .set    k$abo,k$stn+cfp$b# abort
                   3316:        .set    k$arb,k$abo+pasi$# arb
                   3317:        .set    k$bal,k$arb+pasi$# bal
                   3318:        .set    k$fal,k$bal+pasi$# fail
                   3319:        .set    k$fen,k$fal+pasi$# fence
                   3320:        .set    k$rem,k$fen+pasi$# rem
                   3321:        .set    k$suc,k$rem+pasi$# succeed
                   3322:        #page   
                   3323: #
                   3324: #      KEYWORD NUMBER TABLE (CONTINUED)
                   3325: #
                   3326: #      SPECIAL KEYWORDS
                   3327: #
                   3328:        .set    k$alp,k$suc+1   # alphabet
                   3329:        .set    k$rtn,k$alp+1   # rtntype
                   3330:        .set    k$stc,k$rtn+1   # stcount
                   3331:        .set    k$etx,k$stc+1   # errtext
                   3332:        .set    k$stl,k$etx+1   # stlimit
                   3333: #
                   3334: #      RELATIVE OFFSETS OF SPECIAL KEYWORDS
                   3335: #
                   3336:        .set    k$$al,k$alp-k$alp# alphabet
                   3337:        .set    k$$rt,k$rtn-k$alp# rtntype
                   3338:        .set    k$$sc,k$stc-k$alp# stcount
                   3339:        .set    k$$et,k$etx-k$alp# errtext
                   3340:        .set    k$$sl,k$stl-k$alp# stlimit
                   3341: #
                   3342: #      SYMBOLS USED IN ASIGN AND ACESS PROCEDURES
                   3343: #
                   3344:        .set    k$p$$,k$fnc     # first protected keyword
                   3345:        .set    k$v$$,k$abo     # first keyword with constant value
                   3346:        .set    k$s$$,k$alp     # first keyword with special acess
                   3347:        #page   
                   3348: #
                   3349: #      FORMAT OF A TABLE BLOCK (TBBLK)
                   3350: #
                   3351: #      A TABLE BLOCK IS USED TO REPRESENT A TABLE VALUE.
                   3352: #      IT IS BUILT BY A CALL TO THE TABLE OR CONVERT FUNCTIONS.
                   3353: #
                   3354: #           +------------------------------------+
                   3355: #           I                TBTYP               I
                   3356: #           +------------------------------------+
                   3357: #           I                IDVAL               I
                   3358: #           +------------------------------------+
                   3359: #           I                TBLEN               I
                   3360: #           +------------------------------------+
                   3361: #           +------------------------------------+
                   3362: #           I                TBINV               I
                   3363: #           +------------------------------------+
                   3364: #           /                                    /
                   3365: #           /                TBBUK               /
                   3366: #           /                                    /
                   3367: #           +------------------------------------+
                   3368: #
                   3369:        .set    tbtyp,0         # pointer to dummy routine b$tbt
                   3370:        .set    tblen,offs2     # length of tbblk in bytes
                   3371:        .set    tbinv,offs3     # default initial lookup value
                   3372:        .set    tbbuk,tbinv+1   # start of hash bucket pointers
                   3373:        .set    tbsi$,tbbuk     # size of standard fields in tbblk
                   3374:        .set    tbnbk,11        # default no. of buckets
                   3375: #
                   3376: #      THE TABLE BLOCK IS A HASH TABLE WHICH POINTS TO CHAINS
                   3377: #      OF TABLE ELEMENT BLOCKS REPRESENTING THE ELEMENTS
                   3378: #      IN THE TABLE WHICH HASH INTO THE SAME BUCKET.
                   3379: #
                   3380: #      TBBUK ENTRIES EITHER POINT TO THE FIRST TEBLK ON THE
                   3381: #      CHAIN OR THEY POINT TO THE TBBLK ITSELF TO INDICATE THE
                   3382: #      END OF THE CHAIN.
                   3383:        #page   
                   3384: #
                   3385: #      TABLE ELEMENT BLOCK (TEBLK)
                   3386: #
                   3387: #      A TABLE ELEMENT IS USED TO REPRESENT A SINGLE ENTRY IN
                   3388: #      A TABLE (SEE DESCRIPTION OF TBBLK FORMAT FOR HASH TABLE)
                   3389: #
                   3390: #           +------------------------------------+
                   3391: #           I                TETYP               I
                   3392: #           +------------------------------------+
                   3393: #           I                TESUB               I
                   3394: #           +------------------------------------+
                   3395: #           I                TEVAL               I
                   3396: #           +------------------------------------+
                   3397: #           I                TENXT               I
                   3398: #           +------------------------------------+
                   3399: #
                   3400:        .set    tetyp,0         # pointer to dummy routine b$tet
                   3401:        .set    tesub,tetyp+1   # subscript value
                   3402:        .set    teval,tesub+1   # (=vrval) table element value
                   3403:        .set    tenxt,teval+1   # link to next teblk
                   3404: #      SEE S$CNV WHERE RELATION IS ASSUMED WITH TENXT AND TBBUK
                   3405:        .set    tesi$,tenxt+1   # size of teblk in words
                   3406: #
                   3407: #      TENXT POINTS TO THE NEXT TEBLK ON THE HASH CHAIN FROM THE
                   3408: #      TBBUK CHAIN FOR THIS HASH INDEX. AT THE END OF THE CHAIN,
                   3409: #      TENXT POINTS BACK TO THE START OF THE TBBLK.
                   3410: #
                   3411: #      TEVAL CONTAINS A DATA POINTER OR A TRBLK POINTER.
                   3412: #
                   3413: #      TESUB CONTAINS A DATA POINTER.
                   3414:        #page   
                   3415: #
                   3416: #      TRAP BLOCK (TRBLK)
                   3417: #
                   3418: #      A TRAP BLOCK IS USED TO REPRESENT A TRACE OR INPUT OR
                   3419: #      OUTPUT ASSOCIATION IN RESPONSE TO A CALL TO THE TRACE
                   3420: #      INPUT OR OUTPUT SYSTEM FUNCTIONS. SEE BELOW FOR DETAILS
                   3421: #
                   3422: #           +------------------------------------+
                   3423: #           I                TRIDN               I
                   3424: #           +------------------------------------+
                   3425: #           I                TRTYP               I
                   3426: #           +------------------------------------+
                   3427: #           I  TRVAL OR TRLBL OR TRNXT OR TRKVR  I
                   3428: #           +------------------------------------+
                   3429: #           I       TRTAG OR TRTER OR TRTRF      I
                   3430: #           +------------------------------------+
                   3431: #           I            TRFNC OR TRFPT          I
                   3432: #           +------------------------------------+
                   3433: #
                   3434:        .set    tridn,0         # pointer to dummy routine b$trt
                   3435:        .set    trtyp,tridn+1   # trap type code
                   3436:        .set    trval,trtyp+1   # value of trapped variable (=vrval)
                   3437:        .set    trnxt,trval     # ptr to next trblk on trblk chain
                   3438:        .set    trlbl,trval     # ptr to actual label (traced label)
                   3439:        .set    trkvr,trval     # vrblk pointer for keyword trace
                   3440:        .set    trtag,trval+1   # trace tag
                   3441:        .set    trter,trtag     # ptr to terminal vrblk or null
                   3442:        .set    trtrf,trtag     # ptr to trblk holding fcblk ptr
                   3443:        .set    trfnc,trtag+1   # trace function vrblk (zero if none)
                   3444:        .set    trfpt,trfnc     # fcblk ptr for sysio
                   3445:        .set    trsi$,trfnc+1   # number of words in trblk
                   3446: #
                   3447:        .set    trtin,0         # trace type for input association
                   3448:        .set    trtac,trtin+1   # trace type for access trace
                   3449:        .set    trtvl,trtac+1   # trace type for value trace
                   3450:        .set    trtou,trtvl+1   # trace type for output association
                   3451:        .set    trtfc,trtou+1   # trace type for fcblk identification
                   3452:        #page   
                   3453: #
                   3454: #      TRAP BLOCK (CONTINUED)
                   3455: #
                   3456: #      VARIABLE INPUT ASSOCIATION
                   3457: #
                   3458: #           THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK
                   3459: #           INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE
                   3460: #           OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS
                   3461: #           CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK.
                   3462: #
                   3463: #           TRTYP IS SET TO TRTIN
                   3464: #           TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL
                   3465: #           TRTER IS A POINTER TO SVBLK IF ASSOCIATION IS
                   3466: #           FOR INPUT, TERMINAL, ELSE IT IS NULL.
                   3467: #           TRTRF POINTS TO THE TRAP BLOCK WHICH IN TURN POINTS
                   3468: #           TO AN FCBLK USED FOR I/O ASSOCIATION.
                   3469: #           TRFPT IS THE FCBLK PTR RETURNED BY SYSIO.
                   3470: #
                   3471: #      VARIABLE ACCESS TRACE ASSOCIATION
                   3472: #
                   3473: #           THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK
                   3474: #           INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE
                   3475: #           OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS
                   3476: #           CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK.
                   3477: #
                   3478: #           TRTYP IS SET TO TRTAC
                   3479: #           TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL
                   3480: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3481: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3482: #
                   3483: #      VARIABLE VALUE TRACE ASSOCIATION
                   3484: #
                   3485: #           THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK
                   3486: #           INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE
                   3487: #           OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS
                   3488: #           CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK.
                   3489: #
                   3490: #           TRTYP IS SET TO TRTVL
                   3491: #           TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL
                   3492: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3493: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3494:        #page   
                   3495: #      TRAP BLOCK (CONTINUED)
                   3496: #
                   3497: #      VARIABLE OUTPUT ASSOCIATION
                   3498: #
                   3499: #           THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK
                   3500: #           INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE
                   3501: #           OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS
                   3502: #           CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK.
                   3503: #
                   3504: #           TRTYP IS SET TO TRTOU
                   3505: #           TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL
                   3506: #           TRTER IS A POINTER TO SVBLK IF ASSOCIATION IS
                   3507: #           FOR OUTPUT, TERMINAL, ELSE IT IS NULL.
                   3508: #           TRTRF POINTS TO THE TRAP BLOCK WHICH IN TURN POINTS
                   3509: #           TO AN FCBLK USED FOR I/O ASSOCIATION.
                   3510: #           TRFPT IS THE FCBLK PTR RETURNED BY SYSIO.
                   3511: #
                   3512: #      FUNCTION CALL TRACE
                   3513: #
                   3514: #           THE PFCTR FIELD OF THE CORRESPONDING PFBLK IS SET
                   3515: #           TO POINT TO A TRBLK.
                   3516: #
                   3517: #           TRTYP IS SET TO TRTIN
                   3518: #           TRNXT IS ZERO
                   3519: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3520: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3521: #
                   3522: #      FUNCTION RETURN TRACE
                   3523: #
                   3524: #           THE PFRTR FIELD OF THE CORRESPONDING PFBLK IS SET
                   3525: #           TO POINT TO A TRBLK
                   3526: #
                   3527: #           TRTYP IS SET TO TRTIN
                   3528: #           TRNXT IS ZERO
                   3529: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3530: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3531: #
                   3532: #      LABEL TRACE
                   3533: #
                   3534: #           THE VRLBL OF THE VRBLK FOR THE LABEL IS
                   3535: #           CHANGED TO POINT TO A TRBLK AND THE VRTRA FIELD IS
                   3536: #           SET TO B$VRT TO ACTIVATE THE CHECK.
                   3537: #
                   3538: #           TRTYP IS SET TO TRTIN
                   3539: #           TRLBL POINTS TO THE ACTUAL LABEL (CDBLK) VALUE
                   3540: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3541: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3542:        #page   
                   3543: #
                   3544: #      TRAP BLOCK (CONTINUED)
                   3545: #
                   3546: #      KEYWORD TRACE
                   3547: #
                   3548: #           KEYWORDS WHICH CAN BE TRACED POSSESS A UNIQUE
                   3549: #           LOCATION WHICH IS ZERO IF THERE IS NO TRACE AND
                   3550: #           POINTS TO A TRBLK IF THERE IS A TRACE. THE LOCATIONS
                   3551: #           ARE AS FOLLOWS.
                   3552: #
                   3553: #           R$ERT            ERRTYPE
                   3554: #           R$FNC            FNCLEVEL
                   3555: #           R$STC            STCOUNT
                   3556: #
                   3557: #           THE FORMAT OF THE TRBLK IS AS FOLLOWS.
                   3558: #
                   3559: #           TRTYP IS SET TO TRTIN
                   3560: #           TRKVR IS A POINTER TO THE VRBLK FOR THE KEYWORD
                   3561: #           TRTAG IS THE TRACE TAG (0 IF NONE)
                   3562: #           TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE)
                   3563: #
                   3564: #      INPUT/OUTPUT FILE ARG1 TRAP BLOCK
                   3565: #
                   3566: #           THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK
                   3567: #           INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE OF
                   3568: #           A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS
                   3569: #           CONTAIN =B$VRA AND =B$VRV. THIS TRAP BLOCK IS USED
                   3570: #           TO HOLD A POINTER TO THE FCBLK WHICH AN
                   3571: #           IMPLEMENTATION MAY REQUEST TO HOLD INFORMATION
                   3572: #           ABOUT A FILE.
                   3573: #
                   3574: #           TRTYP IS SET TO TRTFC
                   3575: #           TRNEXT POINTS TO NEXT TRBLK OR TRVAL IS VARIABLE VAL
                   3576: #           TRFNM IS 0
                   3577: #           TRFPT IS THE FCBLK POINTER.
                   3578: #
                   3579: #      NOTE THAT WHEN MULTIPLE TRAPS ARE SET ON A VARIABLE
                   3580: #      THE ORDER IS IN ASCENDING VALUE OF TRTYP FIELD.
                   3581: #
                   3582: #      INPUT ASSOCIATION (IF PRESENT)
                   3583: #      ACCESS TRACE (IF PRESENT)
                   3584: #      VALUE TRACE (IF PRESENT)
                   3585: #      OUTPUT ASSOCIATION (IF PRESENT)
                   3586: #
                   3587: #      THE ACTUAL VALUE OF THE VARIABLE IS STORED IN THE TRVAL
                   3588: #      FIELD OF THE LAST TRBLK ON THE CHAIN.
                   3589: #
                   3590: #      THIS IMPLEMENTATION DOES NOT PERMIT TRACE OR I/O
                   3591: #      ASSOCIATIONS TO ANY OF THE PSEUDO-VARIABLES.
                   3592:        #page   
                   3593: #
                   3594: #      VECTOR BLOCK (VCBLK)
                   3595: #
                   3596: #      A VCBLK IS USED TO REPRESENT AN ARRAY VALUE WHICH HAS
                   3597: #      ONE DIMENSION WHOSE LOWER BOUND IS ONE. ALL OTHER ARRAYS
                   3598: #      ARE REPRESENTED BY ARBLKS. A VCBLK IS CREATED BY THE
                   3599: #      SYSTEM FUNCTION ARRAY (S$ARR) WHEN PASSED AN INTEGER ARG.
                   3600: #
                   3601: #           +------------------------------------+
                   3602: #           I                VCTYP               I
                   3603: #           +------------------------------------+
                   3604: #           I                IDVAL               I
                   3605: #           +------------------------------------+
                   3606: #           I                VCLEN               I
                   3607: #           +------------------------------------+
                   3608: #           I                VCVLS               I
                   3609: #           +------------------------------------+
                   3610: #
                   3611:        .set    vctyp,0         # pointer to dummy routine b$vct
                   3612:        .set    vclen,offs2     # length of vcblk in bytes
                   3613:        .set    vcvls,offs3     # start of vector values
                   3614:        .set    vcsi$,vcvls     # size of standard fields in vcblk
                   3615:        .set    vcvlb,vcvls-1   # offset one word behind vcvls
                   3616:        .set    vctbd,tbsi$-vcsi$# difference in sizes - see prtvl
                   3617: #
                   3618: #      VCVLS ARE EITHER DATA POINTERS OR TRBLK POINTERS
                   3619: #
                   3620: #      THE DIMENSION CAN BE DEDUCED FROM VCLEN.
                   3621:        #page   
                   3622: #
                   3623: #      VARIABLE BLOCK (VRBLK)
                   3624: #
                   3625: #      A VARIABLE BLOCK IS BUILT IN THE STATIC MEMORY AREA
                   3626: #      FOR EVERY VARIABLE REFERENCED OR CREATED BY A PROGRAM.
                   3627: #
                   3628: #      NOTE THAT SINCE THESE BLOCKS ONLY OCCUR IN THE STATIC
                   3629: #      REGION, IT IS PERMISSIBLE TO POINT TO ANY WORD IN
                   3630: #      THE BLOCK AND THIS IS USED TO PROVIDE THREE DISTINCT
                   3631: #      ACCESS POINTS FROM THE GENERATED CODE AS FOLLOWS.
                   3632: #
                   3633: #      1)   POINT TO VRGET (FIRST WORD OF VRBLK) TO LOAD THE
                   3634: #           VALUE OF THE VARIABLE ONTO THE MAIN STACK.
                   3635: #
                   3636: #      2)   POINT TO VRSTO (SECOND WORD OF VRBLK) TO STORE THE
                   3637: #           TOP STACK ELEMENT AS THE VALUE OF THE VARIABLE.
                   3638: #
                   3639: #      3)   POINT TO VRTRA (FOURTH WORD OF VRBLK) TO JUMP TO
                   3640: #           THE LABEL ASSOCIATED WITH THE VARIABLE NAME.
                   3641: #
                   3642: #           +------------------------------------+
                   3643: #           I                VRGET               I
                   3644: #           +------------------------------------+
                   3645: #           I                VRSTO               I
                   3646: #           +------------------------------------+
                   3647: #           I                VRVAL               I
                   3648: #           +------------------------------------+
                   3649: #           I                VRTRA               I
                   3650: #           +------------------------------------+
                   3651: #           I                VRLBL               I
                   3652: #           +------------------------------------+
                   3653: #           I                VRFNC               I
                   3654: #           +------------------------------------+
                   3655: #           I                VRNXT               I
                   3656: #           +------------------------------------+
                   3657: #           I                VRLEN               I
                   3658: #           +------------------------------------+
                   3659: #           /                                    /
                   3660: #           /            VRCHS = VRSVP           /
                   3661: #           /                                    /
                   3662: #           +------------------------------------+
                   3663:        #page   
                   3664: #
                   3665: #      VARIABLE BLOCK (CONTINUED)
                   3666: #
                   3667:        .set    vrget,0         # pointer to routine to load value
                   3668:        .set    vrsto,vrget+1   # pointer to routine to store value
                   3669:        .set    vrval,vrsto+1   # variable value
                   3670:        .set    vrvlo,vrval-vrsto# offset to value from store field
                   3671:        .set    vrtra,vrval+1   # pointer to routine to jump to label
                   3672:        .set    vrlbl,vrtra+1   # pointer to code for label
                   3673:        .set    vrlbo,vrlbl-vrtra# offset to label from transfer field
                   3674:        .set    vrfnc,vrlbl+1   # pointer to function block
                   3675:        .set    vrnxt,vrfnc+1   # pointer to next vrblk on hash chain
                   3676:        .set    vrlen,vrnxt+1   # length of name (or zero)
                   3677:        .set    vrchs,vrlen+1   # characters of name (vrlen gt 0)
                   3678:        .set    vrsvp,vrlen+1   # ptr to svblk (vrlen eq 0)
                   3679:        .set    vrsi$,vrchs+1   # number of standard fields in vrblk
                   3680:        .set    vrsof,vrlen-sclen# offset to dummy scblk for name
                   3681:        .set    vrsvo,vrsvp-vrsof# pseudo-offset to vrsvp field
                   3682: #
                   3683: #      VRGET = B$VRL IF NOT INPUT ASSOCIATED OR ACCESS TRACED
                   3684: #      VRGET = B$VRA IF INPUT ASSOCIATED OR ACCESS TRACED
                   3685: #
                   3686: #      VRSTO = B$VRS IF NOT OUTPUT ASSOCIATED OR VALUE TRACED
                   3687: #      VRSTO = B$VRV IF OUTPUT ASSOCIATED OR VALUE TRACED
                   3688: #      VRSTO = B$VRE IF VALUE IS PROTECTED PATTERN VALUE
                   3689: #
                   3690: #      VRVAL POINTS TO THE APPROPRIATE VALUE UNLESS THE
                   3691: #      VARIABLE IS I/O/TRACE ASSOCIATED IN WHICH CASE, VRVAL
                   3692: #      POINTS TO AN APPROPRIATE TRBLK (TRAP BLOCK) CHAIN.
                   3693: #
                   3694: #      VRTRA = B$VRG IF THE LABEL IS NOT TRACED
                   3695: #      VRTRA = B$VRT IF THE LABEL IS TRACED
                   3696: #
                   3697: #      VRLBL POINTS TO A CDBLK IF THERE IS A LABEL
                   3698: #      VRLBL POINTS TO THE SVBLK SVLBL FIELD FOR A SYSTEM LABEL
                   3699: #      VRLBL POINTS TO STNDL FOR AN UNDEFINED LABEL
                   3700: #      VRLBL POINTS TO A TRBLK IF THE LABEL IS TRACED
                   3701: #
                   3702: #      VRFNC POINTS TO A FFBLK FOR A FIELD FUNCTION
                   3703: #      VRFNC POINTS TO A DFBLK FOR A DATATYPE FUNCTION
                   3704: #      VRFNC POINTS TO A PFBLK FOR A PROGRAM DEFINED FUNCTION
                   3705: #      VRFNC POINTS TO A EFBLK FOR AN EXTERNAL LOADED FUNCTION
                   3706: #      VRFNC POINTS TO SVFNC (SVBLK) FOR A SYSTEM FUNCTION
                   3707: #      VRFNC POINTS TO STNDF IF THE FUNCTION IS UNDEFINED
                   3708: #
                   3709: #      VRNXT POINTS TO THE NEXT VRBLK ON THIS CHAIN UNLESS
                   3710: #      THIS IS THE END OF THE CHAIN IN WHICH CASE IT IS ZERO.
                   3711: #
                   3712: #      VRLEN IS THE NAME LENGTH FOR A NON-SYSTEM VARIABLE.
                   3713: #      VRLEN IS ZERO FOR A SYSTEM VARIABLE.
                   3714: #
                   3715: #      VRCHS IS THE NAME (LJRZ) IF VRLEN IS NON-ZERO.
                   3716: #      VRSVP IS A PTR TO THE SVBLK IF VRLEN IS ZERO.
                   3717:        #page   
                   3718: #
                   3719: #      FORMAT OF A NON-RELOCATABLE EXTERNAL BLOCK (XNBLK)
                   3720: #
                   3721: #      AN XNBLK IS A BLOCK REPRESENTING AN UNKNOWN (EXTERNAL)
                   3722: #      DATA VALUE. THE BLOCK CONTAINS NO POINTERS TO OTHER
                   3723: #      RELOCATABLE BLOCKS. AN XNBLK IS USED BY EXTERNAL FUNCTION
                   3724: #      PROCESSING OR POSSIBLY FOR SYSTEM I/O ROUTINES ETC.
                   3725: #      THE MACRO-SYSTEM ITSELF DOES NOT USE XNBLKS.
                   3726: #      THIS TYPE OF BLOCK MAY BE USED AS A FILE CONTROL BLOCK.
                   3727: #      SEE SYSFC,SYSIN,SYSOU,S$INP,S$OUP FOR DETAILS.
                   3728: #
                   3729: #           +------------------------------------+
                   3730: #           I                XNTYP               I
                   3731: #           +------------------------------------+
                   3732: #           I                XNLEN               I
                   3733: #           +------------------------------------+
                   3734: #           /                                    /
                   3735: #           /                XNDTA               /
                   3736: #           /                                    /
                   3737: #           +------------------------------------+
                   3738: #
                   3739:        .set    xntyp,0         # pointer to dummy routine b$xnt
                   3740:        .set    xnlen,xntyp+1   # length of xnblk in bytes
                   3741:        .set    xndta,xnlen+1   # data words
                   3742:        .set    xnsi$,xndta     # size of standard fields in xnblk
                   3743: #
                   3744: #      NOTE THAT THE TERM NON-RELOCATABLE REFERS TO THE CONTENTS
                   3745: #      AND NOT THE BLOCK ITSELF. AN XNBLK CAN BE MOVED AROUND IF
                   3746: #      IT IS BUILT IN THE DYNAMIC MEMORY AREA.
                   3747:        #page   
                   3748: #
                   3749: #      RELOCATABLE EXTERNAL BLOCK (XRBLK)
                   3750: #
                   3751: #      AN XRBLK IS A BLOCK REPRESENTING AN UNKNOWN (EXTERNAL)
                   3752: #      DATA VALUE. THE DATA AREA IN THIS BLOCK CONSISTS ONLY
                   3753: #      OF ADDRESS VALUES AND ANY ADDRESSES POINTING INTO THE
                   3754: #      DYNAMIC MEMORY AREA MUST POINT TO THE START OF OTHER
                   3755: #      DATA BLOCKS. SEE ALSO DESCRIPTION OF XNBLK.
                   3756: #      THIS TYPE OF BLOCK MAY BE USED AS A FILE CONTROL BLOCK.
                   3757: #      SEE SYSFC,SYSIN,SYSOU,S$INP,S$OUP FOR DETAILS.
                   3758: #
                   3759: #           +------------------------------------+
                   3760: #           I                XRTYP               I
                   3761: #           +------------------------------------+
                   3762: #           I                XRLEN               I
                   3763: #           +------------------------------------+
                   3764: #           /                                    /
                   3765: #           /                XRPTR               /
                   3766: #           /                                    /
                   3767: #           +------------------------------------+
                   3768: #
                   3769:        .set    xrtyp,0         # pointer to dummy routine b$xrt
                   3770:        .set    xrlen,xrtyp+1   # length of xrblk in bytes
                   3771:        .set    xrptr,xrlen+1   # start of address pointers
                   3772:        .set    xrsi$,xrptr     # size of standard fields in xrblk
                   3773:        #page   
                   3774: #
                   3775: #      S$CNV (CONVERT) FUNCTION SWITCH CONSTANTS.  THE VALUES
                   3776: #      ARE TIED TO THE ORDER OF THE ENTRIES IN THE SVCTB TABLE
                   3777: #      AND HENCE TO THE BRANCH TABLE IN S$CNV.
                   3778: #
                   3779:        .set    cnvst,8         # max standard type code for convert
                   3780:        .set    cnvrt,cnvst+1   # convert code for reals
                   3781:        .set    cnvbt,cnvrt+1   # convert code for buffer
                   3782:        .set    cnvtt,cnvbt+1   # bsw code for convert
                   3783: #
                   3784: #      INPUT IMAGE LENGTH
                   3785: #
                   3786:        .set    iniln,132       # default image length for compiler
                   3787:        .set    inils,80        # image length if -sequ in effect
                   3788: #
                   3789:        .set    ionmb,2         # name base used for iochn in sysio
                   3790:        .set    ionmo,4         # name offset used for iochn in sysio
                   3791: #
                   3792: #      IN GENERAL, MEANINGFUL MNEMONICS SHOULD BE USED FOR
                   3793: #      OFFSETS. HOWEVER FOR SMALL INTEGERS USED OFTEN IN
                   3794: #      LITERALS THE FOLLOWING GENERAL DEFINITIONS ARE PROVIDED.
                   3795: #
                   3796:        .set    num01,1
                   3797:        .set    num02,2
                   3798:        .set    num03,3
                   3799:        .set    num04,4
                   3800:        .set    num05,5
                   3801:        .set    num06,6
                   3802:        .set    num07,7
                   3803:        .set    num08,8
                   3804:        .set    num09,9
                   3805:        .set    num10,10
                   3806:        .set    nini8,998
                   3807:        .set    nini9,999
                   3808:        .set    thsnd,1000
                   3809:        #page   
                   3810: #
                   3811: #      NUMBERS OF UNDEFINED SPITBOL OPERATORS
                   3812: #
                   3813:        .set    opbun,5         # no. of binary undefined ops
                   3814:        .set    opuun,6         # no of unary undefined ops
                   3815: #
                   3816: #      OFFSETS USED IN PRTSN, PRTMI AND ACESS
                   3817: #
                   3818:        .set    prsnf,13        # offset used in prtsn
                   3819:        .set    prtmf,15        # offset to col 15 (prtmi)
                   3820:        .set    rilen,120       # buffer length for sysri
                   3821: #
                   3822: #      CODES FOR STAGES OF PROCESSING
                   3823: #
                   3824:        .set    stgic,0         # initial compile
                   3825:        .set    stgxc,stgic+1   # execution compile (code)
                   3826:        .set    stgev,stgxc+1   # expression eval during execution
                   3827:        .set    stgxt,stgev+1   # execution time
                   3828:        .set    stgce,stgxt+1   # initial compile after end line
                   3829:        .set    stgxe,stgce+1   # exec. compile after end line
                   3830:        .set    stgnd,stgce-stgic# difference in stage after end
                   3831:        .set    stgee,stgxe+1   # eval evaluating expression
                   3832:        .set    stgno,stgee+1   # number of codes
                   3833:        #page   
                   3834: #
                   3835: #
                   3836: #      STATEMENT NUMBER PAD COUNT FOR LISTR
                   3837: #
                   3838:        .set    stnpd,8         # statement no. pad count
                   3839: #
                   3840: #      SYNTAX TYPE CODES
                   3841: #
                   3842: #      THESE CODES ARE RETURNED FROM THE SCANE PROCEDURE.
                   3843: #
                   3844: #      THEY ARE SPACED 3 APART FOR THE BENEFIT OF EXPAN.
                   3845: #
                   3846:        .set    t$uop,0         # unary operator
                   3847:        .set    t$lpr,t$uop+3   # left paren
                   3848:        .set    t$lbr,t$lpr+3   # left bracket
                   3849:        .set    t$cma,t$lbr+3   # comma
                   3850:        .set    t$fnc,t$cma+3   # function call
                   3851:        .set    t$var,t$fnc+3   # variable
                   3852:        .set    t$con,t$var+3   # constant
                   3853:        .set    t$bop,t$con+3   # binary operator
                   3854:        .set    t$rpr,t$bop+3   # right paren
                   3855:        .set    t$rbr,t$rpr+3   # right bracket
                   3856:        .set    t$col,t$rbr+3   # colon
                   3857:        .set    t$smc,t$col+3   # semi-colon
                   3858: #
                   3859: #      THE FOLLOWING DEFINITIONS ARE USED ONLY IN THE GOTO FIELD
                   3860: #
                   3861:        .set    t$fgo,t$smc+1   # failure goto
                   3862:        .set    t$sgo,t$fgo+1   # success goto
                   3863: #
                   3864: #      THE ABOVE CODES ARE GROUPED SO THAT CODES FOR ELEMENTS
                   3865: #      WHICH CAN LEGITIMATELY IMMEDIATELY PRECEDE A UNARY
                   3866: #      OPERATOR COME FIRST TO FACILITATE OPERATOR SYNTAX CHECK.
                   3867: #
                   3868:        .set    t$uok,t$fnc     # last code ok before unary operator
                   3869:        #page   
                   3870: #
                   3871: #      DEFINITIONS OF VALUES FOR EXPAN JUMP TABLE
                   3872: #
                   3873:        .set    t$uo0,t$uop+0   # unary operator, state zero
                   3874:        .set    t$uo1,t$uop+1   # unary operator, state one
                   3875:        .set    t$uo2,t$uop+2   # unary operator, state two
                   3876:        .set    t$lp0,t$lpr+0   # left paren, state zero
                   3877:        .set    t$lp1,t$lpr+1   # left paren, state one
                   3878:        .set    t$lp2,t$lpr+2   # left paren, state two
                   3879:        .set    t$lb0,t$lbr+0   # left bracket, state zero
                   3880:        .set    t$lb1,t$lbr+1   # left bracket, state one
                   3881:        .set    t$lb2,t$lbr+2   # left bracket, state two
                   3882:        .set    t$cm0,t$cma+0   # comma, state zero
                   3883:        .set    t$cm1,t$cma+1   # comma, state one
                   3884:        .set    t$cm2,t$cma+2   # comma, state two
                   3885:        .set    t$fn0,t$fnc+0   # function call, state zero
                   3886:        .set    t$fn1,t$fnc+1   # function call, state one
                   3887:        .set    t$fn2,t$fnc+2   # function call, state two
                   3888:        .set    t$va0,t$var+0   # variable, state zero
                   3889:        .set    t$va1,t$var+1   # variable, state one
                   3890:        .set    t$va2,t$var+2   # variable, state two
                   3891:        .set    t$co0,t$con+0   # constant, state zero
                   3892:        .set    t$co1,t$con+1   # constant, state one
                   3893:        .set    t$co2,t$con+2   # constant, state two
                   3894:        .set    t$bo0,t$bop+0   # binary operator, state zero
                   3895:        .set    t$bo1,t$bop+1   # binary operator, state one
                   3896:        .set    t$bo2,t$bop+2   # binary operator, state two
                   3897:        .set    t$rp0,t$rpr+0   # right paren, state zero
                   3898:        .set    t$rp1,t$rpr+1   # right paren, state one
                   3899:        .set    t$rp2,t$rpr+2   # right paren, state two
                   3900:        .set    t$rb0,t$rbr+0   # right bracket, state zero
                   3901:        .set    t$rb1,t$rbr+1   # right bracket, state one
                   3902:        .set    t$rb2,t$rbr+2   # right bracket, state two
                   3903:        .set    t$cl0,t$col+0   # colon, state zero
                   3904:        .set    t$cl1,t$col+1   # colon, state one
                   3905:        .set    t$cl2,t$col+2   # colon, state two
                   3906:        .set    t$sm0,t$smc+0   # semicolon, state zero
                   3907:        .set    t$sm1,t$smc+1   # semicolon, state one
                   3908:        .set    t$sm2,t$smc+2   # semicolon, state two
                   3909: #
                   3910:        .set    t$nes,t$sm2+1   # number of entries in branch table
                   3911:        #page   
                   3912: #
                   3913: #       DEFINITION OF OFFSETS USED IN CONTROL CARD PROCESSING
                   3914: #
                   3915:        .set    cc$ca,0         # -case
                   3916:        .set    cc$do,cc$ca+1   # -double
                   3917:        .set    cc$du,cc$do+1   # -dump
                   3918:        .set    cc$ej,cc$du+1   # -eject
                   3919:        .set    cc$er,cc$ej+1   # -errors
                   3920:        .set    cc$ex,cc$er+1   # -execute
                   3921:        .set    cc$fa,cc$ex+1   # -fail
                   3922:        .set    cc$li,cc$fa+1   # -list
                   3923:        .set    cc$nr,cc$li+1   # -noerrors
                   3924:        .set    cc$nx,cc$nr+1   # -noexecute
                   3925:        .set    cc$nf,cc$nx+1   # -nofail
                   3926:        .set    cc$nl,cc$nf+1   # -nolist
                   3927:        .set    cc$no,cc$nl+1   # -noopt
                   3928:        .set    cc$np,cc$no+1   # -noprint
                   3929:        .set    cc$op,cc$np+1   # -optimise
                   3930:        .set    cc$pr,cc$op+1   # -print
                   3931:        .set    cc$si,cc$pr+1   # -single
                   3932:        .set    cc$sp,cc$si+1   # -space
                   3933:        .set    cc$st,cc$sp+1   # -stitl
                   3934:        .set    cc$ti,cc$st+1   # -title
                   3935:        .set    cc$tr,cc$ti+1   # -trace
                   3936:        .set    cc$nc,cc$tr+1   # number of control cards
                   3937:        .set    ccnoc,4         # no. of chars included in match
                   3938:        .set    ccofs,7         # offset to start of title/subtitle
                   3939:        #page   
                   3940: #
                   3941: #      DEFINITIONS OF STACK OFFSETS USED IN CMPIL PROCEDURE
                   3942: #
                   3943: #      SEE DESCRIPTION AT START OF CMPIL PROCEDURE FOR DETAILS
                   3944: #      OF USE OF THESE LOCATIONS ON THE STACK.
                   3945: #
                   3946:        .set    cmstm,0         # tree for statement body
                   3947:        .set    cmsgo,cmstm+1   # tree for success goto
                   3948:        .set    cmfgo,cmsgo+1   # tree for fail goto
                   3949:        .set    cmcgo,cmfgo+1   # conditional goto flag
                   3950:        .set    cmpcd,cmcgo+1   # previous cdblk pointer
                   3951:        .set    cmffp,cmpcd+1   # failure fill in flag for previous
                   3952:        .set    cmffc,cmffp+1   # failure fill in flag for current
                   3953:        .set    cmsop,cmffc+1   # success fill in offset for previous
                   3954:        .set    cmsoc,cmsop+1   # success fill in offset for current
                   3955:        .set    cmlbl,cmsoc+1   # ptr to vrblk for current label
                   3956:        .set    cmtra,cmlbl+1   # ptr to entry cdblk
                   3957: #
                   3958:        .set    cmnen,cmtra+1   # count of stack entries for cmpil
                   3959: #
                   3960: #      A FEW CONSTANTS USED BY THE PROFILER
                   3961:        .set    pfpd1,8         # pad positions ...
                   3962:        .set    pfpd2,20        # ... for profile ...
                   3963:        .set    pfpd3,32        # ... printout
                   3964:        .set    pf$i2,cfp$i+cfp$i# size of table entry (2 ints)
                   3965: #
                   3966:        #title  s p i t b o l -- constant section
                   3967: #
                   3968: #      THIS SECTION CONSISTS ENTIRELY OF ASSEMBLED CONSTANTS.
                   3969: #
                   3970: #      ALL LABEL NAMES ARE FIVE LETTERS. THE ORDER IS
                   3971: #      APPROXIMATELY ALPHABETICAL, BUT IN SOME CASES (ALWAYS
                   3972: #      DOCUMENTED), CONSTANTS MUST BE PLACED IN SOME SPECIAL
                   3973: #      ORDER WHICH MUST NOT BE DISTURBED.
                   3974: #
                   3975: #      IT MUST ALSO BE REMEMBERED THAT THERE IS A REQUIREMENT
                   3976: #      FOR NO FORWARD REFERENCES WHICH ALSO DISTURBS THE
                   3977: #      ALPHABETICAL ORDER IN SOME CASES.
                   3978: #
                   3979:        .data   0
                   3980:        #sec                    # start of constant section
                   3981: #
                   3982: #      FREE STORE PERCENTAGE (USED BY ALLOC)
                   3983: #
                   3984: alfsp: .long   e$fsp           # free store percentage
                   3985: #
                   3986: #      BIT CONSTANTS FOR GENERAL USE
                   3987: #
                   3988: bits0: .long   0               # all zero bits
                   3989: bits1: .long   1               # one bit in low order position
                   3990: bits2: .long   2               # bit in position 2
                   3991: bits3: .long   4               # bit in position 3
                   3992: bits4: .long   8               # bit in position 4
                   3993: bits5: .long   16              # bit in position 5
                   3994: bits6: .long   32              # bit in position 6
                   3995: bits7: .long   64              # bit in position 7
                   3996: bits8: .long   128             # bit in position 8
                   3997: bits9: .long   256             # bit in position 9
                   3998: bit10: .long   512             # bit in position 10
                   3999: bitsm: .long   cfp$m           # mask for max integer
                   4000: #
                   4001: #      BIT CONSTANTS FOR SVBLK (SVBIT FIELD) TESTS
                   4002: #
                   4003: btfnc: .long   svfnc           # bit to test for function
                   4004: btknm: .long   svknm           # bit to test for keyword number
                   4005: btlbl: .long   svlbl           # bit to test for label
                   4006: btffc: .long   svffc           # bit to test for fast call
                   4007: btckw: .long   svckw           # bit to test for constant keyword
                   4008: btprd: .long   svprd           # bit to test for predicate function
                   4009: btpre: .long   svpre           # bit to test for preevaluation
                   4010: btval: .long   svval           # bit to test for value
                   4011:        #page   
                   4012: #
                   4013: #      LIST OF NAMES USED FOR CONTROL CARD PROCESSING
                   4014: #
                   4015: ccnms: .ascii  "CASE"
                   4016:        .align  2
                   4017:        .ascii  "DOUB"
                   4018:        .align  2
                   4019:        .ascii  "DUMP"
                   4020:        .align  2
                   4021:        .ascii  "EJEC"
                   4022:        .align  2
                   4023:        .ascii  "ERRO"
                   4024:        .align  2
                   4025:        .ascii  "EXEC"
                   4026:        .align  2
                   4027:        .ascii  "FAIL"
                   4028:        .align  2
                   4029:        .ascii  "LIST"
                   4030:        .align  2
                   4031:        .ascii  "NOER"
                   4032:        .align  2
                   4033:        .ascii  "NOEX"
                   4034:        .align  2
                   4035:        .ascii  "NOFA"
                   4036:        .align  2
                   4037:        .ascii  "NOLI"
                   4038:        .align  2
                   4039:        .ascii  "NOOP"
                   4040:        .align  2
                   4041:        .ascii  "NOPR"
                   4042:        .align  2
                   4043:        .ascii  "OPTI"
                   4044:        .align  2
                   4045:        .ascii  "PRIN"
                   4046:        .align  2
                   4047:        .ascii  "SING"
                   4048:        .align  2
                   4049:        .ascii  "SPAC"
                   4050:        .align  2
                   4051:        .ascii  "STIT"
                   4052:        .align  2
                   4053:        .ascii  "TITL"
                   4054:        .align  2
                   4055:        .ascii  "TRAC"
                   4056:        .align  2
                   4057: #
                   4058: #      HEADER MESSAGES FOR DUMPR PROCEDURE (SCBLK FORMAT)
                   4059: #
                   4060: dmhdk: .long   b$scl           # dump of keyword values
                   4061:        .long   22
                   4062:        .ascii  "DUMP OF KEYWORD VALUES"
                   4063:        .align  2
                   4064: #
                   4065: dmhdv: .long   b$scl           # dump of natural variables
                   4066:        .long   25
                   4067:        .ascii  "DUMP OF NATURAL VARIABLES"
                   4068:        .align  2
                   4069:        #page   
                   4070: #
                   4071: #      MESSAGE TEXT FOR COMPILATION STATISTICS
                   4072: #
                   4073: encm1: .long   b$scl
                   4074:        .long   10
                   4075:        .ascii  "STORE USED"
                   4076:        .align  2
                   4077: #
                   4078: encm2: .long   b$scl
                   4079:        .long   10
                   4080:        .ascii  "STORE LEFT"
                   4081:        .align  2
                   4082: #
                   4083: encm3: .long   b$scl
                   4084:        .long   11
                   4085:        .ascii  "COMP ERRORS"
                   4086:        .align  2
                   4087: #
                   4088: encm4: .long   b$scl
                   4089:        .long   14
                   4090:        .ascii  "COMP TIME-MSEC"
                   4091:        .align  2
                   4092: #
                   4093: encm5: .long   b$scl           # execution suppressed
                   4094:        .long   20
                   4095:        .ascii  "EXECUTION SUPPRESSED"
                   4096:        .align  2
                   4097: #
                   4098: #      STRING CONSTANT FOR ABNORMAL END
                   4099: #
                   4100: endab: .long   b$scl
                   4101:        .long   12
                   4102:        .ascii  "ABNORMAL END"
                   4103:        .align  2
                   4104:        #page   
                   4105: #
                   4106: #      MEMORY OVERFLOW DURING INITIALISATION
                   4107: #
                   4108: endmo: .long   b$scl
                   4109: endml: .long   15
                   4110:        .ascii  "MEMORY OVERFLOW"
                   4111:        .align  2
                   4112: #
                   4113: #      STRING CONSTANT FOR MESSAGE ISSUED BY L$END
                   4114: #
                   4115: endms: .long   b$scl
                   4116:        .long   10
                   4117:        .ascii  "NORMAL END"
                   4118:        .align  2
                   4119: #
                   4120: #      FAIL MESSAGE FOR STACK FAIL SECTION
                   4121: #
                   4122: endso: .long   b$scl           # stack overflow in garbage collector
                   4123:        .long   36
                   4124:        .ascii  "STACK OVERFLOW IN GARBAGE COLLECTION"
                   4125:        .align  2
                   4126: #
                   4127: #      STRING CONSTANT FOR TIME UP
                   4128: #
                   4129: endtu: .long   b$scl
                   4130:        .long   15
                   4131:        .ascii  "ERROR - TIME UP"
                   4132:        .align  2
                   4133:        #page   
                   4134: #
                   4135: #      STRING CONSTANT FOR ERROR MESSAGE (ERROR SECTION)
                   4136: #
                   4137: ermms: .long   b$scl           # error
                   4138:        .long   5
                   4139:        .ascii  "ERROR"
                   4140:        .align  2
                   4141: #
                   4142: ermns: .long   b$scl           # string / -- /
                   4143:        .long   4
                   4144:        .ascii  " -- "
                   4145:        .align  2
                   4146: #
                   4147: #      STRING CONSTANT FOR PAGE NUMBERING
                   4148: #
                   4149: lstms: .long   b$scl           # page
                   4150:        .long   5
                   4151:        .ascii  "PAGE "
                   4152:        .align  2
                   4153: #
                   4154: #      LISTING HEADER MESSAGE
                   4155: #
                   4156: headr: .long   b$scl
                   4157:        .long   25
                   4158:        .ascii  "MACRO SPITBOL VERSION 3.5"
                   4159:        .align  2
                   4160: #
                   4161: headv: .long   b$scl           # for exit() version no. check
                   4162:        .long   3
                   4163:        .ascii  "3.5"
                   4164:        .align  2
                   4165: #
                   4166: #      INTEGER CONSTANTS FOR GENERAL USE
                   4167: #      ICBLD OPTIMISATION USES THE FIRST THREE.
                   4168: #
                   4169: int$r: .long   b$icl
                   4170: intv0: .long   0               # 0
                   4171: inton: .long   b$icl
                   4172: intv1: .long   1               # 1
                   4173: inttw: .long   b$icl
                   4174: intv2: .long   2               # 2
                   4175: intvt: .long   10              # 10
                   4176: intvh: .long   100             # 100
                   4177: intth: .long   1000            # 1000
                   4178: #
                   4179: #      TABLE USED IN ICBLD OPTIMISATION
                   4180: #
                   4181: intab: .long   int$r           # pointer to 0
                   4182:        .long   inton           # pointer to 1
                   4183:        .long   inttw           # pointer to 2
                   4184:        #page   
                   4185: #
                   4186: #      SPECIAL PATTERN NODES. THE FOLLOWING PATTERN NODES
                   4187: #      CONSIST SIMPLY OF A PCODE POINTER, SEE MATCH ROUTINES
                   4188: #      (P$XXX) FOR FULL DETAILS OF THEIR USE AND FORMAT).
                   4189: #
                   4190: ndabb: .long   p$abb           # arbno
                   4191: ndabd: .long   p$abd           # arbno
                   4192: ndarc: .long   p$arc           # arb
                   4193: ndexb: .long   p$exb           # expression
                   4194: ndfnb: .long   p$fnb           # fence()
                   4195: ndfnd: .long   p$fnd           # fence()
                   4196: ndexc: .long   p$exc           # expression
                   4197: ndimb: .long   p$imb           # immediate assignment
                   4198: ndimd: .long   p$imd           # immediate assignment
                   4199: ndnth: .long   p$nth           # pattern end (null pattern)
                   4200: ndpab: .long   p$pab           # pattern assignment
                   4201: ndpad: .long   p$pad           # pattern assignment
                   4202: nduna: .long   p$una           # anchor point movement
                   4203: #
                   4204: #      KEYWORD CONSTANT PATTERN NODES. THE FOLLOWING NODES ARE
                   4205: #      USED AS THE VALUES OF PATTERN KEYWORDS AND THE INITIAL
                   4206: #      VALUES OF THE CORRESPONDING NATURAL VARIABLES. ALL
                   4207: #      NODES ARE IN P0BLK FORMAT AND THE ORDER IS TIED TO THE
                   4208: #      DEFINITIONS OF CORRESPONDING K$XXX SYMBOLS.
                   4209: #
                   4210: ndabo: .long   p$abo           # abort
                   4211:        .long   ndnth
                   4212: ndarb: .long   p$arb           # arb
                   4213:        .long   ndnth
                   4214: ndbal: .long   p$bal           # bal
                   4215:        .long   ndnth
                   4216: ndfal: .long   p$fal           # fail
                   4217:        .long   ndnth
                   4218: ndfen: .long   p$fen           # fence
                   4219:        .long   ndnth
                   4220: ndrem: .long   p$rem           # rem
                   4221:        .long   ndnth
                   4222: ndsuc: .long   p$suc           # succeed
                   4223:        .long   ndnth
                   4224: #
                   4225: #      NULL STRING. ALL NULL VALUES POINT TO THIS STRING. THE
                   4226: #      SVCHS FIELD CONTAINS A BLANK TO PROVIDE FOR EASY DEFAULT
                   4227: #      PROCESSING IN TRACE, STOPTR, LPAD AND RPAD.
                   4228: #      NULLW CONTAINS 10 BLANKS WHICH ENSURES AN ALL BLANK WORD
                   4229: #      BUT FOR VERY EXCEPTIONAL MACHINES.
                   4230: #
                   4231: nulls: .long   b$scl           # null string value
                   4232:        .long   0               # sclen = 0
                   4233: nullw: .ascii  "          "
                   4234:        .align  2
                   4235:        #page   
                   4236: #
                   4237: #      OPERATOR DOPE VECTORS (SEE DVBLK FORMAT)
                   4238: #
                   4239: opdvc: .long   o$cnc           # concatenation
                   4240:        .long   c$cnc
                   4241:        .long   llcnc
                   4242:        .long   rrcnc
                   4243: #
                   4244: #      OPDVS IS USED WHEN SCANNING BELOW THE TOP LEVEL TO
                   4245: #      INSURE THAT THE CONCATENATION WILL NOT BE LATER
                   4246: #      MISTAKEN FOR PATTERN MATCHING
                   4247: #
                   4248: opdvp: .long   o$cnc           # concatenation - not pattern match
                   4249:        .long   c$cnp
                   4250:        .long   llcnc
                   4251:        .long   rrcnc
                   4252: #
                   4253: #      NOTE THAT THE ORDER OF THE REMAINING ENTRIES IS TIED TO
                   4254: #      THE ORDER OF THE CODING IN THE SCANE PROCEDURE.
                   4255: #
                   4256: opdvs: .long   o$ass           # assignment
                   4257:        .long   c$ass
                   4258:        .long   llass
                   4259:        .long   rrass
                   4260: #
                   4261:        .long   6               # unary equal
                   4262:        .long   c$uuo
                   4263:        .long   lluno
                   4264: #
                   4265:        .long   o$pmv           # pattern match
                   4266:        .long   c$pmt
                   4267:        .long   llpmt
                   4268:        .long   rrpmt
                   4269: #
                   4270:        .long   o$int           # interrogation
                   4271:        .long   c$uvl
                   4272:        .long   lluno
                   4273: #
                   4274:        .long   1               # binary ampersand
                   4275:        .long   c$ubo
                   4276:        .long   llamp
                   4277:        .long   rramp
                   4278: #
                   4279:        .long   o$kwv           # keyword reference
                   4280:        .long   c$key
                   4281:        .long   lluno
                   4282: #
                   4283:        .long   o$alt           # alternation
                   4284:        .long   c$alt
                   4285:        .long   llalt
                   4286:        .long   rralt
                   4287:        #page   
                   4288: #
                   4289: #      OPERATOR DOPE VECTORS (CONTINUED)
                   4290: #
                   4291:        .long   5               # unary vertical bar
                   4292:        .long   c$uuo
                   4293:        .long   lluno
                   4294: #
                   4295:        .long   0               # binary at
                   4296:        .long   c$ubo
                   4297:        .long   llats
                   4298:        .long   rrats
                   4299: #
                   4300:        .long   o$cas           # cursor assignment
                   4301:        .long   c$unm
                   4302:        .long   lluno
                   4303: #
                   4304:        .long   2               # binary number sign
                   4305:        .long   c$ubo
                   4306:        .long   llnum
                   4307:        .long   rrnum
                   4308: #
                   4309:        .long   7               # unary number sign
                   4310:        .long   c$uuo
                   4311:        .long   lluno
                   4312: #
                   4313:        .long   o$dvd           # division
                   4314:        .long   c$bvl
                   4315:        .long   lldvd
                   4316:        .long   rrdvd
                   4317: #
                   4318:        .long   9               # unary slash
                   4319:        .long   c$uuo
                   4320:        .long   lluno
                   4321: #
                   4322:        .long   o$mlt           # multiplication
                   4323:        .long   c$bvl
                   4324:        .long   llmlt
                   4325:        .long   rrmlt
                   4326:        #page   
                   4327: #
                   4328: #      OPERATOR DOPE VECTORS (CONTINUED)
                   4329: #
                   4330:        .long   0               # deferred expression
                   4331:        .long   c$def
                   4332:        .long   lluno
                   4333: #
                   4334:        .long   3               # binary percent
                   4335:        .long   c$ubo
                   4336:        .long   llpct
                   4337:        .long   rrpct
                   4338: #
                   4339:        .long   8               # unary percent
                   4340:        .long   c$uuo
                   4341:        .long   lluno
                   4342: #
                   4343:        .long   o$exp           # exponentiation
                   4344:        .long   c$bvl
                   4345:        .long   llexp
                   4346:        .long   rrexp
                   4347: #
                   4348:        .long   10              # unary exclamation
                   4349:        .long   c$uuo
                   4350:        .long   lluno
                   4351: #
                   4352:        .long   o$ima           # immediate assignment
                   4353:        .long   c$bvn
                   4354:        .long   lldld
                   4355:        .long   rrdld
                   4356: #
                   4357:        .long   o$inv           # indirection
                   4358:        .long   c$ind
                   4359:        .long   lluno
                   4360: #
                   4361:        .long   4               # binary not
                   4362:        .long   c$ubo
                   4363:        .long   llnot
                   4364:        .long   rrnot
                   4365: #
                   4366:        .long   0               # negation
                   4367:        .long   c$neg
                   4368:        .long   lluno
                   4369:        #page   
                   4370: #
                   4371: #      OPERATOR DOPE VECTORS (CONTINUED)
                   4372: #
                   4373:        .long   o$sub           # subtraction
                   4374:        .long   c$bvl
                   4375:        .long   llplm
                   4376:        .long   rrplm
                   4377: #
                   4378:        .long   o$com           # complementation
                   4379:        .long   c$uvl
                   4380:        .long   lluno
                   4381: #
                   4382:        .long   o$add           # addition
                   4383:        .long   c$bvl
                   4384:        .long   llplm
                   4385:        .long   rrplm
                   4386: #
                   4387:        .long   o$aff           # affirmation
                   4388:        .long   c$uvl
                   4389:        .long   lluno
                   4390: #
                   4391:        .long   o$pas           # pattern assignment
                   4392:        .long   c$bvn
                   4393:        .long   lldld
                   4394:        .long   rrdld
                   4395: #
                   4396:        .long   o$nam           # name reference
                   4397:        .long   c$unm
                   4398:        .long   lluno
                   4399: #
                   4400: #      SPECIAL DVS FOR GOTO OPERATORS (SEE PROCEDURE SCNGF)
                   4401: #
                   4402: opdvd: .long   o$god           # direct goto
                   4403:        .long   c$uvl
                   4404:        .long   lluno
                   4405: #
                   4406: opdvn: .long   o$goc           # complex normal goto
                   4407:        .long   c$unm
                   4408:        .long   lluno
                   4409:        #page   
                   4410: #
                   4411: #      OPERATOR ENTRY ADDRESS POINTERS, USED IN CODE
                   4412: #
                   4413: oamn$: .long   o$amn           # array ref (multi-subs by value)
                   4414: oamv$: .long   o$amv           # array ref (multi-subs by value)
                   4415: oaon$: .long   o$aon           # array ref (one sub by name)
                   4416: oaov$: .long   o$aov           # array ref (one sub by value)
                   4417: ocer$: .long   o$cer           # compilation error
                   4418: ofex$: .long   o$fex           # failure in expression evaluation
                   4419: ofif$: .long   o$fif           # failure during goto evaluation
                   4420: ofnc$: .long   o$fnc           # function call (more than one arg)
                   4421: ofne$: .long   o$fne           # function name error
                   4422: ofns$: .long   o$fns           # function call (single argument)
                   4423: ogof$: .long   o$gof           # set goto failure trap
                   4424: oinn$: .long   o$inn           # indirection by name
                   4425: okwn$: .long   o$kwn           # keyword reference by name
                   4426: olex$: .long   o$lex           # load expression by name
                   4427: olpt$: .long   o$lpt           # load pattern
                   4428: olvn$: .long   o$lvn           # load variable name
                   4429: onta$: .long   o$nta           # negation, first entry
                   4430: ontb$: .long   o$ntb           # negation, second entry
                   4431: ontc$: .long   o$ntc           # negation, third entry
                   4432: opmn$: .long   o$pmn           # pattern match by name
                   4433: opms$: .long   o$pms           # pattern match (statement)
                   4434: opop$: .long   o$pop           # pop top stack item
                   4435: ornm$: .long   o$rnm           # return name from expression
                   4436: orpl$: .long   o$rpl           # pattern replacement
                   4437: orvl$: .long   o$rvl           # return value from expression
                   4438: osla$: .long   o$sla           # selection, first entry
                   4439: oslb$: .long   o$slb           # selection, second entry
                   4440: oslc$: .long   o$slc           # selection, third entry
                   4441: osld$: .long   o$sld           # selection, fourth entry
                   4442: ostp$: .long   o$stp           # stop execution
                   4443: ounf$: .long   o$unf           # unexpected failure
                   4444:        #page   
                   4445: #
                   4446: #      TABLE OF NAMES OF UNDEFINED BINARY OPERATORS FOR OPSYN
                   4447: #
                   4448: opsnb: .long   ch$at           # at
                   4449:        .long   ch$am           # ampersand
                   4450:        .long   ch$nm           # number
                   4451:        .long   ch$pc           # percent
                   4452:        .long   ch$nt           # not
                   4453: #
                   4454: #      TABLE OF NAMES OF UNDEFINED UNARY OPERATORS FOR OPSYN
                   4455: #
                   4456: opnsu: .long   ch$br           # vertical bar
                   4457:        .long   ch$eq           # equal
                   4458:        .long   ch$nm           # number
                   4459:        .long   ch$pc           # percent
                   4460:        .long   ch$sl           # slash
                   4461:        .long   ch$ex           # exclamation
                   4462: #
                   4463: #      ADDRESS CONST CONTAINING PROFILE TABLE ENTRY SIZE
                   4464: #
                   4465: pfi2a: .long   pf$i2
                   4466: #
                   4467: #      PROFILER MESSAGE STRINGS
                   4468: #
                   4469: pfms1: .long   b$scl
                   4470:        .long   15
                   4471:        .ascii  "PROGRAM PROFILE"
                   4472:        .align  2
                   4473: pfms2: .long   b$scl
                   4474:        .long   42
                   4475:        .ascii  "STMT    NUMBER OF     -- EXECUTION TIME --"
                   4476:        .align  2
                   4477: pfms3: .long   b$scl
                   4478:        .long   47
                   4479:        .ascii  "NUMBER  EXECUTIONS  TOTAL(MSEC) PER EXCN(MCSEC)"
                   4480:        .align  2
                   4481: #
                   4482: #
                   4483: #      REAL CONSTANTS FOR GENERAL USE. NOTE THAT THE CONSTANTS
                   4484: #      STARTING AT REAV1 FORM A POWERS OF TEN TABLE (GTSTG)
                   4485: #
                   4486: reav0: .float  0f0.0           # 0.0
                   4487: reap1: .float  0f0.1           # 0.1
                   4488: reap5: .float  0f0.5           # 0.5
                   4489: reav1: .float  0f1.0           # 10**0
                   4490: reavt: .float  0f1.0e+1        # 10**1
                   4491:        .float  0f1.0e+2        # 10**2
                   4492:        .float  0f1.0e+3        # 10**3
                   4493:        .float  0f1.0e+4        # 10**4
                   4494:        .float  0f1.0e+5        # 10**5
                   4495:        .float  0f1.0e+6        # 10**6
                   4496:        .float  0f1.0e+7        # 10**7
                   4497:        .float  0f1.0e+8        # 10**8
                   4498:        .float  0f1.0e+9        # 10**9
                   4499: reatt: .float  0f1.0e+10       # 10**10
                   4500:        #page   
                   4501: #
                   4502: #      STRING CONSTANTS (SCBLK FORMAT) FOR DTYPE PROCEDURE
                   4503: #
                   4504: scarr: .long   b$scl           # array
                   4505:        .long   5
                   4506:        .ascii  "ARRAY"
                   4507:        .align  2
                   4508: #
                   4509: scbuf: .long   b$scl           # buffer
                   4510:        .long   6
                   4511:        .ascii  "BUFFER"
                   4512:        .align  2
                   4513: #
                   4514: sccod: .long   b$scl           # code
                   4515:        .long   4
                   4516:        .ascii  "CODE"
                   4517:        .align  2
                   4518: #
                   4519: scexp: .long   b$scl           # expression
                   4520:        .long   10
                   4521:        .ascii  "EXPRESSION"
                   4522:        .align  2
                   4523: #
                   4524: scext: .long   b$scl           # external
                   4525:        .long   8
                   4526:        .ascii  "EXTERNAL"
                   4527:        .align  2
                   4528: #
                   4529: scint: .long   b$scl           # integer
                   4530:        .long   7
                   4531:        .ascii  "INTEGER"
                   4532:        .align  2
                   4533: #
                   4534: scnam: .long   b$scl           # name
                   4535:        .long   4
                   4536:        .ascii  "NAME"
                   4537:        .align  2
                   4538: #
                   4539: scnum: .long   b$scl           # numeric
                   4540:        .long   7
                   4541:        .ascii  "NUMERIC"
                   4542:        .align  2
                   4543: #
                   4544: scpat: .long   b$scl           # pattern
                   4545:        .long   7
                   4546:        .ascii  "PATTERN"
                   4547:        .align  2
                   4548: #
                   4549: screa: .long   b$scl           # real
                   4550:        .long   4
                   4551:        .ascii  "REAL"
                   4552:        .align  2
                   4553: #
                   4554: scstr: .long   b$scl           # string
                   4555:        .long   6
                   4556:        .ascii  "STRING"
                   4557:        .align  2
                   4558: #
                   4559: sctab: .long   b$scl           # table
                   4560:        .long   5
                   4561:        .ascii  "TABLE"
                   4562:        .align  2
                   4563:        #page   
                   4564: #
                   4565: #      STRING CONSTANTS (SCBLK FORMAT) FOR KVRTN (SEE RETRN)
                   4566: #
                   4567: scfrt: .long   b$scl           # freturn
                   4568:        .long   7
                   4569:        .ascii  "FRETURN"
                   4570:        .align  2
                   4571: #
                   4572: scnrt: .long   b$scl           # nreturn
                   4573:        .long   7
                   4574:        .ascii  "NRETURN"
                   4575:        .align  2
                   4576: #
                   4577: scrtn: .long   b$scl           # return
                   4578:        .long   6
                   4579:        .ascii  "RETURN"
                   4580:        .align  2
                   4581: #
                   4582: #      DATATYPE NAME TABLE FOR DTYPE PROCEDURE. THE ORDER OF
                   4583: #      THESE ENTRIES IS TIED TO THE B$XXX DEFINITIONS FOR BLOCKS
                   4584: #
                   4585: scnmt: .long   scarr           # arblk     array
                   4586:        .long   scbuf           # bfblk     buffer
                   4587:        .long   sccod           # cdblk     code
                   4588:        .long   scexp           # exblk     expression
                   4589:        .long   scint           # icblk     integer
                   4590:        .long   scnam           # nmblk     name
                   4591:        .long   scpat           # p0blk     pattern
                   4592:        .long   scpat           # p1blk     pattern
                   4593:        .long   scpat           # p2blk     pattern
                   4594:        .long   screa           # rcblk     real
                   4595:        .long   scstr           # scblk     string
                   4596:        .long   scexp           # seblk     expression
                   4597:        .long   sctab           # tbblk     table
                   4598:        .long   scarr           # vcblk     array
                   4599:        .long   scext           # xnblk     external
                   4600:        .long   scext           # xrblk     external
                   4601: #
                   4602: #      STRING CONSTANT FOR REAL ZERO
                   4603: #
                   4604: scre0: .long   b$scl
                   4605:        .long   2
                   4606:        .ascii  "0."
                   4607:        .align  2
                   4608:        #page   
                   4609: #
                   4610: #      USED TO RE-INITIALISE KVSTL
                   4611: #
                   4612: stlim: .long   50000           # default statement limit
                   4613: #
                   4614: #      DUMMY FUNCTION BLOCK USED FOR UNDEFINED FUNCTIONS
                   4615: #
                   4616: stndf: .long   o$fun           # ptr to undefined function err call
                   4617:        .long   0               # dummy fargs count for call circuit
                   4618: #
                   4619: #      DUMMY CODE BLOCK USED FOR UNDEFINED LABELS
                   4620: #
                   4621: stndl: .long   l$und           # code ptr points to undefined lbl
                   4622: #
                   4623: #      DUMMY OPERATOR BLOCK USED FOR UNDEFINED OPERATORS
                   4624: #
                   4625: stndo: .long   o$oun           # ptr to undefined operator err call
                   4626:        .long   0               # dummy fargs count for call circuit
                   4627: #
                   4628: #      STANDARD VARIABLE BLOCK. THIS BLOCK IS USED TO INITIALIZE
                   4629: #      THE FIRST SEVEN FIELDS OF A NEWLY CONSTRUCTED VRBLK.
                   4630: #      ITS FORMAT IS TIED TO THE VRBLK DEFINITIONS (SEE GTNVR).
                   4631: #
                   4632: stnvr: .long   b$vrl           # vrget
                   4633:        .long   b$vrs           # vrsto
                   4634:        .long   nulls           # vrval
                   4635:        .long   b$vrg           # vrtra
                   4636:        .long   stndl           # vrlbl
                   4637:        .long   stndf           # vrfnc
                   4638:        .long   0               # vrnxt
                   4639:        #page   
                   4640: #
                   4641: #      MESSAGES USED IN END OF RUN PROCESSING (STOPR)
                   4642: #
                   4643: stpm1: .long   b$scl           # in statement
                   4644:        .long   12
                   4645:        .ascii  "IN STATEMENT"
                   4646:        .align  2
                   4647: #
                   4648: stpm2: .long   b$scl
                   4649:        .long   14
                   4650:        .ascii  "STMTS EXECUTED"
                   4651:        .align  2
                   4652: #
                   4653: stpm3: .long   b$scl
                   4654:        .long   13
                   4655:        .ascii  "RUN TIME-MSEC"
                   4656:        .align  2
                   4657: #
                   4658: stpm4: .long   b$scl
                   4659:        .long   12
                   4660:        .ascii  "MCSEC / STMT"
                   4661:        .align  2
                   4662: #
                   4663: stpm5: .long   b$scl
                   4664:        .long   13
                   4665:        .ascii  "REGENERATIONS"
                   4666:        .align  2
                   4667: #
                   4668: #      CHARS FOR /TU/ ENDING CODE
                   4669: #
                   4670: strtu: .ascii  "TU"
                   4671:        .align  2
                   4672: #
                   4673: #      TABLE USED BY CONVERT FUNCTION TO CHECK DATATYPE NAME
                   4674: #      THE ENTRIES ARE ORDERED TO CORRESPOND TO BRANCH TABLE
                   4675: #      IN S$CNV
                   4676: #
                   4677: svctb: .long   scstr           # string
                   4678:        .long   scint           # integer
                   4679:        .long   scnam           # name
                   4680:        .long   scpat           # pattern
                   4681:        .long   scarr           # array
                   4682:        .long   sctab           # table
                   4683:        .long   scexp           # expression
                   4684:        .long   sccod           # code
                   4685:        .long   scnum           # numeric
                   4686:        .long   screa           # real
                   4687:        .long   scbuf           # buffer
                   4688:        .long   0               # zero marks end of list
                   4689:        #page   
                   4690: #
                   4691: #      MESSAGES (SCBLK FORMAT) USED BY TRACE PROCEDURES
                   4692: #
                   4693: #
                   4694: tmasb: .long   b$scl           # asterisks for trace statement no
                   4695:        .long   13
                   4696:        .ascii  "************ "
                   4697:        .align  2
                   4698: #
                   4699: tmbeb: .long   b$scl           # blank-equal-blank
                   4700:        .long   3
                   4701:        .ascii  " = "
                   4702:        .align  2
                   4703: #
                   4704: #      DUMMY TRBLK FOR EXPRESSION VARIABLE
                   4705: #
                   4706: trbev: .long   b$trt           # dummy trblk
                   4707: #
                   4708: #      DUMMY TRBLK FOR KEYWORD VARIABLE
                   4709: #
                   4710: trbkv: .long   b$trt           # dummy trblk
                   4711: #
                   4712: #      DUMMY CODE BLOCK TO RETURN CONTROL TO TRXEQ PROCEDURE
                   4713: #
                   4714: trxdr: .long   o$txr           # block points to return routine
                   4715: trxdc: .long   trxdr           # pointer to block
                   4716:        #page   
                   4717: #
                   4718: #      STANDARD VARIABLE BLOCKS
                   4719: #
                   4720: #      SEE SVBLK FORMAT FOR FULL DETAILS OF THE FORMAT. THE
                   4721: #      VRBLKS ARE ORDERED BY LENGTH AND WITHIN EACH LENGTH THE
                   4722: #      ORDER IS ALPHABETICAL BY NAME OF THE VARIABLE.
                   4723: #
                   4724: v$eqf: .long   svfpr           # eq
                   4725:        .long   2
                   4726:        .ascii  "EQ"
                   4727:        .align  2
                   4728:        .long   s$eqf
                   4729:        .long   2
                   4730: #
                   4731: v$gef: .long   svfpr           # ge
                   4732:        .long   2
                   4733:        .ascii  "GE"
                   4734:        .align  2
                   4735:        .long   s$gef
                   4736:        .long   2
                   4737: #
                   4738: v$gtf: .long   svfpr           # gt
                   4739:        .long   2
                   4740:        .ascii  "GT"
                   4741:        .align  2
                   4742:        .long   s$gtf
                   4743:        .long   2
                   4744: #
                   4745: v$lef: .long   svfpr           # le
                   4746:        .long   2
                   4747:        .ascii  "LE"
                   4748:        .align  2
                   4749:        .long   s$lef
                   4750:        .long   2
                   4751: #
                   4752: v$ltf: .long   svfpr           # lt
                   4753:        .long   2
                   4754:        .ascii  "LT"
                   4755:        .align  2
                   4756:        .long   s$ltf
                   4757:        .long   2
                   4758: #
                   4759: v$nef: .long   svfpr           # ne
                   4760:        .long   2
                   4761:        .ascii  "NE"
                   4762:        .align  2
                   4763:        .long   s$nef
                   4764:        .long   2
                   4765: #
                   4766: v$any: .long   svfnp           # any
                   4767:        .long   3
                   4768:        .ascii  "ANY"
                   4769:        .align  2
                   4770:        .long   s$any
                   4771:        .long   1
                   4772: #
                   4773: v$arb: .long   svkvc           # arb
                   4774:        .long   3
                   4775:        .ascii  "ARB"
                   4776:        .align  2
                   4777:        .long   k$arb
                   4778:        .long   ndarb
                   4779:        #page   
                   4780: #
                   4781: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   4782: #
                   4783: v$arg: .long   svfnn           # arg
                   4784:        .long   3
                   4785:        .ascii  "ARG"
                   4786:        .align  2
                   4787:        .long   s$arg
                   4788:        .long   2
                   4789: #
                   4790: v$bal: .long   svkvc           # bal
                   4791:        .long   3
                   4792:        .ascii  "BAL"
                   4793:        .align  2
                   4794:        .long   k$bal
                   4795:        .long   ndbal
                   4796: #
                   4797: v$end: .long   svlbl           # end
                   4798:        .long   3
                   4799:        .ascii  "END"
                   4800:        .align  2
                   4801:        .long   l$end
                   4802: #
                   4803: v$len: .long   svfnp           # len
                   4804:        .long   3
                   4805:        .ascii  "LEN"
                   4806:        .align  2
                   4807:        .long   s$len
                   4808:        .long   1
                   4809: #
                   4810: v$leq: .long   svfpr           # leq
                   4811:        .long   3
                   4812:        .ascii  "LEQ"
                   4813:        .align  2
                   4814:        .long   s$leq
                   4815:        .long   2
                   4816: #
                   4817: v$lge: .long   svfpr           # lge
                   4818:        .long   3
                   4819:        .ascii  "LGE"
                   4820:        .align  2
                   4821:        .long   s$lge
                   4822:        .long   2
                   4823: #
                   4824: v$lgt: .long   svfpr           # lgt
                   4825:        .long   3
                   4826:        .ascii  "LGT"
                   4827:        .align  2
                   4828:        .long   s$lgt
                   4829:        .long   2
                   4830: #
                   4831: v$lle: .long   svfpr           # lle
                   4832:        .long   3
                   4833:        .ascii  "LLE"
                   4834:        .align  2
                   4835:        .long   s$lle
                   4836:        .long   2
                   4837:        #page   
                   4838: #
                   4839: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   4840: #
                   4841: v$llt: .long   svfpr           # llt
                   4842:        .long   3
                   4843:        .ascii  "LLT"
                   4844:        .align  2
                   4845:        .long   s$llt
                   4846:        .long   2
                   4847: #
                   4848: v$lne: .long   svfpr           # lne
                   4849:        .long   3
                   4850:        .ascii  "LNE"
                   4851:        .align  2
                   4852:        .long   s$lne
                   4853:        .long   2
                   4854: #
                   4855: v$pos: .long   svfnp           # pos
                   4856:        .long   3
                   4857:        .ascii  "POS"
                   4858:        .align  2
                   4859:        .long   s$pos
                   4860:        .long   1
                   4861: #
                   4862: v$rem: .long   svkvc           # rem
                   4863:        .long   3
                   4864:        .ascii  "REM"
                   4865:        .align  2
                   4866:        .long   k$rem
                   4867:        .long   ndrem
                   4868: #
                   4869: v$set: .long   svfnn           # set
                   4870:        .long   3
                   4871:        .ascii  "SET"
                   4872:        .align  2
                   4873:        .long   s$set
                   4874:        .long   3
                   4875: #
                   4876: v$tab: .long   svfnp           # tab
                   4877:        .long   3
                   4878:        .ascii  "TAB"
                   4879:        .align  2
                   4880:        .long   s$tab
                   4881:        .long   1
                   4882: #
                   4883: v$cas: .long   svknm           # case
                   4884:        .long   4
                   4885:        .ascii  "CASE"
                   4886:        .align  2
                   4887:        .long   k$cas
                   4888: #
                   4889: v$chr: .long   svfnp           # char
                   4890:        .long   4
                   4891:        .ascii  "CHAR"
                   4892:        .align  2
                   4893:        .long   s$chr
                   4894:        .long   1
                   4895: #
                   4896: v$cod: .long   svfnk           # code
                   4897:        .long   4
                   4898:        .ascii  "CODE"
                   4899:        .align  2
                   4900:        .long   k$cod
                   4901:        .long   s$cod
                   4902:        .long   1
                   4903: #
                   4904: v$cop: .long   svfnn           # copy
                   4905:        .long   4
                   4906:        .ascii  "COPY"
                   4907:        .align  2
                   4908:        .long   s$cop
                   4909:        .long   1
                   4910:        #page   
                   4911: #
                   4912: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   4913: #
                   4914: v$dat: .long   svfnn           # data
                   4915:        .long   4
                   4916:        .ascii  "DATA"
                   4917:        .align  2
                   4918:        .long   s$dat
                   4919:        .long   1
                   4920: #
                   4921: v$dte: .long   svfnn           # date
                   4922:        .long   4
                   4923:        .ascii  "DATE"
                   4924:        .align  2
                   4925:        .long   s$dte
                   4926:        .long   0
                   4927: #
                   4928: v$dmp: .long   svfnk           # dump
                   4929:        .long   4
                   4930:        .ascii  "DUMP"
                   4931:        .align  2
                   4932:        .long   k$dmp
                   4933:        .long   s$dmp
                   4934:        .long   1
                   4935: #
                   4936: v$dup: .long   svfnn           # dupl
                   4937:        .long   4
                   4938:        .ascii  "DUPL"
                   4939:        .align  2
                   4940:        .long   s$dup
                   4941:        .long   2
                   4942: #
                   4943: v$evl: .long   svfnn           # eval
                   4944:        .long   4
                   4945:        .ascii  "EVAL"
                   4946:        .align  2
                   4947:        .long   s$evl
                   4948:        .long   1
                   4949: #
                   4950: v$ext: .long   svfnn           # exit
                   4951:        .long   4
                   4952:        .ascii  "EXIT"
                   4953:        .align  2
                   4954:        .long   s$ext
                   4955:        .long   1
                   4956: #
                   4957: v$fal: .long   svkvc           # fail
                   4958:        .long   4
                   4959:        .ascii  "FAIL"
                   4960:        .align  2
                   4961:        .long   k$fal
                   4962:        .long   ndfal
                   4963: #
                   4964: v$hst: .long   svfnn           # host
                   4965:        .long   4
                   4966:        .ascii  "HOST"
                   4967:        .align  2
                   4968:        .long   s$hst
                   4969:        .long   3
                   4970:        #page   
                   4971: #
                   4972: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   4973: #
                   4974: v$itm: .long   svfnf           # item
                   4975:        .long   4
                   4976:        .ascii  "ITEM"
                   4977:        .align  2
                   4978:        .long   s$itm
                   4979:        .long   999
                   4980: #
                   4981: v$lod: .long   svfnn           # load
                   4982:        .long   4
                   4983:        .ascii  "LOAD"
                   4984:        .align  2
                   4985:        .long   s$lod
                   4986:        .long   2
                   4987: #
                   4988: v$lpd: .long   svfnp           # lpad
                   4989:        .long   4
                   4990:        .ascii  "LPAD"
                   4991:        .align  2
                   4992:        .long   s$lpd
                   4993:        .long   3
                   4994: #
                   4995: v$rpd: .long   svfnp           # rpad
                   4996:        .long   4
                   4997:        .ascii  "RPAD"
                   4998:        .align  2
                   4999:        .long   s$rpd
                   5000:        .long   3
                   5001: #
                   5002: v$rps: .long   svfnp           # rpos
                   5003:        .long   4
                   5004:        .ascii  "RPOS"
                   5005:        .align  2
                   5006:        .long   s$rps
                   5007:        .long   1
                   5008: #
                   5009: v$rtb: .long   svfnp           # rtab
                   5010:        .long   4
                   5011:        .ascii  "RTAB"
                   5012:        .align  2
                   5013:        .long   s$rtb
                   5014:        .long   1
                   5015: #
                   5016: v$si$: .long   svfnp           # size
                   5017:        .long   4
                   5018:        .ascii  "SIZE"
                   5019:        .align  2
                   5020:        .long   s$si$
                   5021:        .long   1
                   5022: #
                   5023: #
                   5024: v$srt: .long   svfnn           # sort
                   5025:        .long   4
                   5026:        .ascii  "SORT"
                   5027:        .align  2
                   5028:        .long   s$srt
                   5029:        .long   2
                   5030: v$spn: .long   svfnp           # span
                   5031:        .long   4
                   5032:        .ascii  "SPAN"
                   5033:        .align  2
                   5034:        .long   s$spn
                   5035:        .long   1
                   5036:        #page   
                   5037: #
                   5038: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5039: #
                   5040: v$stn: .long   svknm           # stno
                   5041:        .long   4
                   5042:        .ascii  "STNO"
                   5043:        .align  2
                   5044:        .long   k$stn
                   5045: #
                   5046: v$tim: .long   svfnn           # time
                   5047:        .long   4
                   5048:        .ascii  "TIME"
                   5049:        .align  2
                   5050:        .long   s$tim
                   5051:        .long   0
                   5052: #
                   5053: v$trm: .long   svfnk           # trim
                   5054:        .long   4
                   5055:        .ascii  "TRIM"
                   5056:        .align  2
                   5057:        .long   k$trm
                   5058:        .long   s$trm
                   5059:        .long   1
                   5060: #
                   5061: v$abe: .long   svknm           # abend
                   5062:        .long   5
                   5063:        .ascii  "ABEND"
                   5064:        .align  2
                   5065:        .long   k$abe
                   5066: #
                   5067: v$abo: .long   svkvl           # abort
                   5068:        .long   5
                   5069:        .ascii  "ABORT"
                   5070:        .align  2
                   5071:        .long   k$abo
                   5072:        .long   l$abo
                   5073:        .long   ndabo
                   5074: #
                   5075: v$app: .long   svfnf           # apply
                   5076:        .long   5
                   5077:        .ascii  "APPLY"
                   5078:        .align  2
                   5079:        .long   s$app
                   5080:        .long   999
                   5081: #
                   5082: v$abn: .long   svfnp           # arbno
                   5083:        .long   5
                   5084:        .ascii  "ARBNO"
                   5085:        .align  2
                   5086:        .long   s$abn
                   5087:        .long   1
                   5088: #
                   5089: v$arr: .long   svfnn           # array
                   5090:        .long   5
                   5091:        .ascii  "ARRAY"
                   5092:        .align  2
                   5093:        .long   s$arr
                   5094:        .long   2
                   5095:        #page   
                   5096: #
                   5097: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5098: #
                   5099: v$brk: .long   svfnp           # break
                   5100:        .long   5
                   5101:        .ascii  "BREAK"
                   5102:        .align  2
                   5103:        .long   s$brk
                   5104:        .long   1
                   5105: #
                   5106: v$clr: .long   svfnn           # clear
                   5107:        .long   5
                   5108:        .ascii  "CLEAR"
                   5109:        .align  2
                   5110:        .long   s$clr
                   5111:        .long   1
                   5112: #
                   5113: v$ejc: .long   svfnn           # eject
                   5114:        .long   5
                   5115:        .ascii  "EJECT"
                   5116:        .align  2
                   5117:        .long   s$ejc
                   5118:        .long   1
                   5119: #
                   5120: v$fen: .long   svfpk           # fence
                   5121:        .long   5
                   5122:        .ascii  "FENCE"
                   5123:        .align  2
                   5124:        .long   k$fen
                   5125:        .long   s$fnc
                   5126:        .long   1
                   5127:        .long   ndfen
                   5128: #
                   5129: v$fld: .long   svfnn           # field
                   5130:        .long   5
                   5131:        .ascii  "FIELD"
                   5132:        .align  2
                   5133:        .long   s$fld
                   5134:        .long   2
                   5135: #
                   5136: v$idn: .long   svfpr           # ident
                   5137:        .long   5
                   5138:        .ascii  "IDENT"
                   5139:        .align  2
                   5140:        .long   s$idn
                   5141:        .long   2
                   5142: #
                   5143: v$inp: .long   svfnk           # input
                   5144:        .long   5
                   5145:        .ascii  "INPUT"
                   5146:        .align  2
                   5147:        .long   k$inp
                   5148:        .long   s$inp
                   5149:        .long   3
                   5150: #
                   5151: v$loc: .long   svfnn           # local
                   5152:        .long   5
                   5153:        .ascii  "LOCAL"
                   5154:        .align  2
                   5155:        .long   s$loc
                   5156:        .long   2
                   5157:        #page   
                   5158: #
                   5159: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5160: #
                   5161: v$ops: .long   svfnn           # opsyn
                   5162:        .long   5
                   5163:        .ascii  "OPSYN"
                   5164:        .align  2
                   5165:        .long   s$ops
                   5166:        .long   3
                   5167: #
                   5168: v$rmd: .long   svfnp           # remdr
                   5169:        .long   5
                   5170:        .ascii  "REMDR"
                   5171:        .align  2
                   5172:        .long   s$rmd
                   5173:        .long   2
                   5174: #
                   5175: v$rsr: .long   svfnn           # rsort
                   5176:        .long   5
                   5177:        .ascii  "RSORT"
                   5178:        .align  2
                   5179:        .long   s$rsr
                   5180:        .long   2
                   5181: #
                   5182: v$tbl: .long   svfnn           # table
                   5183:        .long   5
                   5184:        .ascii  "TABLE"
                   5185:        .align  2
                   5186:        .long   s$tbl
                   5187:        .long   3
                   5188: #
                   5189: v$tra: .long   svfnk           # trace
                   5190:        .long   5
                   5191:        .ascii  "TRACE"
                   5192:        .align  2
                   5193:        .long   k$tra
                   5194:        .long   s$tra
                   5195:        .long   4
                   5196: #
                   5197: v$anc: .long   svknm           # anchor
                   5198:        .long   6
                   5199:        .ascii  "ANCHOR"
                   5200:        .align  2
                   5201:        .long   k$anc
                   5202: #
                   5203: v$apn: .long   svfnn
                   5204:        .long   6
                   5205:        .ascii  "APPEND"
                   5206:        .align  2
                   5207:        .long   s$apn
                   5208:        .long   2
                   5209: #
                   5210: v$bkx: .long   svfnp           # breakx
                   5211:        .long   6
                   5212:        .ascii  "BREAKX"
                   5213:        .align  2
                   5214:        .long   s$bkx
                   5215:        .long   1
                   5216: #
                   5217: v$buf: .long   svfnn           # buffer
                   5218:        .long   6
                   5219:        .ascii  "BUFFER"
                   5220:        .align  2
                   5221:        .long   s$buf
                   5222:        .long   2
                   5223: #
                   5224: v$def: .long   svfnn           # define
                   5225:        .long   6
                   5226:        .ascii  "DEFINE"
                   5227:        .align  2
                   5228:        .long   s$def
                   5229:        .long   2
                   5230: #
                   5231: v$det: .long   svfnn           # detach
                   5232:        .long   6
                   5233:        .ascii  "DETACH"
                   5234:        .align  2
                   5235:        .long   s$det
                   5236:        .long   1
                   5237:        #page   
                   5238: #
                   5239: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5240: #
                   5241: v$dif: .long   svfpr           # differ
                   5242:        .long   6
                   5243:        .ascii  "DIFFER"
                   5244:        .align  2
                   5245:        .long   s$dif
                   5246:        .long   2
                   5247: #
                   5248: v$ftr: .long   svknm           # ftrace
                   5249:        .long   6
                   5250:        .ascii  "FTRACE"
                   5251:        .align  2
                   5252:        .long   k$ftr
                   5253: #
                   5254: v$ins: .long   svfnn           # insert
                   5255:        .long   6
                   5256:        .ascii  "INSERT"
                   5257:        .align  2
                   5258:        .long   s$ins
                   5259:        .long   4
                   5260: #
                   5261: v$lst: .long   svknm           # lastno
                   5262:        .long   6
                   5263:        .ascii  "LASTNO"
                   5264:        .align  2
                   5265:        .long   k$lst
                   5266: #
                   5267: v$nay: .long   svfnp           # notany
                   5268:        .long   6
                   5269:        .ascii  "NOTANY"
                   5270:        .align  2
                   5271:        .long   s$nay
                   5272:        .long   1
                   5273: #
                   5274: v$oup: .long   svfnk           # output
                   5275:        .long   6
                   5276:        .ascii  "OUTPUT"
                   5277:        .align  2
                   5278:        .long   k$oup
                   5279:        .long   s$oup
                   5280:        .long   3
                   5281: #
                   5282: v$ret: .long   svlbl           # return
                   5283:        .long   6
                   5284:        .ascii  "RETURN"
                   5285:        .align  2
                   5286:        .long   l$rtn
                   5287: #
                   5288: v$rew: .long   svfnn           # rewind
                   5289:        .long   6
                   5290:        .ascii  "REWIND"
                   5291:        .align  2
                   5292:        .long   s$rew
                   5293:        .long   1
                   5294: #
                   5295: v$stt: .long   svfnn           # stoptr
                   5296:        .long   6
                   5297:        .ascii  "STOPTR"
                   5298:        .align  2
                   5299:        .long   s$stt
                   5300:        .long   2
                   5301:        #page   
                   5302: #
                   5303: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5304: #
                   5305: v$sub: .long   svfnn           # substr
                   5306:        .long   6
                   5307:        .ascii  "SUBSTR"
                   5308:        .align  2
                   5309:        .long   s$sub
                   5310:        .long   3
                   5311: #
                   5312: v$unl: .long   svfnn           # unload
                   5313:        .long   6
                   5314:        .ascii  "UNLOAD"
                   5315:        .align  2
                   5316:        .long   s$unl
                   5317:        .long   1
                   5318: #
                   5319: v$col: .long   svfnn           # collect
                   5320:        .long   7
                   5321:        .ascii  "COLLECT"
                   5322:        .align  2
                   5323:        .long   s$col
                   5324:        .long   1
                   5325: #
                   5326: v$cnv: .long   svfnn           # convert
                   5327:        .long   7
                   5328:        .ascii  "CONVERT"
                   5329:        .align  2
                   5330:        .long   s$cnv
                   5331:        .long   2
                   5332: #
                   5333: v$enf: .long   svfnn           # endfile
                   5334:        .long   7
                   5335:        .ascii  "ENDFILE"
                   5336:        .align  2
                   5337:        .long   s$enf
                   5338:        .long   1
                   5339: #
                   5340: v$etx: .long   svknm           # errtext
                   5341:        .long   7
                   5342:        .ascii  "ERRTEXT"
                   5343:        .align  2
                   5344:        .long   k$etx
                   5345: #
                   5346: v$ert: .long   svknm           # errtype
                   5347:        .long   7
                   5348:        .ascii  "ERRTYPE"
                   5349:        .align  2
                   5350:        .long   k$ert
                   5351: #
                   5352: v$frt: .long   svlbl           # freturn
                   5353:        .long   7
                   5354:        .ascii  "FRETURN"
                   5355:        .align  2
                   5356:        .long   l$frt
                   5357: #
                   5358: v$int: .long   svfpr           # integer
                   5359:        .long   7
                   5360:        .ascii  "INTEGER"
                   5361:        .align  2
                   5362:        .long   s$int
                   5363:        .long   1
                   5364: #
                   5365: v$nrt: .long   svlbl           # nreturn
                   5366:        .long   7
                   5367:        .ascii  "NRETURN"
                   5368:        .align  2
                   5369:        .long   l$nrt
                   5370:        #page   
                   5371: #
                   5372: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5373: #
                   5374: #
                   5375: v$pfl: .long   svknm           # profile
                   5376:        .long   7
                   5377:        .ascii  "PROFILE"
                   5378:        .align  2
                   5379:        .long   k$pfl
                   5380: #
                   5381: v$rpl: .long   svfnp           # replace
                   5382:        .long   7
                   5383:        .ascii  "REPLACE"
                   5384:        .align  2
                   5385:        .long   s$rpl
                   5386:        .long   3
                   5387: #
                   5388: v$rvs: .long   svfnp           # reverse
                   5389:        .long   7
                   5390:        .ascii  "REVERSE"
                   5391:        .align  2
                   5392:        .long   s$rvs
                   5393:        .long   1
                   5394: #
                   5395: v$rtn: .long   svknm           # rtntype
                   5396:        .long   7
                   5397:        .ascii  "RTNTYPE"
                   5398:        .align  2
                   5399:        .long   k$rtn
                   5400: #
                   5401: v$stx: .long   svfnn           # setexit
                   5402:        .long   7
                   5403:        .ascii  "SETEXIT"
                   5404:        .align  2
                   5405:        .long   s$stx
                   5406:        .long   1
                   5407: #
                   5408: v$stc: .long   svknm           # stcount
                   5409:        .long   7
                   5410:        .ascii  "STCOUNT"
                   5411:        .align  2
                   5412:        .long   k$stc
                   5413: #
                   5414: v$stl: .long   svknm           # stlimit
                   5415:        .long   7
                   5416:        .ascii  "STLIMIT"
                   5417:        .align  2
                   5418:        .long   k$stl
                   5419: #
                   5420: v$suc: .long   svkvc           # succeed
                   5421:        .long   7
                   5422:        .ascii  "SUCCEED"
                   5423:        .align  2
                   5424:        .long   k$suc
                   5425:        .long   ndsuc
                   5426: #
                   5427: v$alp: .long   svkwc           # alphabet
                   5428:        .long   8
                   5429:        .ascii  "ALPHABET"
                   5430:        .align  2
                   5431:        .long   k$alp
                   5432: #
                   5433: v$cnt: .long   svlbl           # continue
                   5434:        .long   8
                   5435:        .ascii  "CONTINUE"
                   5436:        .align  2
                   5437:        .long   l$cnt
                   5438:        #page   
                   5439: #
                   5440: #      STANDARD VARIABLE BLOCKS (CONTINUED)
                   5441: #
                   5442: v$dtp: .long   svfnp           # datatype
                   5443:        .long   8
                   5444:        .ascii  "DATATYPE"
                   5445:        .align  2
                   5446:        .long   s$dtp
                   5447:        .long   1
                   5448: #
                   5449: v$erl: .long   svknm           # errlimit
                   5450:        .long   8
                   5451:        .ascii  "ERRLIMIT"
                   5452:        .align  2
                   5453:        .long   k$erl
                   5454: #
                   5455: v$fnc: .long   svknm           # fnclevel
                   5456:        .long   8
                   5457:        .ascii  "FNCLEVEL"
                   5458:        .align  2
                   5459:        .long   k$fnc
                   5460: #
                   5461: v$mxl: .long   svknm           # maxlngth
                   5462:        .long   8
                   5463:        .ascii  "MAXLNGTH"
                   5464:        .align  2
                   5465:        .long   k$mxl
                   5466: #
                   5467: v$ter: .long   0               # terminal
                   5468:        .long   8
                   5469:        .ascii  "TERMINAL"
                   5470:        .align  2
                   5471:        .long   0
                   5472: #
                   5473: v$pro: .long   svfnn           # prototype
                   5474:        .long   9
                   5475:        .ascii  "PROTOTYPE"
                   5476:        .align  2
                   5477:        .long   s$pro
                   5478:        .long   1
                   5479: #
                   5480:        .long   0               # dummy entry to end list
                   5481:        .long   10              # length gt 9 (prototype)
                   5482:        #page   
                   5483: #
                   5484: #      LIST OF SVBLK POINTERS FOR KEYWORDS TO BE DUMPED. THE
                   5485: #      LIST IS IN THE ORDER WHICH APPEARS ON THE DUMP OUTPUT.
                   5486: #
                   5487: vdmkw: .long   v$anc           # anchor
                   5488:        .long   v$cas           # ccase
                   5489:        .long   v$cod           # code
                   5490:        .long   v$dmp           # dump
                   5491:        .long   v$erl           # errlimit
                   5492:        .long   v$etx           # errtext
                   5493:        .long   v$ert           # errtype
                   5494:        .long   v$fnc           # fnclevel
                   5495:        .long   v$ftr           # ftrace
                   5496:        .long   v$inp           # input
                   5497:        .long   v$lst           # lastno
                   5498:        .long   v$mxl           # maxlength
                   5499:        .long   v$oup           # output
                   5500:        .long   v$pfl           # profile
                   5501:        .long   v$rtn           # rtntype
                   5502:        .long   v$stc           # stcount
                   5503:        .long   v$stl           # stlimit
                   5504:        .long   v$stn           # stno
                   5505:        .long   v$tra           # trace
                   5506:        .long   v$trm           # trim
                   5507:        .long   0               # end of list
                   5508: #
                   5509: #      TABLE USED BY GTNVR TO SEARCH SVBLK LISTS
                   5510: #
                   5511: vsrch: .long   0               # dummy entry to get proper indexing
                   5512:        .long   v$eqf           # start of 1 char variables (none)
                   5513:        .long   v$eqf           # start of 2 char variables
                   5514:        .long   v$any           # start of 3 char variables
                   5515:        .long   v$cas           # start of 4 char variables
                   5516:        .long   v$abe           # start of 5 char variables
                   5517:        .long   v$anc           # start of 6 char variables
                   5518:        .long   v$col           # start of 7 char variables
                   5519:        .long   v$alp           # start of 8 char variables
                   5520:        .long   v$pro           # start of 9 char variables
                   5521:        #title  s p i t b o l -- working storage section
                   5522: #
                   5523: #      THE WORKING STORAGE SECTION CONTAINS AREAS WHICH ARE
                   5524: #      CHANGED DURING EXECUTION OF THE PROGRAM. THE VALUE
                   5525: #      ASSEMBLED IS THE INITIAL VALUE BEFORE EXECUTION STARTS.
                   5526: #
                   5527: #      ALL THESE AREAS ARE FIXED LENGTH AREAS. VARIABLE LENGTH
                   5528: #      DATA IS STORED IN THE STATIC OR DYNAMIC REGIONS OF THE
                   5529: #      ALLOCATED DATA AREAS.
                   5530: #
                   5531: #      THE VALUES IN THIS AREA ARE DESCRIBED EITHER AS WORK
                   5532: #      AREAS OR AS GLOBAL VALUES. A WORK AREA IS USED IN AN
                   5533: #      EPHEMERAL MANNER AND THE VALUE IS NOT SAVED FROM ONE
                   5534: #      ENTRY INTO A ROUTINE TO ANOTHER. A GLOBAL VALUE IS A
                   5535: #      LESS TEMPORARY LOCATION WHOSE VALUE IS SAVED FROM ONE
                   5536: #      CALL TO ANOTHER.
                   5537: #
                   5538: #      A GENERAL PART OF THE APPROACH IN THIS PROGRAM IS NOT
                   5539: #      TO OVERLAP WORK AREAS BETWEEN PROCEDURES EVEN THOUGH A
                   5540: #      SMALL AMOUNT OF SPACE COULD BE SAVED. SUCH OVERLAP IS
                   5541: #      CONSIDERED A SOURCE OF PROGRAM ERRORS AND DECREASES THE
                   5542: #      INFORMATION LEFT BEHIND AFTER A SYSTEM CRASH OF ANY KIND.
                   5543: #
                   5544: #      THE NAMES OF THESE LOCATIONS ARE LABELS WITH FIVE LETTER
                   5545: #      (A-Y,$) NAMES. AS FAR AS POSSIBLE THE ORDER IS KEPT
                   5546: #      ALPHABETICAL BY THESE NAMES BUT IN SOME CASES THERE
                   5547: #      ARE SLIGHT DEPARTURES CAUSED BY OTHER ORDER REQUIREMENTS.
                   5548: #
                   5549: #      UNLESS OTHERWISE DOCUMENTED, THE ORDER OF WORK AREAS
                   5550: #      DOES NOT AFFECT THE EXECUTION OF THE SPITBOL PROGRAM.
                   5551: #
                   5552:        .data   1
                   5553:        #sec                    # start of working storage section
                   5554:        #page   
                   5555: #
                   5556: #      THIS AREA IS NOT CLEARED BY INITIAL CODE
                   5557: #
                   5558: cmlab: .long   b$scl           # string used to check label legality
                   5559:        .long   2
                   5560:        .ascii  "  "
                   5561:        .align  2
                   5562: #
                   5563: #      LABEL TO MARK START OF WORK AREA
                   5564: #
                   5565: aaaaa: .long   0
                   5566: #
                   5567: #      WORK AREAS FOR ALLOC PROCEDURE
                   5568: #
                   5569: aldyn: .long   0               # amount of dynamic store
                   5570: alfsf: .long   0               # factor in free store pcntage check
                   5571: allia: .long   0               # dump ia
                   5572: allsv: .long   0               # save wb in alloc
                   5573: #
                   5574: #      WORK AREAS FOR ALOST PROCEDURE
                   5575: #
                   5576: alsta: .long   0               # save wa in alost
                   5577: #
                   5578: #      SAVE AREAS FOR ARRAY FUNCTION (S$ARR)
                   5579: #
                   5580: arcdm: .long   0               # count dimensions
                   5581: arnel: .long   0               # count elements
                   5582: arptr: .long   0               # offset ptr into arblk
                   5583: arsvl: .long   0               # save integer low bound
                   5584:        #page   
                   5585: #      WORK AREAS FOR ARREF ROUTINE
                   5586: #
                   5587: arfsi: .long   0               # save current evolving subscript
                   5588: arfxs: .long   0               # save base stack pointer
                   5589: #
                   5590: #      WORK AREAS FOR B$EFC BLOCK ROUTINE
                   5591: #
                   5592: befof: .long   0               # save offset ptr into efblk
                   5593: #
                   5594: #      WORK AREAS FOR B$PFC BLOCK ROUTINE
                   5595: #
                   5596: bpfpf: .long   0               # save pfblk pointer
                   5597: bpfsv: .long   0               # save old function value
                   5598: bpfxt: .long   0               # pointer to stacked arguments
                   5599: #
                   5600: #      SAVE AREAS FOR COLLECT FUNCTION (S$COL)
                   5601: #
                   5602: clsvi: .long   0               # save integer argument
                   5603: #
                   5604: #      GLOBAL VALUES FOR CMPIL PROCEDURE
                   5605: #
                   5606: cmerc: .long   0               # count of initial compile errors
                   5607: cmpxs: .long   0               # save stack ptr in case of errors
                   5608: cmpsn: .long   1               # number of next statement to compile
                   5609: cmpss: .long   0               # save subroutine stack ptr
                   5610: #
                   5611: #      WORK AREA FOR CNCRD
                   5612: #
                   5613: cnscc: .long   0               # pointer to control card string
                   5614: cnswc: .long   0               # word count
                   5615: cnr$t: .long   0               # pointer to r$ttl or r$stl
                   5616: cnttl: .long   0               # flag for -title, -stitl
                   5617: #
                   5618: #      WORK AREAS FOR CONVERT FUNCTION (S$CNV)
                   5619: #
                   5620: cnvtp: .long   0               # save ptr into scvtb
                   5621: #
                   5622: #      FLAG FOR SUPPRESSION OF COMPILATION STATISTICS.
                   5623: #
                   5624: cpsts: .long   0               # suppress comp. stats if non zero
                   5625: #
                   5626: #      GLOBAL VALUES FOR CONTROL CARD SWITCHES
                   5627: #
                   5628: cswdb: .long   0               # 0/1 for -single/-double
                   5629: cswer: .long   0               # 0/1 for -errors/-noerrors
                   5630: cswex: .long   0               # 0/1 for -execute/-noexecute
                   5631: cswfl: .long   1               # 0/1 for -nofail/-fail
                   5632: cswin: .long   iniln           # xxx for -inxxx
                   5633: cswls: .long   1               # 0/1 for -nolist/-list
                   5634: cswno: .long   0               # 0/1 for -optimise/-noopt
                   5635: cswpr: .long   0               # 0/1 for -noprint/-print
                   5636: #
                   5637: #      GLOBAL LOCATION USED BY PATST PROCEDURE
                   5638: #
                   5639: ctmsk: .long   0               # last bit position used in r$ctp
                   5640: curid: .long   0               # current id value
                   5641:        #page   
                   5642: #
                   5643: #      GLOBAL VALUE FOR CDWRD PROCEDURE
                   5644: #
                   5645: cwcof: .long   0               # next word offset in current ccblk
                   5646: #
                   5647: #      WORK AREAS FOR DATA FUNCTION (S$DAT)
                   5648: #
                   5649: datdv: .long   0               # save vrblk ptr for datatype name
                   5650: datxs: .long   0               # save initial stack pointer
                   5651: #
                   5652: #      WORK AREAS FOR DEFINE FUNCTION (S$DEF)
                   5653: #
                   5654: deflb: .long   0               # save vrblk ptr for label
                   5655: defna: .long   0               # count function arguments
                   5656: defvr: .long   0               # save vrblk ptr for function name
                   5657: defxs: .long   0               # save initial stack pointer
                   5658: #
                   5659: #      WORK AREAS FOR DUMPR PROCEDURE
                   5660: #
                   5661: dmarg: .long   0               # dump argument
                   5662: dmpkb: .long   b$kvt           # dummy kvblk for use in dumpr
                   5663: dmpkt: .long   trbkv           # kvvar trblk pointer
                   5664: dmpkn: .long   0               # keyword number (must follow dmpkb)
                   5665: dmpsa: .long   0               # preserve wa over prtvl call
                   5666: dmpsv: .long   0               # general scratch save
                   5667: dmvch: .long   0               # chain pointer for variable blocks
                   5668: dmpch: .long   0               # save sorted vrblk chain pointer
                   5669: #
                   5670: #      GLOBAL LOCATIONS FOR DYNAMIC STORAGE POINTERS
                   5671: #
                   5672: dnamb: .long   0               # start of dynamic area
                   5673: dnamp: .long   0               # next available loc in dynamic area
                   5674: dname: .long   0               # end of available dynamic area
                   5675: #
                   5676: #      WORK AREA FOR DTACH
                   5677: #
                   5678: dtcnb: .long   0               # name base
                   5679: dtcnm: .long   0               # name ptr
                   5680: #
                   5681: #      WORK AREAS FOR DUPL FUNCTION (S$DUP)
                   5682: #
                   5683: dupsi: .long   0               # store integer string length
                   5684: #
                   5685: #      WORK AREA FOR ENDFILE (S$ENF)
                   5686: #
                   5687: enfch: .long   0               # for iochn chain head
                   5688: #
                   5689: #      WORK AREA FOR ERROR PROCESSING.
                   5690: #
                   5691: erich: .long   0               # copy error reports to int.chan if 1
                   5692: erlst: .long   0               # for listr when errors go to int.ch.
                   5693: errft: .long   0               # fatal error flag
                   5694: errsp: .long   0               # error suppression flag
                   5695:        #page   
                   5696: #
                   5697: #      DUMP AREA FOR ERTEX
                   5698: #
                   5699: ertwa: .long   0               # save wa
                   5700: ertwb: .long   0               # save wb
                   5701: #
                   5702: #      GLOBAL VALUES FOR EVALI
                   5703: #
                   5704: evlin: .long   p$len           # dummy pattern block pcode
                   5705: evlis: .long   0               # pointer to subsequent node
                   5706: evliv: .long   0               # value of parameter
                   5707: #      WORK AREA FOR EXPAN
                   5708: #
                   5709: expsv: .long   0               # save op dope vector pointer
                   5710: #
                   5711: #      FLAG FOR SUPPRESSION OF EXECUTION STATS
                   5712: #
                   5713: exsts: .long   0               # suppress exec stats if set
                   5714: #
                   5715: #      GLOBAL VALUES FOR EXFAL AND RETURN
                   5716: #
                   5717: flprt: .long   0               # location of fail offset for return
                   5718: flptr: .long   0               # location of failure offset on stack
                   5719: #
                   5720: #      WORK AREAS FOR GBCOL PROCEDURE
                   5721: #
                   5722: gbcfl: .long   0               # garbage collector active flag
                   5723: gbclm: .long   0               # pointer to last move block (pass 3)
                   5724: gbcnm: .long   0               # dummy first move block
                   5725: gbcns: .long   0               # rest of dummy block (follows gbcnm)
                   5726: gbsva: .long   0               # save wa
                   5727: gbsvb: .long   0               # save wb
                   5728: gbsvc: .long   0               # save wc
                   5729: #
                   5730: #      GLOBAL LOCATION TO COUNT GARBAGE COLLECTIONS (GBCOL)
                   5731: #
                   5732: gbcnt: .long   0               # count of garbage collections
                   5733: #
                   5734: #      WORK AREAS FOR GTNVR PROCEDURE
                   5735: #
                   5736: gnvhe: .long   0               # ptr to end of hash chain
                   5737: gnvnw: .long   0               # number of words in string name
                   5738: gnvsa: .long   0               # save wa
                   5739: gnvsb: .long   0               # save wb
                   5740: gnvsp: .long   0               # pointer into vsrch table
                   5741: gnvst: .long   0               # pointer to chars of string
                   5742: #
                   5743: #      GLOBAL VALUE FOR GTCOD AND GTEXP
                   5744: #
                   5745: gtcef: .long   0               # save fail ptr in case of error
                   5746: #
                   5747: #      WORK AREAS FOR GTINT
                   5748: #
                   5749: gtina: .long   0               # save wa
                   5750: gtinb: .long   0               # save wb
                   5751:        #page   
                   5752: #
                   5753: #      WORK AREAS FOR GTNUM PROCEDURE
                   5754: #
                   5755: gtnnf: .long   0               # zero/nonzero for result +/-
                   5756: gtnsi: .long   0               # general integer save
                   5757: gtndf: .long   0               # 0/1 for dec point so far no/yes
                   5758: gtnes: .long   0               # zero/nonzero exponent +/-
                   5759: gtnex: .long   0               # real exponent
                   5760: gtnsc: .long   0               # scale (places after point)
                   5761: gtnsr: .float  0f0.0           # general real save
                   5762: gtnrd: .long   0               # flag for ok real number
                   5763: #
                   5764: #      WORK AREAS FOR GTPAT PROCEDURE
                   5765: #
                   5766: gtpsb: .long   0               # save wb
                   5767: #
                   5768: #      WORK AREAS FOR GTSTG PROCEDURE
                   5769: #
                   5770: gtssf: .long   0               # 0/1 for result +/-
                   5771: gtsvc: .long   0               # save wc
                   5772: gtsvb: .long   0               # save wb
                   5773: gtswk: .long   0               # ptr to work area for gtstg
                   5774: gtses: .long   0               # char + or - for exponent +/-
                   5775: gtsrs: .float  0f0.0           # general real save
                   5776: #
                   5777: #      GLOBAL LOCATIONS (CONSTANTS) FOR GTSTG PROCEDURE
                   5778: #
                   5779: gtsrn: .float  0f0.0           # rounding factor 0.5*10**-cfp$s
                   5780: gtssc: .float  0f0.0           # scaling value 10**cfp$s
                   5781: #
                   5782: #      WORK AREAS FOR GTVAR PROCEDURE
                   5783: #
                   5784: gtvrc: .long   0               # save wc
                   5785: #
                   5786: #      FLAG FOR HEADER PRINTING
                   5787: #
                   5788: headp: .long   0               # header printed flag
                   5789: #
                   5790: #      GLOBAL VALUES FOR VARIABLE HASH TABLE
                   5791: #
                   5792: hshnb: .long   0               # number of hash buckets
                   5793: hshtb: .long   0               # pointer to start of vrblk hash tabl
                   5794: hshte: .long   0               # pointer past end of vrblk hash tabl
                   5795: #
                   5796: #      WORK AREA FOR INIT
                   5797: #
                   5798: iniss: .long   0               # save subroutine stack ptr
                   5799: initr: .long   0               # save terminal flag
                   5800: #
                   5801: #      SAVE AREA FOR INSBF
                   5802: #
                   5803: insab: .long   0               # entry wa + entry wb
                   5804: inssa: .long   0               # save entry wa
                   5805: inssb: .long   0               # save entry wb
                   5806: inssc: .long   0               # save entry wc
                   5807: #
                   5808: #      WORK AREAS FOR IOPUT
                   5809: #
                   5810: ioptt: .long   0               # type of association
                   5811:        #page   
                   5812: #
                   5813: #      GLOBAL VALUES FOR KEYWORD VALUES WHICH ARE STORED AS ONE
                   5814: #      WORD INTEGERS. THESE VALUES MUST BE ASSEMBLED IN THE
                   5815: #      FOLLOWING ORDER (AS DICTATED BY K$XXX DEFINITION VALUES).
                   5816: #
                   5817: kvabe: .long   0               # abend
                   5818: kvanc: .long   0               # anchor
                   5819: kvcas: .long   0               # case
                   5820: kvcod: .long   0               # code
                   5821: kvdmp: .long   0               # dump
                   5822: kverl: .long   0               # errlimit
                   5823: kvert: .long   0               # errtype
                   5824: kvftr: .long   0               # ftrace
                   5825: kvinp: .long   1               # input
                   5826: kvmxl: .long   5000            # maxlength
                   5827: kvoup: .long   1               # output
                   5828: kvpfl: .long   0               # profile
                   5829: kvtra: .long   0               # trace
                   5830: kvtrm: .long   0               # trim
                   5831: kvfnc: .long   0               # fnclevel
                   5832: kvlst: .long   0               # lastno
                   5833: kvstn: .long   0               # stno
                   5834: #
                   5835: #      GLOBAL VALUES FOR OTHER KEYWORDS
                   5836: #
                   5837: kvalp: .long   0               # alphabet
                   5838: kvrtn: .long   nulls           # rtntype (scblk pointer)
                   5839: kvstl: .long   50000           # stlimit
                   5840: kvstc: .long   50000           # stcount (counts down from stlimit)
                   5841: #
                   5842: #      WORK AREAS FOR LOAD FUNCTION
                   5843: #
                   5844: lodfn: .long   0               # pointer to vrblk for func name
                   5845: lodna: .long   0               # count number of arguments
                   5846: #
                   5847: #      GLOBAL VALUES FOR LISTR PROCEDURE
                   5848: #
                   5849: lstlc: .long   0               # count lines on source list page
                   5850: lstnp: .long   0               # max number of lines on page
                   5851: lstpf: .long   1               # set nonzero if current image listed
                   5852: lstpg: .long   0               # current source list page number
                   5853: lstpo: .long   0               # offset to   page nnn   message
                   5854: lstsn: .long   0               # remember last stmnum listed
                   5855: #
                   5856: #      MAXIMUM SIZE OF SPITBOL OBJECTS
                   5857: #
                   5858: mxlen: .long   0               # initialised by sysmx call
                   5859: #
                   5860: #      EXECUTION CONTROL VARIABLE
                   5861: #
                   5862: noxeq: .long   0               # set non-zero to inhibit execution
                   5863: #
                   5864: #      PROFILER GLOBAL VALUES AND WORK LOCATIONS
                   5865: #
                   5866: pfdmp: .long   0               # set non-0 if &profile set non-0
                   5867: pffnc: .long   0               # set non-0 if funct just entered
                   5868: pfstm: .long   0               # to store starting time of stmt
                   5869: pfetm: .long   0               # to store ending time of stmt
                   5870: pfsvw: .long   0               # to save a w-reg
                   5871: pftbl: .long   0               # gets adrs of (imag) table base
                   5872: pfnte: .long   0               # nr of table entries
                   5873: pfste: .long   0               # gets int rep of table entry size
                   5874: #
                   5875:        #page   
                   5876: #
                   5877: #      GLOBAL VALUES USED IN PATTERN MATCH ROUTINES
                   5878: #
                   5879: pmdfl: .long   0               # pattern assignment flag
                   5880: pmhbs: .long   0               # history stack base pointer
                   5881: pmssl: .long   0               # length of subject string in chars
                   5882: #
                   5883: #      FLAGS USED FOR STANDARD FILE LISTING OPTIONS
                   5884: #
                   5885: prich: .long   0               # printer on interactive channel
                   5886: prstd: .long   0               # tested by prtpg
                   5887: prsto: .long   0               # standard listing option flag
                   5888: #
                   5889: #      GLOBAL VALUE FOR PRTNM PROCEDURE
                   5890: #
                   5891: prnmv: .long   0               # vrblk ptr from last name search
                   5892: #
                   5893: #      WORK AREAS FOR PRTNM PROCEDURE
                   5894: #
                   5895: prnsi: .long   0               # scratch integer loc
                   5896: #
                   5897: #      WORK AREAS FOR PRTSN PROCEDURE
                   5898: #
                   5899: prsna: .long   0               # save wa
                   5900: #
                   5901: #      GLOBAL VALUES FOR PRINT PROCEDURES
                   5902: #
                   5903: prbuf: .long   0               # ptr to print bfr in static
                   5904: precl: .long   0               # extended/compact listing flag
                   5905: prlen: .long   0               # length of print buffer in chars
                   5906: prlnw: .long   0               # length of print buffer in words
                   5907: profs: .long   0               # offset to next location in prbuf
                   5908: prtef: .long   0               # endfile flag
                   5909: #
                   5910: #      WORK AREAS FOR PRTST PROCEDURE
                   5911: #
                   5912: prsva: .long   0               # save wa
                   5913: prsvb: .long   0               # save wb
                   5914: prsvc: .long   0               # save char counter
                   5915: #
                   5916: #      WORK AREA FOR PRTNL
                   5917: #
                   5918: prtsa: .long   0               # save wa
                   5919: prtsb: .long   0               # save wb
                   5920: #
                   5921: #      WORK AREA FOR PRTVL
                   5922: #
                   5923: prvsi: .long   0               # save idval
                   5924: #
                   5925: #      WORK AREAS FOR PATTERN MATCH ROUTINES
                   5926: #
                   5927: psave: .long   0               # temporary save for current node ptr
                   5928: psavc: .long   0               # save cursor in p$spn, p$str
                   5929:        #page   
                   5930: #
                   5931: #      AMOUNT OF MEMORY RESERVED FOR END OF EXECUTION
                   5932: #
                   5933: rsmem: .long   0               # reserve memory
                   5934: #
                   5935: #      WORK AREAS FOR RETRN ROUTINE
                   5936: #
                   5937: rtnbp: .long   0               # to save a block pointer
                   5938: rtnfv: .long   0               # new function value (result)
                   5939: rtnsv: .long   0               # old function value (saved value)
                   5940: #
                   5941: #      RELOCATABLE GLOBAL VALUES
                   5942: #
                   5943: #      ALL THE POINTERS IN THIS SECTION CAN POINT TO BLOCKS IN
                   5944: #      THE DYNAMIC STORAGE AREA AND MUST BE RELOCATED BY THE
                   5945: #      GARBAGE COLLECTOR. THEY ARE IDENTIFIED BY R$XXX NAMES.
                   5946: #
                   5947: r$aaa: .long   0               # start of relocatable values
                   5948: r$arf: .long   0               # array block pointer for arref
                   5949: r$ccb: .long   0               # ptr to ccblk being built (cdwrd)
                   5950: r$cim: .long   0               # ptr to current compiler input str
                   5951: r$cmp: .long   0               # copy of r$cim used in cmpil
                   5952: r$cni: .long   0               # ptr to next compiler input string
                   5953: r$cnt: .long   0               # cdblk pointer for setexit continue
                   5954: r$cod: .long   0               # pointer to current cdblk or exblk
                   5955: r$ctp: .long   0               # ptr to current ctblk for patst
                   5956: r$ert: .long   0               # trblk pointer for errtype trace
                   5957: r$etx: .long   nulls           # pointer to errtext string
                   5958: r$exs: .long   0               # = save xl in expdm
                   5959: r$fcb: .long   0               # fcblk chain head
                   5960: r$fnc: .long   0               # trblk pointer for fnclevel trace
                   5961: r$gtc: .long   0               # keep code ptr for gtcod,gtexp
                   5962: r$io1: .long   0               # file arg1 for ioput
                   5963: r$io2: .long   0               # file arg2 for ioput
                   5964: r$iof: .long   0               # fcblk ptr or 0
                   5965: r$ion: .long   0               # name base ptr
                   5966: r$iop: .long   0               # predecessor block ptr for ioput
                   5967: r$iot: .long   0               # trblk ptr for ioput
                   5968: r$pmb: .long   0               # buffer ptr in pattern match
                   5969: r$pms: .long   0               # subject string ptr in pattern match
                   5970: r$ra2: .long   0               # replace second argument last time
                   5971: r$ra3: .long   0               # replace third argument last time
                   5972: r$rpt: .long   0               # ptr to ctblk replace table last usd
                   5973: r$scp: .long   0               # save pointer from last scane call
                   5974: r$sxl: .long   0               # preserve xl in sortc
                   5975: r$sxr: .long   0               # preserve xr in sorta/sortc
                   5976: r$stc: .long   0               # trblk pointer for stcount trace
                   5977: r$stl: .long   0               # source listing sub-title
                   5978: r$sxc: .long   0               # code (cdblk) ptr for setexit trap
                   5979: r$ttl: .long   nulls           # source listing title
                   5980: r$xsc: .long   0               # string pointer for xscan
                   5981:        #page   
                   5982: #
                   5983: #      THE REMAINING POINTERS IN THIS LIST ARE USED TO POINT
                   5984: #      TO FUNCTION BLOCKS FOR NORMALLY UNDEFINED OPERATORS.
                   5985: #
                   5986: r$uba: .long   stndo           # binary at
                   5987: r$ubm: .long   stndo           # binary ampersand
                   5988: r$ubn: .long   stndo           # binary number sign
                   5989: r$ubp: .long   stndo           # binary percent
                   5990: r$ubt: .long   stndo           # binary not
                   5991: r$uub: .long   stndo           # unary vertical bar
                   5992: r$uue: .long   stndo           # unary equal
                   5993: r$uun: .long   stndo           # unary number sign
                   5994: r$uup: .long   stndo           # unary percent
                   5995: r$uus: .long   stndo           # unary slash
                   5996: r$uux: .long   stndo           # unary exclamation
                   5997: r$yyy: .long   0               # last relocatable location
                   5998: #
                   5999: #      WORK AREAS FOR SUBSTR FUNCTION (S$SUB)
                   6000: #
                   6001: sbssv: .long   0               # save third argument
                   6002: #
                   6003: #      GLOBAL LOCATIONS USED IN SCAN PROCEDURE
                   6004: #
                   6005: scnbl: .long   0               # set non-zero if scanned past blanks
                   6006: scncc: .long   0               # non-zero to scan control card name
                   6007: scngo: .long   0               # set non-zero to scan goto field
                   6008: scnil: .long   0               # length of current input image
                   6009: scnpt: .long   0               # pointer to next location in r$cim
                   6010: scnrs: .long   0               # set non-zero to signal rescan
                   6011: scntp: .long   0               # save syntax type from last call
                   6012: #
                   6013: #      WORK AREAS FOR SCAN PROCEDURE
                   6014: #
                   6015: scnsa: .long   0               # save wa
                   6016: scnsb: .long   0               # save wb
                   6017: scnsc: .long   0               # save wc
                   6018: scnse: .long   0               # start of current element
                   6019: scnof: .long   0               # save offset
                   6020:        #page   
                   6021: #
                   6022: #      WORK AREA USED BY SORTA, SORTC, SORTF, SORTH
                   6023: #
                   6024: srtdf: .long   0               # datatype field name
                   6025: srtfd: .long   0               # found dfblk address
                   6026: srtff: .long   0               # found field name
                   6027: srtfo: .long   0               # offset to field name
                   6028: srtnr: .long   0               # number of rows
                   6029: srtof: .long   0               # offset within row to sort key
                   6030: srtrt: .long   0               # root offset
                   6031: srts1: .long   0               # save offset 1
                   6032: srts2: .long   0               # save offset 2
                   6033: srtsc: .long   0               # save wc
                   6034: srtsf: .long   0               # sort array first row offset
                   6035: srtsn: .long   0               # save n
                   6036: srtso: .long   0               # offset to a(0)
                   6037: srtsr: .long   0               # 0 , non-zero for sort, rsort
                   6038: srtst: .long   0               # stride from one row to next
                   6039: srtwc: .long   0               # dump wc
                   6040: #
                   6041: #      GLOBAL VALUE FOR INDICATING STAGE (SEE ERROR SECTION)
                   6042: #
                   6043: stage: .long   0               # initial value = initial compile
                   6044: #
                   6045: #      GLOBAL VALUES DEFINING EXTENT OF STATIC AREA (ALOST)
                   6046: #
                   6047: statb: .long   0               # start of static area
                   6048: state: .long   0               # end of static area
                   6049:        #page   
                   6050: #
                   6051: #      GLOBAL STACK POINTER
                   6052: #
                   6053: stbas: .long   0               # pointer past stack base
                   6054: #
                   6055: #      WORK AREAS FOR STOPR ROUTINE
                   6056: #
                   6057: stpsi: .long   0               # save value of stcount
                   6058: stpti: .long   0               # save time elapsed
                   6059: #
                   6060: #      GLOBAL VALUES FOR SETEXIT FUNCTION (S$STX)
                   6061: #
                   6062: stxof: .long   0               # failure offset
                   6063: stxvr: .long   nulls           # vrblk pointer or null
                   6064: #
                   6065: #      WORK AREAS FOR TFIND PROCEDURE
                   6066: #
                   6067: tfnsi: .long   0               # number of headers
                   6068: #
                   6069: #      GLOBAL VALUE FOR TIME KEEPING
                   6070: #
                   6071: timsx: .long   0               # time at start of execution
                   6072: timup: .long   0               # set when time up occurs
                   6073: #
                   6074: #      WORK AREAS FOR XSCAN PROCEDURE
                   6075: #
                   6076: xscrt: .long   0               # save return code
                   6077: xscwb: .long   0               # save register wb
                   6078: #
                   6079: #      GLOBAL VALUES FOR XSCAN AND XSCNI PROCEDURES
                   6080: #
                   6081: xsofs: .long   0               # offset to current location in r$xsc
                   6082: #
                   6083: #      LABEL TO MARK END OF WORK AREA
                   6084: #
                   6085: yyyyy: .long   0
                   6086:        #title  s p i t b o l -- initialization
                   6087: #
                   6088: #      INITIALISATION
                   6089: #      THE FOLLOWING SECTION RECEIVES CONTROL FROM THE SYSTEM
                   6090: #      AT THE START OF A RUN WITH THE REGISTERS SET AS FOLLOWS.
                   6091: #
                   6092: #      (XS)                  POINTS PAST STACK BASE
                   6093: #      (XR)                  POINTS TO FIRST WORD OF DATA AREA
                   6094: #      (XL)                  POINTS TO LAST WORD OF DATA AREA
                   6095: #
                   6096:        .text   0
                   6097:        .globl  sec04
                   6098: sec04:         
                   6099:        #sec                    # start of program section
                   6100:        jsb     systm           # initialise timer
                   6101: #
                   6102: #      INITIALISE WORK AREA (ESSENTIAL FOR BATCHED RUNS)
                   6103: #
                   6104:        movl    r9,r7           # preserve xr
                   6105:        movl    $yyyyy,r6       # point to end of work area
                   6106:        subl2   $aaaaa,r6       # get length of work area
                   6107:        ashl    $-2,r6,r6       # convert to words
                   6108:                                # count for loop
                   6109:        movl    $aaaaa,r9       # set up index register
                   6110: #
                   6111: #      CLEAR WORK SPACE
                   6112: #
                   6113: ini01: clrl    (r9)+           # clear a word
                   6114:        sobgtr  r6,ini01        # loop till done
                   6115:        movl    $stndo,r6       # undefined operators pointer
                   6116:        movl    $r$yyy,r8       # point to table end
                   6117:        subl2   $r$uba,r8       # length of undef. operators table
                   6118:        ashl    $-2,r8,r8       # convert to words
                   6119:                                # loop counter
                   6120:        movl    $r$uba,r9       # set up xr
                   6121: #
                   6122: #      SET CORRECT VALUE INTO UNDEFINED OPERATORS TABLE
                   6123: #
                   6124: ini02: movl    r6,(r9)+        # store value
                   6125:        sobgtr  r8,ini02        # loop till all done
                   6126:        movl    $num01,r6       # get a 1
                   6127:        movl    r6,cmpsn        # statement no
                   6128:        movl    r6,cswfl        # nofail
                   6129:        movl    r6,cswls        # list
                   6130:        movl    r6,kvinp        # input
                   6131:        movl    r6,kvoup        # output
                   6132:        movl    r6,lstpf        # nothing for listr yet
                   6133:        movl    $iniln,r6       # input image length
                   6134:        movl    r6,cswin        # -in72
                   6135:        movl    $b$kvt,dmpkb    # dump
                   6136:        movl    $trbkv,dmpkt    # dump
                   6137:        movl    $p$len,evlin    # eval
                   6138:        #page   
                   6139:        movl    $nulls,r6       # get nullstring pointer
                   6140:        movl    r6,kvrtn        # return
                   6141:        movl    r6,r$etx        # errtext
                   6142:        movl    r6,r$ttl        # title for listing
                   6143:        movl    r6,stxvr        # setexit
                   6144:        movl    r5,timsx        # store time in correct place
                   6145:        movl    stlim,r5        # get default stlimit
                   6146:        movl    r5,kvstl        # statement limit
                   6147:        movl    r5,kvstc        # statement count
                   6148:        movl    r7,statb        # store start adrs of static
                   6149:        movl    $4*e$srs,rsmem  # reserve memory
                   6150:        movl    sp,stbas        # store stack base
                   6151:        #sss    iniss           # save s-r stack ptr
                   6152: #
                   6153: #      NOW CONVERT FREE STORE PERCENTAGE TO A SUITABLE FACTOR
                   6154: #      FOR EASY TESTING IN ALLOC ROUTINE.
                   6155: #
                   6156:        movl    intvh,r5        # get 100
                   6157:        divl2   alfsp,r5        # form 100 / alfsp
                   6158:        movl    r5,alfsf        # store the factor
                   6159: #
                   6160: #      INITIALIZE VALUES FOR REAL CONVERSION ROUTINE
                   6161: #
                   6162:        movl    $cfp$s,r7       # load counter for significant digits
                   6163:        movf    reav1,r2        # load 1.0
                   6164: #
                   6165: #      LOOP TO COMPUTE 10**(MAX NUMBER SIGNIFICANT DIGITS)
                   6166: #
                   6167: ini03: mulf2   reavt,r2        # * 10.0
                   6168:        sobgtr  r7,ini03        # loop till done
                   6169:        movf    r2,gtssc        # store 10**(max sig digits)
                   6170:        movf    reap5,r2        # load 0.5
                   6171:        divf2   gtssc,r2        # compute 0.5*10**(max sig digits)
                   6172:        movf    r2,gtsrn        # store as rounding bias
                   6173:        clrl    r8              # set to read parameters
                   6174:        jsb     prpar           # read them
                   6175:        #page   
                   6176: #
                   6177: #      NOW COMPUTE STARTING ADDRESS FOR DYNAMIC STORE AND IF
                   6178: #      NECESSARY REQUEST MORE MEMORY.
                   6179: #
                   6180:        subl2   $4*e$srs,r10    # allow for reserve memory
                   6181:        movl    prlen,r6        # get print buffer length
                   6182:        addl2   $cfp$a,r6       # add no. of chars in alphabet
                   6183:        addl2   $nstmx,r6       # add chars for gtstg bfr
                   6184:        movab   3+(4*8)(r6),r6  # convert to bytes, allowing a margin
                   6185:        bicl2   $3,r6
                   6186:        movl    statb,r9        # point to static base
                   6187:        addl2   r6,r9           # increment for above buffers
                   6188:        addl2   $4*e$hnb,r9     # increment for hash table
                   6189:        addl2   $4*e$sts,r9     # bump for initial static block
                   6190:        jsb     sysmx           # get mxlen
                   6191:        movl    r6,kvmxl        # provisionally store as maxlngth
                   6192:        movl    r6,mxlen        # and as mxlen
                   6193:        cmpl    r9,r6           # skip if static hi exceeds mxlen
                   6194:        bgtru   ini06
                   6195:        movl    r6,r9           # use mxlen instead
                   6196:        addl2   $4,r9           # make bigger than mxlen
                   6197: #
                   6198: #      HERE TO STORE VALUES WHICH MARK INITIAL DIVISION
                   6199: #      OF DATA AREA INTO STATIC AND DYNAMIC
                   6200: #
                   6201: ini06: movl    r9,dnamb        # dynamic base adrs
                   6202:        movl    r9,dnamp        # dynamic ptr
                   6203:        tstl    r6              # skip if non-zero mxlen
                   6204:        bnequ   ini07
                   6205:        subl2   $4,r9           # point a word in front
                   6206:        movl    r9,kvmxl        # use as maxlngth
                   6207:        movl    r9,mxlen        # and as mxlen
                   6208:        #page   
                   6209: #
                   6210: #      LOOP HERE IF NECESSARY TILL ENOUGH MEMORY OBTAINED
                   6211: #      SO THAT DNAME IS ABOVE DNAMB
                   6212: #
                   6213: ini07: movl    r10,dname       # store dynamic end address
                   6214:        cmpl    dnamb,r10       # skip if high enough
                   6215:        blssu   ini09
                   6216:        jsb     sysmm           # request more memory
                   6217:        moval   0[r9],r9        # get as baus (sgd05)
                   6218:        addl2   r9,r10          # bump by amount obtained
                   6219:        tstl    r9              # try again
                   6220:        bnequ   ini07
                   6221:        movl    $endmo,r9       # point to failure message
                   6222:        movl    endml,r6        # message length
                   6223:        jsb     syspr           # print it (prtst not yet usable)
                   6224:        .long   invalid$        # should not fail
                   6225:        jsb     sysej           # pack up (stopr not yet usable)
                   6226: #
                   6227: #      INITIALISE PRINT BUFFER WITH BLANK WORDS
                   6228: #
                   6229: ini09: movl    prlen,r8        # no. of chars in print bfr
                   6230:        movl    statb,r9        # point to static again
                   6231:        movl    r9,prbuf        # print bfr is put at static start
                   6232:        movl    $b$scl,(r9)+    # store string type code
                   6233:        movl    r8,(r9)+        # and string length
                   6234:        movab   3+(4*0)(r8),r8  # get number of words in buffer
                   6235:        ashl    $-2,r8,r8
                   6236:        movl    r8,prlnw        # store for buffer clear
                   6237:                                # words to clear
                   6238: #
                   6239: #      LOOP TO CLEAR BUFFER
                   6240: #
                   6241: ini10: movl    nullw,(r9)+     # store blank
                   6242:        sobgtr  r8,ini10        # loop
                   6243: #
                   6244: #      INITIALIZE NUMBER OF HASH HEADERS
                   6245: #
                   6246:        movl    $e$hnb,r6       # get number of hash headers
                   6247:        movl    r6,r5           # convert to integer
                   6248:        movl    r5,hshnb        # store for use by gtnvr procedure
                   6249:                                # counter for clearing hash table
                   6250:        movl    r9,hshtb        # pointer to hash table
                   6251: #
                   6252: #      LOOP TO CLEAR HASH TABLE
                   6253: #
                   6254: ini11: clrl    (r9)+           # blank a word
                   6255:        sobgtr  r6,ini11        # loop
                   6256:        movl    r9,hshte        # end of hash table adrs is kept
                   6257: #
                   6258: #      ALLOCATE WORK AREA FOR GTSTG CONVERSION PROCEDURE
                   6259: #
                   6260:        movl    $nstmx,r6       # get max num chars in output number
                   6261:        movab   3+(4*scsi$)(r6),r6 # no of bytes needed
                   6262:        bicl2   $3,r6
                   6263:        movl    r9,gtswk        # store bfr adrs
                   6264:        addl2   r6,r9           # bump for work bfr
                   6265:        #page   
                   6266: #
                   6267: #      BUILD ALPHABET STRING FOR ALPHABET KEYWORD AND REPLACE
                   6268: #
                   6269:        movl    r9,kvalp        # save alphabet pointer
                   6270:        movl    $b$scl,(r9)     # string blk type
                   6271:        movl    $cfp$a,r8       # no of chars in alphabet
                   6272:        movl    r8,4*sclen(r9)  # store as string length
                   6273:        movl    r8,r7           # copy char count
                   6274:        movab   3+(4*scsi$)(r7),r7 # no. of bytes needed
                   6275:        bicl2   $3,r7
                   6276:        addl2   r9,r7           # current end address for static
                   6277:        movl    r7,state        # store static end adrs
                   6278:                                # loop counter
                   6279:        movab   cfp$f(r9),r9    # point to chars of string
                   6280:        clrl    r7              # set initial character value
                   6281: #
                   6282: #      LOOP TO ENTER CHARACTER CODES IN ORDER
                   6283: #
                   6284: ini12: movb    r7,(r9)+        # store next code
                   6285:        incl    r7              # bump code value
                   6286:        sobgtr  r8,ini12        # loop till all stored
                   6287:        #csc    r9              # complete store characters
                   6288: #
                   6289: #      INITIALIZE VARIABLE BLOCKS FOR INPUT AND OUTPUT
                   6290: #
                   6291:        movl    $v$inp,r10      # point to string /input/
                   6292:        movl    $trtin,r7       # trblk type for input
                   6293:        jsb     inout           # perform input association
                   6294:        movl    $v$oup,r10      # point to string /output/
                   6295:        movl    $trtou,r7       # trblk type for output
                   6296:        jsb     inout           # perform output association
                   6297:        movl    initr,r8        # terminal flag
                   6298:        tstl    r8              # skip if no terminal
                   6299:        beqlu   ini13
                   6300:        jsb     prpar           # associate terminal
                   6301:        #page   
                   6302: #
                   6303: #      CHECK FOR EXPIRY DATE
                   6304: #
                   6305: ini13: jsb     sysdc           # call date check
                   6306:        movl    sp,flptr        # in case stack overflows in compiler
                   6307: #
                   6308: #      NOW COMPILE SOURCE INPUT CODE
                   6309: #
                   6310:        jsb     cmpil           # call compiler
                   6311:        movl    r9,r$cod        # set ptr to first code block
                   6312:        movl    $nulls,r$ttl    # forget title      (reg04)
                   6313:        movl    $nulls,r$stl    # forget sub-title  (reg04)
                   6314:        clrl    r$cim           # forget compiler input image
                   6315:        clrl    r10             # clear dud value
                   6316:        clrl    r7              # dont shift dynamic store up
                   6317:        jsb     gbcol           # clear garbage left from compile
                   6318:        tstl    cpsts           # skip if no listing of comp stats
                   6319:        beqlu   0f
                   6320:        jmp     inix0
                   6321: 0:             
                   6322:        jsb     prtpg           # eject page
                   6323: #
                   6324: #      PRINT COMPILE STATISTICS
                   6325: #
                   6326:        movl    dnamp,r6        # next available loc
                   6327:        subl2   statb,r6        # minus start
                   6328:        ashl    $-2,r6,r6       # convert to words
                   6329:        movl    r6,r5           # convert to integer
                   6330:        movl    $encm1,r9       # point to /memory used (words)/
                   6331:        jsb     prtmi           # print message
                   6332:        movl    dname,r6        # end of memory
                   6333:        subl2   dnamp,r6        # minus next available loc
                   6334:        ashl    $-2,r6,r6       # convert to words
                   6335:        movl    r6,r5           # convert to integer
                   6336:        movl    $encm2,r9       # point to /memory available (words)/
                   6337:        jsb     prtmi           # print line
                   6338:        movl    cmerc,r5        # get count of errors as integer
                   6339:        movl    $encm3,r9       # point to /compile errors/
                   6340:        jsb     prtmi           # print it
                   6341:        movl    gbcnt,r5        # garbage collection count
                   6342:        subl2   intv1,r5        # adjust for unavoidable collect
                   6343:        movl    $stpm5,r9       # point to /storage regenerations/
                   6344:        jsb     prtmi           # print gbcol count
                   6345:        jsb     systm           # get time
                   6346:        subl2   timsx,r5        # get compilation time
                   6347:        movl    $encm4,r9       # point to compilation time (msec)/
                   6348:        jsb     prtmi           # print message
                   6349:        addl2   $num05,lstlc    # bump line count
                   6350:        tstl    headp           # no eject if nothing printed (sdg11)
                   6351:        bnequ   0f
                   6352:        jmp     inix0
                   6353: 0:             
                   6354:        jsb     prtpg           # eject printer
                   6355:        #page   
                   6356: #
                   6357: #      PREPARE NOW TO START EXECUTION
                   6358: #
                   6359: #      SET DEFAULT INPUT RECORD LENGTH
                   6360: #
                   6361: inix0: cmpl    cswin,$iniln    # skip if not default -in72 used
                   6362:        bgtru   inix1
                   6363:        movl    $inils,cswin    # else use default record length
                   6364: #
                   6365: #      RESET TIMER
                   6366: #
                   6367: inix1: jsb     systm           # get time again
                   6368:        movl    r5,timsx        # store for end run processing
                   6369:        addl2   cswex,noxeq     # add -noexecute flag
                   6370:        tstl    noxeq           # jump if execution suppressed
                   6371:        bnequ   inix2
                   6372:        clrl    gbcnt           # initialise collect count
                   6373:        jsb     sysbx           # call before starting execution
                   6374: #
                   6375: #      MERGE WHEN LISTING FILE SET FOR EXECUTION
                   6376: #
                   6377: iniy0: movl    sp,headp        # mark headers out regardless
                   6378:        clrl    -(sp)           # set failure location on stack
                   6379:        movl    sp,flptr        # save ptr to failure offset word
                   6380:        movl    r$cod,r9        # load ptr to entry code block
                   6381:        movl    $stgxt,stage    # set stage for execute time
                   6382:        movl    cmpsn,pfnte     # copy stmts compiled count in case
                   6383:        jsb     systm           # time yet again
                   6384:        movl    r5,pfstm
                   6385:        movl    (r9),r11        # start xeq with first statement
                   6386:        jmp     (r11)
                   6387: #
                   6388: #      HERE IF EXECUTION IS SUPPRESSED
                   6389: #
                   6390: inix2: jsb     prtnl           # print a blank line
                   6391:        movl    $encm5,r9       # point to /execution suppressed/
                   6392:        jsb     prtst           # print string
                   6393:        jsb     prtnl           # output line
                   6394:        clrl    r6              # set abend value to zero
                   6395:        movl    $nini9,r7       # set special code value
                   6396:        jsb     sysej           # end of job, exit to system
                   6397:        #title  s p i t b o l -- snobol4 operator routines
                   6398: #
                   6399: #      THIS SECTION INCLUDES ALL ROUTINES WHICH CAN BE ACCESSED
                   6400: #      DIRECTLY FROM THE GENERATED CODE EXCEPT SYSTEM FUNCTIONS.
                   6401: #
                   6402: #      ALL ROUTINES IN THIS SECTION START WITH A LABEL OF THE
                   6403: #      FORM O$XXX WHERE XXX IS THREE LETTERS. THE GENERATED CODE
                   6404: #      CONTAINS A POINTER TO THE APPROPRIATE ENTRY LABEL.
                   6405: #
                   6406: #      SINCE THE GENERAL FORM OF THE GENERATED CODE CONSISTS OF
                   6407: #      POINTERS TO BLOCKS WHOSE FIRST WORD IS THE ADDRESS OF THE
                   6408: #      ACTUAL ENTRY POINT LABEL (O$XXX).
                   6409: #
                   6410: #      THESE ROUTINES ARE IN ALPHABETICAL ORDER BY THEIR
                   6411: #      ENTRY LABEL NAMES (I.E. BY THE XXX OF THE O$XXX NAME)
                   6412: #
                   6413: #      THESE ROUTINES RECEIVE CONTROL AS FOLLOWS
                   6414: #
                   6415: #      (CP)                  POINTER TO NEXT CODE WORD
                   6416: #      (XS)                  CURRENT STACK POINTER
                   6417:        #page   
                   6418: #
                   6419: #      BINARY PLUS (ADDITION)
                   6420: #
                   6421: o$add:                         # entry point
                   6422:        jsb     arith           # fetch arithmetic operands
                   6423:        .long   er_001          # addition left operand is not numeric
                   6424:        .long   er_002          # addition right operand is not numeric
                   6425:        .long   oadd1           # jump if real operands
                   6426: #
                   6427: #      HERE TO ADD TWO INTEGERS
                   6428: #
                   6429:        addl2   4*icval(r10),r5 # add right operand to left
                   6430:        bvs     0f
                   6431:        jmp     exint
                   6432: 0:             
                   6433:        jmp     er_003          # addition caused integer overflow
                   6434: #
                   6435: #      HERE TO ADD TWO REALS
                   6436: #
                   6437: oadd1: addf2   4*rcval(r10),r2 # add right operand to left
                   6438:        bvs     0f
                   6439:        jmp     exrea
                   6440: 0:             
                   6441:        jmp     er_261          # addition caused real overflow
                   6442:        #page   
                   6443: #
                   6444: #      UNARY PLUS (AFFIRMATION)
                   6445: #
                   6446: o$aff:                         # entry point
                   6447:        movl    (sp)+,r9        # load operand
                   6448:        jsb     gtnum           # convert to numeric
                   6449:        .long   er_004          # affirmation operand is not numeric
                   6450:        jmp     exixr           # return if converted to numeric
                   6451:        #page   
                   6452: #
                   6453: #      BINARY BAR (ALTERNATION)
                   6454: #
                   6455: o$alt:                         # entry point
                   6456:        movl    (sp)+,r9        # load right operand
                   6457:        jsb     gtpat           # convert to pattern
                   6458:        .long   er_005          # alternation right operand is not pattern
                   6459: #
                   6460: #      MERGE HERE FROM SPECIAL (LEFT ALTERNATION) CASE
                   6461: #
                   6462: oalt1: movl    $p$alt,r7       # set pcode for alternative node
                   6463:        jsb     pbild           # build alternative node
                   6464:        movl    r9,r10          # save address of alternative node
                   6465:        movl    (sp)+,r9        # load left operand
                   6466:        jsb     gtpat           # convert to pattern
                   6467:        .long   er_006          # alternation left operand is not pattern
                   6468:        cmpl    r9,$p$alt       # jump if left arg is alternation
                   6469:        beqlu   oalt2
                   6470:        movl    r9,4*pthen(r10) # set left operand as successor
                   6471:        movl    r10,r9          # move result to proper register
                   6472:        jmp     exixr           # jump for next code word
                   6473: #
                   6474: #      COME HERE IF LEFT ARGUMENT IS ITSELF AN ALTERNATION
                   6475: #
                   6476: #      THE RESULT IS MORE EFFICIENT IF WE MAKE THE REPLACEMENT
                   6477: #
                   6478: #      (A / B) / C = A / (B / C)
                   6479: #
                   6480: oalt2: movl    4*parm1(r9),4*pthen(r10) # build the (b / c) node
                   6481:        movl    4*pthen(r9),-(sp)# set a as new left arg
                   6482:        movl    r10,r9          # set (b / c) as new right arg
                   6483:        jmp     oalt1           # merge back to build a / (b / c)
                   6484:        #page   
                   6485: #
                   6486: #      ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY NAME)
                   6487: #
                   6488: o$amn:                         # entry point
                   6489:        movl    (r3)+,r9        # load number of subscripts
                   6490:        movl    r9,r7           # set flag for by name
                   6491:        jmp     arref           # jump to array reference routine
                   6492:        #page   
                   6493: #
                   6494: #      ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY VALUE)
                   6495: #
                   6496: o$amv:                         # entry point
                   6497:        movl    (r3)+,r9        # load number of subscripts
                   6498:        clrl    r7              # set flag for by value
                   6499:        jmp     arref           # jump to array reference routine
                   6500:        #page   
                   6501: #
                   6502: #      ARRAY REFERENCE (ONE SUBSCRIPT, BY NAME)
                   6503: #
                   6504: o$aon:                         # entry point
                   6505:        movl    (sp),r9         # load subscript value
                   6506:        movl    4*1(sp),r10     # load array value
                   6507:        movl    (r10),r6        # load first word of array operand
                   6508:        cmpl    r6,$b$vct       # jump if vector reference
                   6509:        beqlu   oaon2
                   6510:        cmpl    r6,$b$tbt       # jump if table reference
                   6511:        beqlu   oaon3
                   6512: #
                   6513: #      HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE
                   6514: #
                   6515: oaon1: movl    $num01,r9       # set number of subscripts to one
                   6516:        movl    r9,r7           # set flag for by name
                   6517:        jmp     arref           # jump to array reference routine
                   6518: #
                   6519: #      HERE IF WE HAVE A VECTOR REFERENCE
                   6520: #
                   6521: oaon2: cmpl    (r9),$b$icl     # use long routine if not integer
                   6522:        bnequ   oaon1
                   6523:        movl    4*icval(r9),r5  # load integer subscript value
                   6524:        movl    r5,r6           # copy as address int, fail if ovflo
                   6525:        bgeq    0f
                   6526:        jmp     exfal
                   6527: 0:             
                   6528:        tstl    r6              # fail if zero
                   6529:        bnequ   0f
                   6530:        jmp     exfal
                   6531: 0:             
                   6532:        addl2   $vcvlb,r6       # compute offset in words
                   6533:        moval   0[r6],r6        # convert to bytes
                   6534:        movl    r6,(sp)         # complete name on stack
                   6535:        cmpl    r6,4*vclen(r10) # exit if subscript not too large
                   6536:        bgequ   0f
                   6537:        jmp     exits
                   6538: 0:             
                   6539:        jmp     exfal           # else fail
                   6540: #
                   6541: #      HERE FOR TABLE REFERENCE
                   6542: #
                   6543: oaon3: movl    sp,r7           # set flag for name reference
                   6544:        jsb     tfind           # locate/create table element
                   6545:        .long   exfal           # fail if access fails
                   6546:        movl    r10,4*1(sp)     # store name base on stack
                   6547:        movl    r6,(sp)         # store name offset on stack
                   6548:        jmp     exits           # exit with result on stack
                   6549:        #page   
                   6550: #
                   6551: #      ARRAY REFERENCE (ONE SUBSCRIPT, BY VALUE)
                   6552: #
                   6553: o$aov:                         # entry point
                   6554:        movl    (sp)+,r9        # load subscript value
                   6555:        movl    (sp)+,r10       # load array value
                   6556:        movl    (r10),r6        # load first word of array operand
                   6557:        cmpl    r6,$b$vct       # jump if vector reference
                   6558:        beqlu   oaov2
                   6559:        cmpl    r6,$b$tbt       # jump if table reference
                   6560:        beqlu   oaov3
                   6561: #
                   6562: #      HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE
                   6563: #
                   6564: oaov1: movl    r10,-(sp)       # restack array value
                   6565:        movl    r9,-(sp)        # restack subscript
                   6566:        movl    $num01,r9       # set number of subscripts to one
                   6567:        clrl    r7              # set flag for value call
                   6568:        jmp     arref           # jump to array reference routine
                   6569: #
                   6570: #      HERE IF WE HAVE A VECTOR REFERENCE
                   6571: #
                   6572: oaov2: cmpl    (r9),$b$icl     # use long routine if not integer
                   6573:        bnequ   oaov1
                   6574:        movl    4*icval(r9),r5  # load integer subscript value
                   6575:        movl    r5,r6           # move as one word int, fail if ovflo
                   6576:        bgeq    0f
                   6577:        jmp     exfal
                   6578: 0:             
                   6579:        tstl    r6              # fail if zero
                   6580:        bnequ   0f
                   6581:        jmp     exfal
                   6582: 0:             
                   6583:        addl2   $vcvlb,r6       # compute offset in words
                   6584:        moval   0[r6],r6        # convert to bytes
                   6585:        cmpl    r6,4*vclen(r10) # fail if subscript too large
                   6586:        blssu   0f
                   6587:        jmp     exfal
                   6588: 0:             
                   6589:        jsb     acess           # access value
                   6590:        .long   exfal           # fail if access fails
                   6591:        jmp     exixr           # else return value to caller
                   6592: #
                   6593: #      HERE FOR TABLE REFERENCE BY VALUE
                   6594: #
                   6595: oaov3: clrl    r7              # set flag for value reference
                   6596:        jsb     tfind           # call table search routine
                   6597:        .long   exfal           # fail if access fails
                   6598:        jmp     exixr           # exit with result in xr
                   6599:        #page   
                   6600: #
                   6601: #      ASSIGNMENT
                   6602: #
                   6603: o$ass:                         # entry point
                   6604: #
                   6605: #      O$RPL (PATTERN REPLACEMENT) MERGES HERE
                   6606: #
                   6607: oass0: movl    (sp)+,r7        # load value to be assigned
                   6608:        movl    (sp)+,r6        # load name offset
                   6609:        movl    (sp),r10        # load name base
                   6610:        movl    r7,(sp)         # store assigned value as result
                   6611:        jsb     asign           # perform assignment
                   6612:        .long   exfal           # fail if assignment fails
                   6613:        jmp     exits           # exit with result on stack
                   6614:        #page   
                   6615: #
                   6616: #      COMPILATION ERROR
                   6617: #
                   6618: o$cer:                         # entry point
                   6619:        jmp     er_007          # compilation error encountered during execution
                   6620:        #page   
                   6621: #
                   6622: #      UNARY AT (CURSOR ASSIGNMENT)
                   6623: #
                   6624: o$cas:                         # entry point
                   6625:        movl    (sp)+,r8        # load name offset (parm2)
                   6626:        movl    (sp)+,r9        # load name base (parm1)
                   6627:        movl    $p$cas,r7       # set pcode for cursor assignment
                   6628:        jsb     pbild           # build node
                   6629:        jmp     exixr           # jump for next code word
                   6630:        #page   
                   6631: #
                   6632: #      CONCATENATION
                   6633: #
                   6634: o$cnc:                         # entry point
                   6635:        movl    (sp),r9         # load right argument
                   6636:        cmpl    r9,$nulls       # jump if right arg is null
                   6637:        bnequ   0f
                   6638:        jmp     ocnc3
                   6639: 0:             
                   6640:        movl    4*1(sp),r10     # load left argument
                   6641:        cmpl    r10,$nulls      # jump if left argument is null
                   6642:        bnequ   0f
                   6643:        jmp     ocnc4
                   6644: 0:             
                   6645:        movl    $b$scl,r6       # get constant to test for string
                   6646:        cmpl    r6,(r10)        # jump if left arg not a string
                   6647:        beqlu   0f
                   6648:        jmp     ocnc2
                   6649: 0:             
                   6650:        cmpl    r6,(r9)         # jump if right arg not a string
                   6651:        beqlu   0f
                   6652:        jmp     ocnc2
                   6653: 0:             
                   6654: #
                   6655: #      MERGE HERE TO CONCATENATE TWO STRINGS
                   6656: #
                   6657: ocnc1: movl    4*sclen(r10),r6 # load left argument length
                   6658:        addl2   4*sclen(r9),r6  # compute result length
                   6659:        jsb     alocs           # allocate scblk for result
                   6660:        movl    r9,4*1(sp)      # store result ptr over left argument
                   6661:        movab   cfp$f(r9),r9    # prepare to store chars of result
                   6662:        movl    4*sclen(r10),r6 # get number of chars in left arg
                   6663:        movab   cfp$f(r10),r10  # prepare to load left arg chars
                   6664:        jsb     sbmvc           # move characters of left argument
                   6665:        movl    (sp)+,r10       # load right arg pointer, pop stack
                   6666:        movl    4*sclen(r10),r6 # load number of chars in right arg
                   6667:        movab   cfp$f(r10),r10  # prepare to load right arg chars
                   6668:        jsb     sbmvc           # move characters of right argument
                   6669:        jmp     exits           # exit with result on stack
                   6670: #
                   6671: #      COME HERE IF ARGUMENTS ARE NOT BOTH STRINGS
                   6672: #
                   6673: ocnc2: jsb     gtstg           # convert right arg to string
                   6674:        .long   ocnc5           # jump if right arg is not string
                   6675:        movl    r9,r10          # save right arg ptr
                   6676:        jsb     gtstg           # convert left arg to string
                   6677:        .long   ocnc6           # jump if left arg is not a string
                   6678:        movl    r9,-(sp)        # stack left argument
                   6679:        movl    r10,-(sp)       # stack right argument
                   6680:        movl    r9,r10          # move left arg to proper reg
                   6681:        movl    (sp),r9         # move right arg to proper reg
                   6682:        jmp     ocnc1           # merge back to concatenate strings
                   6683:        #page   
                   6684: #
                   6685: #      CONCATENATION (CONTINUED)
                   6686: #
                   6687: #      COME HERE FOR NULL RIGHT ARGUMENT
                   6688: #
                   6689: ocnc3: addl2   $4,sp           # remove right arg from stack
                   6690:        jmp     exits           # return with left argument on stack
                   6691: #
                   6692: #      HERE FOR NULL LEFT ARGUMENT
                   6693: #
                   6694: ocnc4: addl2   $4,sp           # unstack one argument
                   6695:        movl    r9,(sp)         # store right argument
                   6696:        jmp     exits           # exit with result on stack
                   6697: #
                   6698: #      HERE IF RIGHT ARGUMENT IS NOT A STRING
                   6699: #
                   6700: ocnc5: movl    r9,r10          # move right argument ptr
                   6701:        movl    (sp)+,r9        # load left arg pointer
                   6702: #
                   6703: #      MERGE HERE WHEN LEFT ARGUMENT IS NOT A STRING
                   6704: #
                   6705: ocnc6: jsb     gtpat           # convert left arg to pattern
                   6706:        .long   er_008          # concatenation left opnd is not string or pattern
                   6707:        movl    r9,-(sp)        # save result on stack
                   6708:        movl    r10,r9          # point to right operand
                   6709:        jsb     gtpat           # convert to pattern
                   6710:        .long   er_009          # concatenation right opd is not string or pattern
                   6711:        movl    r9,r10          # move for pconc
                   6712:        movl    (sp)+,r9        # reload left operand ptr
                   6713:        jsb     pconc           # concatenate patterns
                   6714:        jmp     exixr           # exit with result in xr
                   6715:        #page   
                   6716: #
                   6717: #      COMPLEMENTATION
                   6718: #
                   6719: o$com:                         # entry point
                   6720:        movl    (sp)+,r9        # load operand
                   6721:        movl    (r9),r6         # load type word
                   6722: #
                   6723: #      MERGE BACK HERE AFTER CONVERSION
                   6724: #
                   6725: ocom1: cmpl    r6,$b$icl       # jump if integer
                   6726:        beqlu   ocom2
                   6727:        cmpl    r6,$b$rcl       # jump if real
                   6728:        beqlu   ocom3
                   6729:        jsb     gtnum           # else convert to numeric
                   6730:        .long   er_010          # complementation operand is not numeric
                   6731:        jmp     ocom1           # back to check cases
                   6732: #
                   6733: #      HERE TO COMPLEMENT INTEGER
                   6734: #
                   6735: ocom2: movl    4*icval(r9),r5  # load integer value
                   6736:        mnegl   r5,r5           # negate
                   6737:        bvs     0f
                   6738:        jmp     exint
                   6739: 0:             
                   6740:        jmp     er_011          # complementation caused integer overflow
                   6741: #
                   6742: #      HERE TO COMPLEMENT REAL
                   6743: #
                   6744: ocom3: movf    4*rcval(r9),r2  # load real value
                   6745:        mnegf   r2,r2           # negate
                   6746:        jmp     exrea           # return real result
                   6747:        #page   
                   6748: #
                   6749: #      BINARY SLASH (DIVISION)
                   6750: #
                   6751: o$dvd:                         # entry point
                   6752:        jsb     arith           # fetch arithmetic operands
                   6753:        .long   er_012          # division left operand is not numeric
                   6754:        .long   er_013          # division right operand is not numeric
                   6755:        .long   odvd2           # jump if real operands
                   6756: #
                   6757: #      HERE TO DIVIDE TWO INTEGERS
                   6758: #
                   6759:        divl2   4*icval(r10),r5 # divide left operand by right
                   6760:        bvs     0f
                   6761:        jmp     exint
                   6762: 0:             
                   6763:        jmp     er_014          # division caused integer overflow
                   6764: #
                   6765: #      HERE TO DIVIDE TWO REALS
                   6766: #
                   6767: odvd2: divf2   4*rcval(r10),r2 # divide left operand by right
                   6768:        bvs     0f
                   6769:        jmp     exrea
                   6770: 0:             
                   6771:        jmp     er_262          # division caused real overflow
                   6772:        #page   
                   6773: #
                   6774: #      EXPONENTIATION
                   6775: #
                   6776: o$exp:                         # entry point
                   6777:        movl    (sp)+,r9        # load exponent
                   6778:        jsb     gtnum           # convert to number
                   6779:        .long   er_015          # exponentiation right operand is not numeric
                   6780:        cmpl    r6,$b$icl       # jump if real
                   6781:        beqlu   0f
                   6782:        jmp     oexp7
                   6783: 0:             
                   6784:        movl    r9,r10          # move exponent
                   6785:        movl    (sp)+,r9        # load base
                   6786:        jsb     gtnum           # convert to numeric
                   6787:        .long   er_016          # exponentiation left operand is not numeric
                   6788:        movl    4*icval(r10),r5 # load exponent
                   6789:        tstl    r5              # error if negative exponent
                   6790:        bgeq    0f
                   6791:        jmp     oexp8
                   6792: 0:             
                   6793:        cmpl    r6,$b$rcl       # jump if base is real
                   6794:        beqlu   oexp3
                   6795: #
                   6796: #      HERE TO EXPONENTIATE AN INTEGER
                   6797: #
                   6798:        movl    r5,r6           # convert exponent to 1 word integer
                   6799:        bgeq    0f
                   6800:        jmp     oexp2
                   6801: 0:             
                   6802:                                # set loop counter
                   6803:        movl    intv1,r5        # load initial value of 1
                   6804:        tstl    r6              # jump if non-zero exponent
                   6805:        bnequ   oexp1
                   6806:        tstl    r5              # give zero as result for nonzero**0
                   6807:        beql    0f
                   6808:        jmp     exint
                   6809: 0:             
                   6810:        jmp     oexp4           # else error of 0**0
                   6811: #
                   6812: #      LOOP TO PERFORM EXPONENTIATION
                   6813: #
                   6814: oexp1: mull2   4*icval(r9),r5  # multiply by base
                   6815:        bvs     oexp2
                   6816:        sobgtr  r6,oexp1        # loop back till computation complete
                   6817:        jmp     exint           # then return integer result
                   6818: #
                   6819: #      HERE IF INTEGER OVERFLOW
                   6820: #
                   6821: oexp2: jmp     er_017          # exponentiation caused integer overflow
                   6822:        #page   
                   6823: #
                   6824: #      EXPONENTIATION (CONTINUED)
                   6825: #
                   6826: #      HERE TO EXPONENTIATE A REAL
                   6827: #
                   6828: oexp3: movl    r5,r6           # convert exponent to one word
                   6829:        bgeq    0f
                   6830:        jmp     oexp6
                   6831: 0:             
                   6832:                                # set loop counter
                   6833:        movf    reav1,r2        # load 1.0 as initial value
                   6834:        tstl    r6              # jump if non-zero exponent
                   6835:        bnequ   oexp5
                   6836:        tstf    r2              # return 1.0 if nonzero**zero
                   6837:        beql    0f
                   6838:        jmp     exrea
                   6839: 0:             
                   6840: #
                   6841: #      HERE FOR ERROR OF 0**0 OR 0.0**0
                   6842: #
                   6843: oexp4: jmp     er_018          # exponentiation result is undefined
                   6844: #
                   6845: #      LOOP TO PERFORM EXPONENTIATION
                   6846: #
                   6847: oexp5: mulf2   4*rcval(r9),r2  # multiply by base
                   6848:        bvs     oexp6
                   6849:        sobgtr  r6,oexp5        # loop till computation complete
                   6850:        jmp     exrea           # then return real result
                   6851: #
                   6852: #      HERE IF REAL OVERFLOW
                   6853: #
                   6854: oexp6: jmp     er_266          # exponentiation caused real overflow
                   6855: #
                   6856: #      HERE IF REAL EXPONENT
                   6857: #
                   6858: oexp7: jmp     er_267          # exponentiation right operand is real not integer
                   6859: #
                   6860: #      HERE FOR NEGATIVE EXPONENT
                   6861: #
                   6862: oexp8: jmp     er_019          # exponentiation right operand is negative
                   6863:        #page   
                   6864: #
                   6865: #      FAILURE IN EXPRESSION EVALUATION
                   6866: #
                   6867: #      THIS ENTRY POINT IS USED IF THE EVALUATION OF AN
                   6868: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, FAILS.
                   6869: #      CONTROL IS RETURNED TO AN APPROPRIATE POINT IN EVALX.
                   6870: #
                   6871: o$fex:                         # entry point
                   6872:        jmp     evlx6           # jump to failure loc in evalx
                   6873:        #page   
                   6874: #
                   6875: #      FAILURE DURING EVALUATION OF A COMPLEX OR DIRECT GOTO
                   6876: #
                   6877: o$fif:                         # entry point
                   6878:        jmp     er_020          # goto evaluation failure
                   6879:        #page   
                   6880: #
                   6881: #      FUNCTION CALL (MORE THAN ONE ARGUMENT)
                   6882: #
                   6883: o$fnc:                         # entry point
                   6884:        movl    (r3)+,r6        # load number of arguments
                   6885:        movl    (r3)+,r9        # load function vrblk pointer
                   6886:        movl    4*vrfnc(r9),r10 # load function pointer
                   6887:        cmpl    r6,4*fargs(r10) # use central routine if wrong num
                   6888:        beqlu   0f
                   6889:        jmp     cfunc
                   6890: 0:             
                   6891:        movl    (r10),r11       # jump to function if arg count ok
                   6892:        jmp     (r11)
                   6893:        #page   
                   6894: #
                   6895: #      FUNCTION NAME ERROR
                   6896: #
                   6897: o$fne:                         # entry point
                   6898:        movl    (r3)+,r6        # get next code word
                   6899:        cmpl    r6,$ornm$       # fail if not evaluating expression
                   6900:        bnequ   ofne1
                   6901:        tstl    4*2(sp) # ok if expr. was wanted by value
                   6902:        bnequ   0f
                   6903:        jmp     evlx3
                   6904: 0:             
                   6905: #
                   6906: #      HERE FOR ERROR
                   6907: #
                   6908: ofne1: jmp     er_021          # function called by name returned a value
                   6909:        #page   
                   6910: #
                   6911: #      FUNCTION CALL (SINGLE ARGUMENT)
                   6912: #
                   6913: o$fns:                         # entry point
                   6914:        movl    (r3)+,r9        # load function vrblk pointer
                   6915:        movl    $num01,r6       # set number of arguments to one
                   6916:        movl    4*vrfnc(r9),r10 # load function pointer
                   6917:        cmpl    r6,4*fargs(r10) # use central routine if wrong num
                   6918:        beqlu   0f
                   6919:        jmp     cfunc
                   6920: 0:             
                   6921:        movl    (r10),r11       # jump to function if arg count ok
                   6922:        jmp     (r11)
                   6923:        #page   
                   6924: #      CALL TO UNDEFINED FUNCTION
                   6925: #
                   6926: o$fun:                         # entry point
                   6927:        jmp     er_022          # undefined function called
                   6928:        #page   
                   6929: #
                   6930: #      EXECUTE COMPLEX GOTO
                   6931: #
                   6932: o$goc:                         # entry point
                   6933:        movl    4*1(sp),r9      # load name base pointer
                   6934:        cmpl    r9,state        # jump if not natural variable
                   6935:        bgequ   ogoc1
                   6936:        addl2   $4*vrtra,r9     # else point to vrtra field
                   6937:        movl    (r9),r11        # and jump through it
                   6938:        jmp     (r11)
                   6939: #
                   6940: #      HERE IF GOTO OPERAND IS NOT NATURAL VARIABLE
                   6941: #
                   6942: ogoc1: jmp     er_023          # goto operand is not a natural variable
                   6943:        #page   
                   6944: #
                   6945: #      EXECUTE DIRECT GOTO
                   6946: #
                   6947: o$god:                         # entry point
                   6948:        movl    (sp),r9         # load operand
                   6949:        movl    (r9),r6         # load first word
                   6950:        cmpl    r6,$b$cds       # jump if code block to code routine
                   6951:        bnequ   0f
                   6952:        jmp     bcds0
                   6953: 0:             
                   6954:        cmpl    r6,$b$cdc       # jump if code block to code routine
                   6955:        bnequ   0f
                   6956:        jmp     bcdc0
                   6957: 0:             
                   6958:        jmp     er_024          # goto operand in direct goto is not code
                   6959:        #page   
                   6960: #
                   6961: #      SET GOTO FAILURE TRAP
                   6962: #
                   6963: #      THIS ROUTINE IS EXECUTED AT THE START OF A COMPLEX OR
                   6964: #      DIRECT FAILURE GOTO TO TRAP A SUBSEQUENT FAIL (SEE EXFAL)
                   6965: #
                   6966: o$gof:                         # entry point
                   6967:        movl    flptr,r9        # point to fail offset on stack
                   6968:        addl2   $4,(r9)         # point failure to o$fif word
                   6969:        tstl    (r3)+           # point to next code word
                   6970:        jmp     exits           # exit to continue
                   6971:        #page   
                   6972: #
                   6973: #      BINARY DOLLAR (IMMEDIATE ASSIGNMENT)
                   6974: #
                   6975: #      THE PATTERN BUILT BY BINARY DOLLAR IS A COMPOUND PATTERN.
                   6976: #      SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR
                   6977: #      DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED.
                   6978: #
                   6979: o$ima:                         # entry point
                   6980:        movl    $p$imc,r7       # set pcode for last node
                   6981:        movl    (sp)+,r8        # pop name offset (parm2)
                   6982:        movl    (sp)+,r9        # pop name base (parm1)
                   6983:        jsb     pbild           # build p$imc node
                   6984:        movl    r9,r10          # save ptr to node
                   6985:        movl    (sp),r9         # load left argument
                   6986:        jsb     gtpat           # convert to pattern
                   6987:        .long   er_025          # immediate assignment left operand is not pattern
                   6988:        movl    r9,(sp)         # save ptr to left operand pattern
                   6989:        movl    $p$ima,r7       # set pcode for first node
                   6990:        jsb     pbild           # build p$ima node
                   6991:        movl    (sp)+,4*pthen(r9)# set left operand as p$ima successor
                   6992:        jsb     pconc           # concatenate to form final pattern
                   6993:        jmp     exixr           # all done
                   6994:        #page   
                   6995: #
                   6996: #      INDIRECTION (BY NAME)
                   6997: #
                   6998: o$inn:                         # entry point
                   6999:        movl    sp,r7           # set flag for result by name
                   7000:        jmp     indir           # jump to common routine
                   7001:        #page   
                   7002: #
                   7003: #      INTERROGATION
                   7004: #
                   7005: o$int:                         # entry point
                   7006:        movl    $nulls,(sp)     # replace operand with null
                   7007:        jmp     exits           # exit for next code word
                   7008:        #page   
                   7009: #
                   7010: #      INDIRECTION (BY VALUE)
                   7011: #
                   7012: o$inv:                         # entry point
                   7013:        clrl    r7              # set flag for by value
                   7014:        jmp     indir           # jump to common routine
                   7015:        #page   
                   7016: #
                   7017: #      KEYWORD REFERENCE (BY NAME)
                   7018: #
                   7019: o$kwn:                         # entry point
                   7020:        jsb     kwnam           # get keyword name
                   7021:        jmp     exnam           # exit with result name
                   7022:        #page   
                   7023: #
                   7024: #      KEYWORD REFERENCE (BY VALUE)
                   7025: #
                   7026: o$kwv:                         # entry point
                   7027:        jsb     kwnam           # get keyword name
                   7028:        movl    r9,dnamp        # delete kvblk
                   7029:        jsb     acess           # access value
                   7030:        .long   exnul           # dummy (unused) failure return
                   7031:        jmp     exixr           # jump with value in xr
                   7032:        #page   
                   7033: #
                   7034: #      LOAD EXPRESSION BY NAME
                   7035: #
                   7036: o$lex:                         # entry point
                   7037:        movl    $4*evsi$,r6     # set size of evblk
                   7038:        jsb     alloc           # allocate space for evblk
                   7039:        movl    $b$evt,(r9)     # set type word
                   7040:        movl    $trbev,4*evvar(r9) # set dummy trblk pointer
                   7041:        movl    (r3)+,r6        # load exblk pointer
                   7042:        movl    r6,4*evexp(r9)  # set exblk pointer
                   7043:        movl    r9,r10          # move name base to proper reg
                   7044:        movl    $4*evvar,r6     # set name offset = zero
                   7045:        jmp     exnam           # exit with name in (xl,wa)
                   7046:        #page   
                   7047: #
                   7048: #      LOAD PATTERN VALUE
                   7049: #
                   7050: o$lpt:                         # entry point
                   7051:        movl    (r3)+,r9        # load pattern pointer
                   7052:        jmp     exixr           # stack ptr and obey next code word
                   7053:        #page   
                   7054: #
                   7055: #      LOAD VARIABLE NAME
                   7056: #
                   7057: o$lvn:                         # entry point
                   7058:        movl    (r3)+,r6        # load vrblk pointer
                   7059:        movl    r6,-(sp)        # stack vrblk ptr (name base)
                   7060:        movl    $4*vrval,-(sp)  # stack name offset
                   7061:        jmp     exits           # exit with result on stack
                   7062:        #page   
                   7063: #
                   7064: #      BINARY ASTERISK (MULTIPLICATION)
                   7065: #
                   7066: o$mlt:                         # entry point
                   7067:        jsb     arith           # fetch arithmetic operands
                   7068:        .long   er_026          # multiplication left operand is not numeric
                   7069:        .long   er_027          # multiplication right operand is not numeric
                   7070:        .long   omlt1           # jump if real operands
                   7071: #
                   7072: #      HERE TO MULTIPLY TWO INTEGERS
                   7073: #
                   7074:        mull2   4*icval(r10),r5 # multiply left operand by right
                   7075:        bvs     0f
                   7076:        jmp     exint
                   7077: 0:             
                   7078:        jmp     er_028          # multiplication caused integer overflow
                   7079: #
                   7080: #      HERE TO MULTIPLY TWO REALS
                   7081: #
                   7082: omlt1: mulf2   4*rcval(r10),r2 # multiply left operand by right
                   7083:        bvs     0f
                   7084:        jmp     exrea
                   7085: 0:             
                   7086:        jmp     er_263          # multiplication caused real overflow
                   7087:        #page   
                   7088: #
                   7089: #      NAME REFERENCE
                   7090: #
                   7091: o$nam:                         # entry point
                   7092:        movl    $4*nmsi$,r6     # set length of nmblk
                   7093:        jsb     alloc           # allocate nmblk
                   7094:        movl    $b$nml,(r9)     # set name block code
                   7095:        movl    (sp)+,4*nmofs(r9)# set name offset from operand
                   7096:        movl    (sp)+,4*nmbas(r9)# set name base from operand
                   7097:        jmp     exixr           # exit with result in xr
                   7098:        #page   
                   7099: #
                   7100: #      NEGATION
                   7101: #
                   7102: #      INITIAL ENTRY
                   7103: #
                   7104: o$nta:                         # entry point
                   7105:        movl    (r3)+,r6        # load new failure offset
                   7106:        movl    flptr,-(sp)     # stack old failure pointer
                   7107:        movl    r6,-(sp)        # stack new failure offset
                   7108:        movl    sp,flptr        # set new failure pointer
                   7109:        jmp     exits           # jump to continue execution
                   7110: #
                   7111: #      ENTRY AFTER SUCCESSFUL EVALUATION OF OPERAND
                   7112: #
                   7113: o$ntb:                         # entry point
                   7114:        movl    4*2(sp),flptr   # restore old failure pointer
                   7115:        jmp     exfal           # and fail
                   7116: #
                   7117: #      ENTRY FOR FAILURE DURING OPERAND EVALUATION
                   7118: #
                   7119: o$ntc:                         # entry point
                   7120:        addl2   $4,sp           # pop failure offset
                   7121:        movl    (sp)+,flptr     # restore old failure pointer
                   7122:        jmp     exnul           # exit giving null result
                   7123:        #page   
                   7124: #
                   7125: #      USE OF UNDEFINED OPERATOR
                   7126: #
                   7127: o$oun:                         # entry point
                   7128:        jmp     er_029          # undefined operator referenced
                   7129:        #page   
                   7130: #
                   7131: #      BINARY DOT (PATTERN ASSIGNMENT)
                   7132: #
                   7133: #      THE PATTERN BUILT BY BINARY DOT IS A COMPOUND PATTERN.
                   7134: #      SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR
                   7135: #      DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED.
                   7136: #
                   7137: o$pas:                         # entry point
                   7138:        movl    $p$pac,r7       # load pcode for p$pac node
                   7139:        movl    (sp)+,r8        # load name offset (parm2)
                   7140:        movl    (sp)+,r9        # load name base (parm1)
                   7141:        jsb     pbild           # build p$pac node
                   7142:        movl    r9,r10          # save ptr to node
                   7143:        movl    (sp),r9         # load left operand
                   7144:        jsb     gtpat           # convert to pattern
                   7145:        .long   er_030          # pattern assignment left operand is not pattern
                   7146:        movl    r9,(sp)         # save ptr to left operand pattern
                   7147:        movl    $p$paa,r7       # set pcode for p$paa node
                   7148:        jsb     pbild           # build p$paa node
                   7149:        movl    (sp)+,4*pthen(r9)# set left operand as p$paa successor
                   7150:        jsb     pconc           # concatenate to form final pattern
                   7151:        jmp     exixr           # jump for next code word
                   7152:        #page   
                   7153: #
                   7154: #      PATTERN MATCH (BY NAME, FOR REPLACEMENT)
                   7155: #
                   7156: o$pmn:                         # entry point
                   7157:        clrl    r7              # set type code for match by name
                   7158:        jmp     match           # jump to routine to start match
                   7159:        #page   
                   7160: #
                   7161: #      PATTERN MATCH (STATEMENT)
                   7162: #
                   7163: #      O$PMS IS USED IN PLACE OF O$PMV WHEN THE PATTERN MATCH
                   7164: #      OCCURS AT THE OUTER (STATEMENT) LEVEL SINCE IN THIS
                   7165: #      CASE THE SUBSTRING VALUE NEED NOT BE CONSTRUCTED.
                   7166: #
                   7167: o$pms:                         # entry point
                   7168:        movl    $num02,r7       # set flag for statement to match
                   7169:        jmp     match           # jump to routine to start match
                   7170:        #page   
                   7171: #
                   7172: #      PATTERN MATCH (BY VALUE)
                   7173: #
                   7174: o$pmv:                         # entry point
                   7175:        movl    $num01,r7       # set type code for value match
                   7176:        jmp     match           # jump to routine to start match
                   7177:        #page   
                   7178: #
                   7179: #      POP TOP ITEM ON STACK
                   7180: #
                   7181: o$pop:                         # entry point
                   7182:        addl2   $4,sp           # pop top stack entry
                   7183:        jmp     exits           # obey next code word
                   7184:        #page   
                   7185: #
                   7186: #      TERMINATE EXECUTION (CODE COMPILED FOR END STATEMENT)
                   7187: #
                   7188: o$stp:                         # entry point
                   7189:        jmp     lend0           # jump to end circuit
                   7190:        #page   
                   7191: #
                   7192: #      RETURN NAME FROM EXPRESSION
                   7193: #      THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN
                   7194: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS
                   7195: #      A NAME. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX.
                   7196: #
                   7197: o$rnm:                         # entry point
                   7198:        jmp     evlx4           # return to evalx procedure
                   7199:        #page   
                   7200: #
                   7201: #      PATTERN REPLACEMENT
                   7202: #
                   7203: #      WHEN THIS ROUTINE GETS CONTROL, THE FOLLOWING STACK
                   7204: #      ENTRIES HAVE BEEN MADE (SEE END OF MATCH ROUTINE P$NTH)
                   7205: #
                   7206: #                            SUBJECT NAME BASE
                   7207: #                            SUBJECT NAME OFFSET
                   7208: #                            INITIAL CURSOR VALUE
                   7209: #                            FINAL CURSOR VALUE
                   7210: #                            SUBJECT POINTER
                   7211: #      (XS) ---------------- REPLACEMENT VALUE
                   7212: #
                   7213: o$rpl:                         # entry point
                   7214:        jsb     gtstg           # convert replacement val to string
                   7215:        .long   er_031          # pattern replacement right operand is not string
                   7216: #
                   7217: #      GET RESULT LENGTH AND ALLOCATE RESULT SCBLK
                   7218: #
                   7219:        movl    (sp),r10        # load subject string pointer
                   7220:        cmpl    (r10),$b$bct    # branch if buffer assignment
                   7221:        bnequ   0f
                   7222:        jmp     orpl4
                   7223: 0:             
                   7224:        addl2   4*sclen(r10),r6 # add subject string length
                   7225:        addl2   4*2(sp),r6      # add starting cursor
                   7226:        subl2   4*1(sp),r6      # minus final cursor = total length
                   7227:        tstl    r6              # jump if result is null
                   7228:        bnequ   0f
                   7229:        jmp     orpl3
                   7230: 0:             
                   7231:        movl    r9,-(sp)        # restack replacement string
                   7232:        jsb     alocs           # allocate scblk for result
                   7233:        movl    4*3(sp),r6      # get initial cursor (part 1 len)
                   7234:        movl    r9,4*3(sp)      # stack result pointer
                   7235:        movab   cfp$f(r9),r9    # point to characters of result
                   7236: #
                   7237: #      MOVE PART 1 (START OF SUBJECT) TO RESULT
                   7238: #
                   7239:        tstl    r6              # jump if first part is null
                   7240:        beqlu   orpl1
                   7241:        movl    4*1(sp),r10     # else point to subject string
                   7242:        movab   cfp$f(r10),r10  # point to subject string chars
                   7243:        jsb     sbmvc           # move first part to result
                   7244:        #page   
                   7245: #      PATTERN REPLACEMENT (CONTINUED)
                   7246: #
                   7247: #      NOW MOVE IN REPLACEMENT VALUE
                   7248: #
                   7249: orpl1: movl    (sp)+,r10       # load replacement string, pop
                   7250:        movl    4*sclen(r10),r6 # load length
                   7251:        tstl    r6              # jump if null replacement
                   7252:        beqlu   orpl2
                   7253:        movab   cfp$f(r10),r10  # else point to chars of replacement
                   7254:        jsb     sbmvc           # move in chars (part 2)
                   7255: #
                   7256: #      NOW MOVE IN REMAINDER OF STRING (PART 3)
                   7257: #
                   7258: orpl2: movl    (sp)+,r10       # load subject string pointer, pop
                   7259:        movl    (sp)+,r8        # load final cursor, pop
                   7260:        movl    4*sclen(r10),r6 # load subject string length
                   7261:        subl2   r8,r6           # minus final cursor = part 3 length
                   7262:        tstl    r6              # jump to assign if part 3 is null
                   7263:        bnequ   0f
                   7264:        jmp     oass0
                   7265: 0:             
                   7266:        movab   cfp$f(r10)[r8],r10 # else point to last part of string
                   7267:        jsb     sbmvc           # move part 3 to result
                   7268:        jmp     oass0           # jump to perform assignment
                   7269: #
                   7270: #      HERE IF RESULT IS NULL
                   7271: #
                   7272: orpl3: addl2   $4*num02,sp     # pop subject str ptr, final cursor
                   7273:        movl    $nulls,(sp)     # set null result
                   7274:        jmp     oass0           # jump to assign null value
                   7275: #
                   7276: #      HERE FOR BUFFER SUBSTRING ASSIGNMENT
                   7277: #
                   7278: orpl4: movl    r9,r10          # copy scblk replacement ptr
                   7279:        movl    (sp)+,r9        # unstack bcblk ptr
                   7280:        movl    (sp)+,r7        # get final cursor value
                   7281:        movl    (sp)+,r6        # get initial cursor
                   7282:        subl2   r6,r7           # get length in wb
                   7283:        addl2   $4*num02,sp     # get rid of name base/offset
                   7284:        jsb     insbf           # insert substring
                   7285:        .long   invalid$        # convert fail impossible
                   7286:        .long   exfal           # fail if insert fails
                   7287:        jmp     exnul           # else null result
                   7288:        #page   
                   7289: #
                   7290: #      RETURN VALUE FROM EXPRESSION
                   7291: #
                   7292: #      THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN
                   7293: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS
                   7294: #      A VALUE. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX
                   7295: #
                   7296: o$rvl:                         # entry point
                   7297:        jmp     evlx3           # return to evalx procedure
                   7298:        #page   
                   7299: #
                   7300: #      SELECTION
                   7301: #
                   7302: #      INITIAL ENTRY
                   7303: #
                   7304: o$sla:                         # entry point
                   7305:        movl    (r3)+,r6        # load new failure offset
                   7306:        movl    flptr,-(sp)     # stack old failure pointer
                   7307:        movl    r6,-(sp)        # stack new failure offset
                   7308:        movl    sp,flptr        # set new failure pointer
                   7309:        jmp     exits           # jump to execute first alternative
                   7310: #
                   7311: #      ENTRY AFTER SUCCESSFUL EVALUATION OF ALTERNATIVE
                   7312: #
                   7313: o$slb:                         # entry point
                   7314:        movl    (sp)+,r9        # load result
                   7315:        addl2   $4,sp           # pop fail offset
                   7316:        movl    (sp),flptr      # restore old failure pointer
                   7317:        movl    r9,(sp)         # restack result
                   7318:        movl    (r3)+,r6        # load new code offset
                   7319:        addl2   r$cod,r6        # point to absolute code location
                   7320:        movl    r6,r3           # set new code pointer
                   7321:        jmp     exits           # jump to continue past selection
                   7322: #
                   7323: #      ENTRY AT START OF SUBSEQUENT ALTERNATIVES
                   7324: #
                   7325: o$slc:                         # entry point
                   7326:        movl    (r3)+,r6        # load new fail offset
                   7327:        movl    r6,(sp)         # store new fail offset
                   7328:        jmp     exits           # jump to execute next alternative
                   7329: #
                   7330: #      ENTRY AT START OF LAST ALTERNATIVE
                   7331: #
                   7332: o$sld:                         # entry point
                   7333:        addl2   $4,sp           # pop failure offset
                   7334:        movl    (sp)+,flptr     # restore old failure pointer
                   7335:        jmp     exits           # jump to execute last alternative
                   7336:        #page   
                   7337: #
                   7338: #      BINARY MINUS (SUBTRACTION)
                   7339: #
                   7340: o$sub:                         # entry point
                   7341:        jsb     arith           # fetch arithmetic operands
                   7342:        .long   er_032          # subtraction left operand is not numeric
                   7343:        .long   er_033          # subtraction right operand is not numeric
                   7344:        .long   osub1           # jump if real operands
                   7345: #
                   7346: #      HERE TO SUBTRACT TWO INTEGERS
                   7347: #
                   7348:        subl2   4*icval(r10),r5 # subtract right operand from left
                   7349:        bvs     0f
                   7350:        jmp     exint
                   7351: 0:             
                   7352:        jmp     er_034          # subtraction caused integer overflow
                   7353: #
                   7354: #      HERE TO SUBTRACT TWO REALS
                   7355: #
                   7356: osub1: subf2   4*rcval(r10),r2 # subtract right operand from left
                   7357:        bvs     0f
                   7358:        jmp     exrea
                   7359: 0:             
                   7360:        jmp     er_264          # subtraction caused real overflow
                   7361:        #page   
                   7362: #
                   7363: #      DUMMY OPERATOR TO RETURN CONTROL TO TRXEQ PROCEDURE
                   7364: #
                   7365: o$txr:                         # entry point
                   7366:        jmp     trxq1           # jump into trxeq procedure
                   7367:        #page   
                   7368: #
                   7369: #      UNEXPECTED FAILURE
                   7370: #
                   7371: #      NOTE THAT IF A SETEXIT TRAP IS OPERATING THEN
                   7372: #      TRANSFER TO SYSTEM LABEL CONTINUE
                   7373: #      WILL RESULT IN LOOPING HERE.  DIFFICULT TO AVOID EXCEPT
                   7374: #      WITH A CONSIDERABLE OVERHEAD WHICH IS NOT WORTHWHILE OR
                   7375: #      ELSE BY A TECHNIQUE SUCH AS SETTING KVERL TO ZERO.
                   7376: #
                   7377: o$unf:                         # entry point
                   7378:        jmp     er_035          # unexpected failure in -nofail mode
                   7379:        #title  s p i t b o l -- snobol4 builtin label routines
                   7380: #
                   7381: #      THE FOLLOWING SECTION CONTAINS THE ROUTINES FOR LABELS
                   7382: #      WHICH HAVE A PREDEFINED MEANING IN SNOBOL4.
                   7383: #
                   7384: #      CONTROL IS PASSED DIRECTLY TO THE LABEL NAME ENTRY POINT.
                   7385: #
                   7386: #      ENTRY NAMES ARE OF THE FORM L$XXX WHERE XXX IS THE THREE
                   7387: #      LETTER VARIABLE NAME IDENTIFIER.
                   7388: #
                   7389: #      ENTRIES ARE IN ALPHABETICAL ORDER
                   7390:        #page   
                   7391: #
                   7392: #      ABORT
                   7393: #
                   7394: l$abo:                         # entry point
                   7395: #
                   7396: #      MERGE HERE IF EXECUTION TERMINATES IN ERROR
                   7397: #
                   7398: labo1: movl    kvert,r6        # load error code
                   7399:        tstl    r6              # jump if no error has occured
                   7400:        beqlu   labo2
                   7401:        jsb     sysax           # call after execution proc (reg04)
                   7402:        jsb     prtpg           # else eject printer
                   7403:        jsb     ermsg           # print error message
                   7404:        clrl    r9              # indicate no message to print
                   7405:        jmp     stopr           # jump to routine to stop run
                   7406: #
                   7407: #      HERE IF NO ERROR HAD OCCURED
                   7408: #
                   7409: labo2: jmp     er_036          # goto abort with no preceding error
                   7410:        #page   
                   7411: #
                   7412: #      CONTINUE
                   7413: #
                   7414: l$cnt:                         # entry point
                   7415: #
                   7416: #      MERGE HERE AFTER EXECUTION ERROR
                   7417: #
                   7418: lcnt1: movl    r$cnt,r9        # load continuation code block ptr
                   7419:        tstl    r9              # jump if no previous error
                   7420:        beqlu   lcnt2
                   7421:        clrl    r$cnt           # clear flag
                   7422:        movl    r9,r$cod        # else store as new code block ptr
                   7423:        addl2   stxof,r9        # add failure offset
                   7424:        movl    r9,r3           # load code pointer
                   7425:        movl    flptr,sp        # reset stack pointer
                   7426:        jmp     exits           # jump to take indicated failure
                   7427: #
                   7428: #      HERE IF NO PREVIOUS ERROR
                   7429: #
                   7430: lcnt2: jmp     er_037          # goto continue with no preceding error
                   7431:        #page   
                   7432: #
                   7433: #      END
                   7434: #
                   7435: l$end:                         # entry point
                   7436: #
                   7437: #      MERGE HERE FROM END CODE CIRCUIT
                   7438: #
                   7439: lend0: movl    $endms,r9       # point to message /normal term../
                   7440:        jmp     stopr           # jump to routine to stop run
                   7441:        #page   
                   7442: #
                   7443: #      FRETURN
                   7444: #
                   7445: l$frt:                         # entry point
                   7446:        movl    $scfrt,r6       # point to string /freturn/
                   7447:        jmp     retrn           # jump to common return routine
                   7448:        #page   
                   7449: #
                   7450: #      NRETURN
                   7451: #
                   7452: l$nrt:                         # entry point
                   7453:        movl    $scnrt,r6       # point to string /nreturn/
                   7454:        jmp     retrn           # jump to common return routine
                   7455:        #page   
                   7456: #
                   7457: #      RETURN
                   7458: #
                   7459: l$rtn:                         # entry point
                   7460:        movl    $scrtn,r6       # point to string /return/
                   7461:        jmp     retrn           # jump to common return routine
                   7462:        #page   
                   7463: #
                   7464: #      UNDEFINED LABEL
                   7465: #
                   7466: l$und:                         # entry point
                   7467:        jmp     er_038          # goto undefined label
                   7468:        #title  s p i t b o l -- block action routines
                   7469: #
                   7470: #      THE FIRST WORD OF EVERY BLOCK IN DYNAMIC STORAGE AND THE
                   7471: #      VRGET, VRSTO AND VRTRA FIELDS OF A VRBLK CONTAIN A
                   7472: #      POINTER TO AN ENTRY POINT IN THE PROGRAM. ALL SUCH ENTRY
                   7473: #      POINTS ARE IN THE FOLLOWING SECTION EXCEPT THOSE FOR
                   7474: #      PATTERN BLOCKS WHICH ARE IN THE PATTERN MATCHING SEGMENT
                   7475: #      LATER ON (LABELS OF THE FORM P$XXX), AND DOPE VECTORS
                   7476: #      (D$XXX) WHICH ARE IN THE DOPE VECTOR SECTION FOLLOWING
                   7477: #      THE PATTERN ROUTINES (DOPE VECTORS ARE USED FOR CMBLKS).
                   7478: #
                   7479: #      THE ENTRY POINTS IN THIS SECTION HAVE LABELS OF THE
                   7480: #      FORM B$XXY WHERE XX IS THE TWO CHARACTER BLOCK TYPE FOR
                   7481: #      THE CORRESPONDING BLOCK AND Y IS ANY LETTER.
                   7482: #
                   7483: #      IN SOME CASES, THE POINTERS SERVE NO OTHER PURPOSE THAN
                   7484: #      TO IDENTIFY THE BLOCK TYPE. IN THIS CASE THE ROUTINE
                   7485: #      IS NEVER EXECUTED AND THUS NO CODE IS ASSEMBLED.
                   7486: #
                   7487: #      FOR EACH OF THESE ENTRY POINTS CORRESPONDING TO A BLOCK
                   7488: #      AN ENTRY POINT IDENTIFICATION IS ASSEMBLED (BL$XX).
                   7489: #
                   7490: #      THE EXACT ENTRY CONDITIONS DEPEND ON THE MANNER IN
                   7491: #      WHICH THE ROUTINE IS ACCESSED AND ARE DOCUMENTED WITH
                   7492: #      THE INDIVIDUAL ROUTINES AS REQUIRED.
                   7493: #
                   7494: #      THE ORDER OF THESE ROUTINES IS ALPHABETICAL WITH THE
                   7495: #      FOLLOWING EXCEPTIONS.
                   7496: #
                   7497: #      THE ROUTINES FOR SEBLK AND EXBLK ENTRIES OCCUR FIRST SO
                   7498: #      THAT EXPRESSIONS CAN BE QUICKLY IDENTIFIED FROM THE FACT
                   7499: #      THAT THEIR ROUTINES LIE BEFORE THE SYMBOL B$E$$.
                   7500: #
                   7501: #      THESE ARE IMMEDIATELY FOLLOWED BY THE ROUTINE FOR A TRBLK
                   7502: #      SO THAT THE TEST AGAINST THE SYMBOL B$T$$ CHECKS FOR
                   7503: #      TRAPPED VALUES OR EXPRESSION VALUES (SEE PROCEDURE EVALP)
                   7504: #
                   7505: #      THE PATTERN ROUTINES LIE AFTER THIS SECTION SO THAT
                   7506: #      PATTERNS ARE IDENTIFIED WITH ROUTINES STARTING AT OR
                   7507: #      AFTER THE INITIAL INSTRUCTION IN THESE ROUTINES (P$AAA).
                   7508: #
                   7509: #      THE SYMBOL B$AAA DEFINES THE FIRST LOCATION FOR BLOCK
                   7510: #      ROUTINES AND THE SYMBOL P$YYY (AT THE END OF THE PATTERN
                   7511: #      MATCH ROUTINES SECTION) DEFINES THE LAST SUCH ENTRY POINT
                   7512: #
                   7513:        .align  2
                   7514:        .word   bl$$i
                   7515: b$aaa:                         # entry point of first block routine
                   7516:        #page   
                   7517: #
                   7518: #      EXBLK
                   7519: #
                   7520: #      THE ROUTINE FOR AN EXBLK LOADS THE EXPRESSION ONTO
                   7521: #      THE STACK AS A VALUE.
                   7522: #
                   7523: #      (XR)                  POINTER TO EXBLK
                   7524: #
                   7525:        .align  2
                   7526:        .word   bl$ex
                   7527: b$exl:                         # entry point (exblk)
                   7528:        jmp     exixr           # stack xr and obey next code word
                   7529:        #page   
                   7530: #
                   7531: #      SEBLK
                   7532: #
                   7533: #      THE ROUTINE FOR SEBLK IS ACCESSED FROM THE GENERATED
                   7534: #      CODE TO LOAD THE EXPRESSION VALUE ONTO THE STACK.
                   7535: #
                   7536:        .align  2
                   7537:        .word   bl$se
                   7538: b$sel:                         # entry point (seblk)
                   7539:        jmp     exixr           # stack xr and obey next code word
                   7540: #
                   7541: #      DEFINE SYMBOL WHICH MARKS END OF ENTRIES FOR EXPRESSIONS
                   7542: #
                   7543:        .align  2
                   7544:        .word   bl$$i
                   7545: b$e$$:                         # entry point
                   7546:        #page   
                   7547: #
                   7548: #      TRBLK
                   7549: #
                   7550: #      THE ROUTINE FOR A TRBLK IS NEVER EXECUTED
                   7551: #
                   7552:        .align  2
                   7553:        .word   bl$tr
                   7554: b$trt:                         # entry point (trblk)
                   7555: #
                   7556: #      DEFINE SYMBOL MARKING END OF TRAP AND EXPRESSION BLOCKS
                   7557: #
                   7558:        .align  2
                   7559:        .word   bl$$i
                   7560: b$t$$:                         # end of trblk,seblk,exblk entries
                   7561:        #page   
                   7562: #
                   7563: #      ARBLK
                   7564: #
                   7565: #      THE ROUTINE FOR ARBLK IS NEVER EXECUTED
                   7566: #
                   7567:        .align  2
                   7568:        .word   bl$ar
                   7569: b$art:                         # entry point (arblk)
                   7570:        #page   
                   7571: #
                   7572: #      BCBLK
                   7573: #
                   7574: #      THE ROUTINE FOR A BCBLK IS NEVER EXECUTED
                   7575: #
                   7576: #      (XR)                  POINTER TO BCBLK
                   7577: #
                   7578:        .align  2
                   7579:        .word   bl$bc
                   7580: b$bct:                         # entry point (bcblk)
                   7581:        #page   
                   7582: #
                   7583: #      BFBLK
                   7584: #
                   7585: #      THE ROUTINE FOR A BFBLK IS NEVER EXECUTED
                   7586: #
                   7587: #      (XR)                  POINTER TO BFBLK
                   7588: #
                   7589:        .align  2
                   7590:        .word   bl$bf
                   7591: b$bft:                         # entry point (bfblk)
                   7592:        #page   
                   7593: #
                   7594: #      CCBLK
                   7595: #
                   7596: #      THE ROUTINE FOR CCBLK IS NEVER ENTERED
                   7597: #
                   7598:        .align  2
                   7599:        .word   bl$cc
                   7600: b$cct:                         # entry point (ccblk)
                   7601:        #page   
                   7602: #
                   7603: #      CDBLK
                   7604: #
                   7605: #      THE CDBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE.
                   7606: #      THERE ARE TWO CASES DEPENDING ON THE FORM OF CDFAL.
                   7607: #
                   7608: #      ENTRY FOR COMPLEX FAILURE CODE AT CDFAL
                   7609: #
                   7610: #      (XR)                  POINTER TO CDBLK
                   7611: #
                   7612:        .align  2
                   7613:        .word   bl$cd
                   7614: b$cdc:                         # entry point (cdblk)
                   7615: bcdc0: movl    flptr,sp        # pop garbage off stack
                   7616:        movl    4*cdfal(r9),(sp)# set failure offset
                   7617:        jmp     stmgo           # enter stmt
                   7618:        #page   
                   7619: #
                   7620: #      CDBLK (CONTINUED)
                   7621: #
                   7622: #      ENTRY FOR SIMPLE FAILURE CODE AT CDFAL
                   7623: #
                   7624: #      (XR)                  POINTER TO CDBLK
                   7625: #
                   7626:        .align  2
                   7627:        .word   bl$cd
                   7628: b$cds:                         # entry point (cdblk)
                   7629: bcds0: movl    flptr,sp        # pop garbage off stack
                   7630:        movl    $4*cdfal,(sp)   # set failure offset
                   7631:        jmp     stmgo           # enter stmt
                   7632:        #page   
                   7633: #
                   7634: #      CMBLK
                   7635: #
                   7636: #      THE ROUTINE FOR A CMBLK IS NEVER EXECUTED
                   7637: #
                   7638:        .align  2
                   7639:        .word   bl$cm
                   7640: b$cmt:                         # entry point (cmblk)
                   7641:        #page   
                   7642: #
                   7643: #      CTBLK
                   7644: #
                   7645: #      THE ROUTINE FOR A CTBLK IS NEVER EXECUTED
                   7646: #
                   7647:        .align  2
                   7648:        .word   bl$ct
                   7649: b$ctt:                         # entry point (ctblk)
                   7650:        #page   
                   7651: #
                   7652: #      DFBLK
                   7653: #
                   7654: #      THE ROUTINE FOR A DFBLK IS ACCESSED FROM THE O$FNC ENTRY
                   7655: #      TO CALL A DATATYPE FUNCTION AND BUILD A PDBLK.
                   7656: #
                   7657: #      (XL)                  POINTER TO DFBLK
                   7658: #
                   7659:        .align  2
                   7660:        .word   bl$df
                   7661: b$dfc:                         # entry point
                   7662:        movl    4*dfpdl(r10),r6 # load length of pdblk
                   7663:        jsb     alloc           # allocate pdblk
                   7664:        movl    $b$pdt,(r9)     # store type word
                   7665:        movl    r10,4*pddfp(r9) # store dfblk pointer
                   7666:        movl    r9,r8           # save pointer to pdblk
                   7667:        addl2   r6,r9           # point past pdblk
                   7668:        movl    4*fargs(r10),r6 # set to count fields
                   7669: #
                   7670: #      LOOP TO ACQUIRE FIELD VALUES FROM STACK
                   7671: #
                   7672: bdfc1: movl    (sp)+,-(r9)     # move a field value
                   7673:        sobgtr  r6,bdfc1        # loop till all moved
                   7674:        movl    r8,r9           # recall pointer to pdblk
                   7675:        jmp     exsid           # exit setting id field
                   7676:        #page   
                   7677: #
                   7678: #      EFBLK
                   7679: #
                   7680: #      THE ROUTINE FOR AN EFBLK IS PASSED CONTROL FORM THE O$FNC
                   7681: #      ENTRY TO CALL AN EXTERNAL FUNCTION.
                   7682: #
                   7683: #      (XL)                  POINTER TO EFBLK
                   7684: #
                   7685:        .align  2
                   7686:        .word   bl$ef
                   7687: b$efc:                         # entry point (efblk)
                   7688:        movl    4*fargs(r10),r8 # load number of arguments
                   7689:        moval   0[r8],r8        # convert to offset
                   7690:        movl    r10,-(sp)       # save pointer to efblk
                   7691:        movl    sp,r10          # copy pointer to arguments
                   7692: #
                   7693: #      LOOP TO CONVERT ARGUMENTS
                   7694: #
                   7695: befc1: addl2   $4,r10          # point to next entry
                   7696:        movl    (sp),r9         # load pointer to efblk
                   7697:        subl2   $4,r8           # decrement eftar offset
                   7698:        addl2   r8,r9           # point to next eftar entry
                   7699:        movl    4*eftar(r9),r9  # load eftar entry
                   7700:        casel   r9,$0,$4                # switch on type
                   7701: 5:             
                   7702:        .word   befc7-5b        # no conversion needed
                   7703:        .word   befc2-5b        # string
                   7704:        .word   befc3-5b        # integer
                   7705:        .word   befc4-5b        # real
                   7706:        #esw                    # end of switch on type
                   7707: #
                   7708: #      HERE TO CONVERT TO STRING
                   7709: #
                   7710: befc2: movl    (r10),-(sp)     # stack arg ptr
                   7711:        jsb     gtstg           # convert argument to string
                   7712:        .long   er_039          # external function argument is not string
                   7713:        jmp     befc6           # jump to merge
                   7714:        #page   
                   7715: #
                   7716: #      EFBLK (CONTINUED)
                   7717: #
                   7718: #      HERE TO CONVERT AN INTEGER
                   7719: #
                   7720: befc3: movl    (r10),r9        # load next argument
                   7721:        movl    r8,befof        # save offset
                   7722:        jsb     gtint           # convert to integer
                   7723:        .long   er_040          # external function argument is not integer
                   7724:        jmp     befc5           # merge with real case
                   7725: #
                   7726: #      HERE TO CONVERT A REAL
                   7727: #
                   7728: befc4: movl    (r10),r9        # load next argument
                   7729:        movl    r8,befof        # save offset
                   7730:        jsb     gtrea           # convert to real
                   7731:        .long   er_265          # external function argument is not real
                   7732: #
                   7733: #      INTEGER CASE MERGES HERE
                   7734: #
                   7735: befc5: movl    befof,r8        # restore offset
                   7736: #
                   7737: #      STRING MERGES HERE
                   7738: #
                   7739: befc6: movl    r9,(r10)        # store converted result
                   7740: #
                   7741: #      NO CONVERSION MERGES HERE
                   7742: #
                   7743: befc7: tstl    r8              # loop back if more to go
                   7744:        bnequ   befc1
                   7745: #
                   7746: #      HERE AFTER CONVERTING ALL THE ARGUMENTS
                   7747: #
                   7748:        movl    (sp)+,r10       # restore efblk pointer
                   7749:        movl    4*fargs(r10),r6 # get number of args
                   7750:        jsb     sysex           # call routine to call external fnc
                   7751:        .long   exfal           # fail if failure
                   7752:        #page   
                   7753: #
                   7754: #      EFBLK (CONTINUED)
                   7755: #
                   7756: #      RETURN HERE WITH RESULT IN XR
                   7757: #
                   7758: #      FIRST DEFEND AGAINST NON-STANDARD NULL STRING RETURNED
                   7759: #
                   7760:        movl    4*efrsl(r10),r7 # get result type id
                   7761:        tstl    r7              # branch if not unconverted
                   7762:        bnequ   befa8
                   7763:        cmpl    (r9),$b$scl     # jump if not a string
                   7764:        bnequ   befc8
                   7765:        tstl    4*sclen(r9)     # return null if null
                   7766:        bnequ   0f
                   7767:        jmp     exnul
                   7768: 0:             
                   7769: #
                   7770: #      HERE IF CONVERTED RESULT TO CHECK FOR NULL STRING
                   7771: #
                   7772: befa8: cmpl    r7,$num01       # jump if not a string
                   7773:        bnequ   befc8
                   7774:        tstl    4*sclen(r9)     # return null if null
                   7775:        bnequ   0f
                   7776:        jmp     exnul
                   7777: 0:             
                   7778: #
                   7779: #      RETURN IF RESULT IS IN DYNAMIC STORAGE
                   7780: #
                   7781: befc8: cmpl    r9,dnamb        # jump if not in dynamic storage
                   7782:        blssu   befc9
                   7783:        cmpl    r9,dnamp        # return result if already dynamic
                   7784:        bgtru   0f
                   7785:        jmp     exixr
                   7786: 0:             
                   7787: #
                   7788: #      HERE WE COPY A RESULT INTO THE DYNAMIC REGION
                   7789: #
                   7790: befc9: movl    (r9),r6         # get possible type word
                   7791:        tstl    r7              # jump if unconverted result
                   7792:        beqlu   bef11
                   7793:        movl    $b$scl,r6       # string
                   7794:        cmpl    r7,$num01       # yes jump
                   7795:        beqlu   bef10
                   7796:        movl    $b$icl,r6       # integer
                   7797:        cmpl    r7,$num02       # yes jump
                   7798:        beqlu   bef10
                   7799:        movl    $b$rcl,r6       # real
                   7800: #
                   7801: #      STORE TYPE WORD IN RESULT
                   7802: #
                   7803: bef10: movl    r6,(r9)         # stored before copying to dynamic
                   7804: #
                   7805: #      MERGE FOR UNCONVERTED RESULT
                   7806: #
                   7807: bef11: jsb     blkln           # get length of block
                   7808:        movl    r9,r10          # copy address of old block
                   7809:        jsb     alloc           # allocate dynamic block same size
                   7810:        movl    r9,-(sp)        # set pointer to new block as result
                   7811:        jsb     sbmvw           # copy old block to dynamic block
                   7812:        jmp     exits           # exit with result on stack
                   7813:        #page   
                   7814: #
                   7815: #      EVBLK
                   7816: #
                   7817: #      THE ROUTINE FOR AN EVBLK IS NEVER EXECUTED
                   7818: #
                   7819:        .align  2
                   7820:        .word   bl$ev
                   7821: b$evt:                         # entry point (evblk)
                   7822:        #page   
                   7823: #
                   7824: #      FFBLK
                   7825: #
                   7826: #      THE ROUTINE FOR AN FFBLK IS EXECUTED FROM THE O$FNC ENTRY
                   7827: #      TO CALL A FIELD FUNCTION AND EXTRACT A FIELD VALUE/NAME.
                   7828: #
                   7829: #      (XL)                  POINTER TO FFBLK
                   7830: #
                   7831:        .align  2
                   7832:        .word   bl$ff
                   7833: b$ffc:                         # entry point (ffblk)
                   7834:        movl    r10,r9          # copy ffblk pointer
                   7835:        movl    (r3)+,r8        # load next code word
                   7836:        movl    (sp),r10        # load pdblk pointer
                   7837:        cmpl    (r10),$b$pdt    # jump if not pdblk at all
                   7838:        bnequ   bffc2
                   7839:        movl    4*pddfp(r10),r6 # load dfblk pointer from pdblk
                   7840: #
                   7841: #      LOOP TO FIND CORRECT FFBLK FOR THIS PDBLK
                   7842: #
                   7843: bffc1: cmpl    r6,4*ffdfp(r9)  # jump if this is the correct ffblk
                   7844:        beqlu   bffc3
                   7845:        movl    4*ffnxt(r9),r9  # else link to next ffblk on chain
                   7846:        tstl    r9              # loop back if another entry to check
                   7847:        bnequ   bffc1
                   7848: #
                   7849: #      HERE FOR BAD ARGUMENT
                   7850: #
                   7851: bffc2: jmp     er_041          # field function argument is wrong datatype
                   7852:        #page   
                   7853: #
                   7854: #      FFBLK (CONTINUED)
                   7855: #
                   7856: #      HERE AFTER LOCATING CORRECT FFBLK
                   7857: #
                   7858: bffc3: movl    4*ffofs(r9),r6  # load field offset
                   7859:        cmpl    r8,$ofne$       # jump if called by name
                   7860:        beqlu   bffc5
                   7861:        addl2   r6,r10          # else point to value field
                   7862:        movl    (r10),r9        # load value
                   7863:        cmpl    (r9),$b$trt     # jump if not trapped
                   7864:        bnequ   bffc4
                   7865:        subl2   r6,r10          # else restore name base,offset
                   7866:        movl    r8,(sp)         # save next code word over pdblk ptr
                   7867:        jsb     acess           # access value
                   7868:        .long   exfal           # fail if access fails
                   7869:        movl    (sp),r8         # restore next code word
                   7870: #
                   7871: #      HERE AFTER GETTING VALUE IN (XR)
                   7872: #
                   7873: bffc4: movl    r9,(sp)         # store value on stack (over pdblk)
                   7874:        movl    r8,r9           # copy next code word
                   7875:        movl    (r9),r10        # load entry address
                   7876:        movl    r10,r11         # jump to routine for next code word
                   7877:        jmp     (r11)
                   7878: #
                   7879: #      HERE IF CALLED BY NAME
                   7880: #
                   7881: bffc5: movl    r6,-(sp)        # store name offset (base is set)
                   7882:        jmp     exits           # exit with name on stack
                   7883:        #page   
                   7884: #
                   7885: #      ICBLK
                   7886: #
                   7887: #      THE ROUTINE FOR ICBLK IS EXECUTED FROM THE GENERATED
                   7888: #      CODE TO LOAD AN INTEGER VALUE ONTO THE STACK.
                   7889: #
                   7890: #      (XR)                  POINTER TO ICBLK
                   7891: #
                   7892:        .align  2
                   7893:        .word   bl$ic
                   7894: b$icl:                         # entry point (icblk)
                   7895:        jmp     exixr           # stack xr and obey next code word
                   7896:        #page   
                   7897: #
                   7898: #      KVBLK
                   7899: #
                   7900: #      THE ROUTINE FOR A KVBLK IS NEVER EXECUTED.
                   7901: #
                   7902:        .align  2
                   7903:        .word   bl$kv
                   7904: b$kvt:                         # entry point (kvblk)
                   7905:        #page   
                   7906: #
                   7907: #      NMBLK
                   7908: #
                   7909: #      THE ROUTINE FOR A NMBLK IS EXECUTED FROM THE GENERATED
                   7910: #      CODE FOR THE CASE OF LOADING A NAME ONTO THE STACK
                   7911: #      WHERE THE NAME IS THAT OF A NATURAL VARIABLE WHICH CAN
                   7912: #      BE PREEVALUATED AT COMPILE TIME.
                   7913: #
                   7914: #      (XR)                  POINTER TO NMBLK
                   7915: #
                   7916:        .align  2
                   7917:        .word   bl$nm
                   7918: b$nml:                         # entry point (nmblk)
                   7919:        jmp     exixr           # stack xr and obey next code word
                   7920:        #page   
                   7921: #
                   7922: #      PDBLK
                   7923: #
                   7924: #      THE ROUTINE FOR A PDBLK IS NEVER EXECUTED
                   7925: #
                   7926:        .align  2
                   7927:        .word   bl$pd
                   7928: b$pdt:                         # entry point (pdblk)
                   7929:        #page   
                   7930: #
                   7931: #      PFBLK
                   7932: #
                   7933: #      THE ROUTINE FOR A PFBLK IS EXECUTED FROM THE ENTRY O$FNC
                   7934: #      TO CALL A PROGRAM DEFINED FUNCTION.
                   7935: #
                   7936: #      (XL)                  POINTER TO PFBLK
                   7937: #
                   7938: #      THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING
                   7939: #      CONTROL TO THE PROGRAM DEFINED FUNCTION.
                   7940: #
                   7941: #                            SAVED VALUE OF FIRST ARGUMENT
                   7942: #                            .
                   7943: #                            SAVED VALUE OF LAST ARGUMENT
                   7944: #                            SAVED VALUE OF FIRST LOCAL
                   7945: #                            .
                   7946: #                            SAVED VALUE OF LAST LOCAL
                   7947: #                            SAVED VALUE OF FUNCTION NAME
                   7948: #                            SAVED CODE BLOCK PTR (R$COD)
                   7949: #                            SAVED CODE POINTER (-R$COD)
                   7950: #                            SAVED VALUE OF FLPRT
                   7951: #                            SAVED VALUE OF FLPTR
                   7952: #                            POINTER TO PFBLK
                   7953: #      FLPTR --------------- ZERO (TO BE OVERWRITTEN WITH OFFS)
                   7954: #
                   7955:        .align  2
                   7956:        .word   bl$pf
                   7957: b$pfc:                         # entry point (pfblk)
                   7958:        movl    r10,bpfpf       # save pfblk ptr (need not be reloc)
                   7959:        movl    r10,r9          # copy for the moment
                   7960:        movl    4*pfvbl(r9),r10 # point to vrblk for function
                   7961: #
                   7962: #      LOOP TO FIND OLD VALUE OF FUNCTION
                   7963: #
                   7964: bpf01: movl    r10,r7          # save pointer
                   7965:        movl    4*vrval(r10),r10# load value
                   7966:        cmpl    (r10),$b$trt    # loop if trblk
                   7967:        beqlu   bpf01
                   7968: #
                   7969: #      SET VALUE TO NULL AND SAVE OLD FUNCTION VALUE
                   7970: #
                   7971:        movl    r10,bpfsv       # save old value
                   7972:        movl    r7,r10          # point back to block with value
                   7973:        movl    $nulls,4*vrval(r10) # set value to null
                   7974:        movl    4*fargs(r9),r6  # load number of arguments
                   7975:        addl2   $4*pfarg,r9     # point to pfarg entries
                   7976:        tstl    r6              # jump if no arguments
                   7977:        beqlu   bpf04
                   7978:        movl    sp,r10          # ptr to last arg
                   7979:        moval   0[r6],r6        # convert no. of args to bytes offset
                   7980:        addl2   r6,r10          # point before first arg
                   7981:        movl    r10,bpfxt       # remember arg pointer
                   7982:        #page   
                   7983: #
                   7984: #      PFBLK (CONTINUED)
                   7985: #
                   7986: #      LOOP TO SAVE OLD ARGUMENT VALUES AND SET NEW ONES
                   7987: #
                   7988: bpf02: movl    (r9)+,r10       # load vrblk ptr for next argument
                   7989: #
                   7990: #      LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE
                   7991: #
                   7992: bpf03: movl    r10,r8          # save pointer
                   7993:        movl    4*vrval(r10),r10# load next value
                   7994:        cmpl    (r10),$b$trt    # loop back if trblk
                   7995:        beqlu   bpf03
                   7996: #
                   7997: #      SAVE OLD VALUE AND GET NEW VALUE
                   7998: #
                   7999:        movl    r10,r6          # keep old value
                   8000:        movl    bpfxt,r10       # point before next stacked arg
                   8001:        movl    -(r10),r7       # load argument (new value)
                   8002:        movl    r6,(r10)        # save old value
                   8003:        movl    r10,bpfxt       # keep arg ptr for next time
                   8004:        movl    r8,r10          # point back to block with value
                   8005:        movl    r7,4*vrval(r10) # set new value
                   8006:        cmpl    sp,bpfxt        # loop if not all done
                   8007:        bnequ   bpf02
                   8008: #
                   8009: #      NOW PROCESS LOCALS
                   8010: #
                   8011: bpf04: movl    bpfpf,r10       # restore pfblk pointer
                   8012:        movl    4*pfnlo(r10),r6 # load number of locals
                   8013:        tstl    r6              # jump if no locals
                   8014:        beqlu   bpf07
                   8015:        movl    $nulls,r7       # get null constant
                   8016:                                # set local counter
                   8017: #
                   8018: #      LOOP TO PROCESS LOCALS
                   8019: #
                   8020: bpf05: movl    (r9)+,r10       # load vrblk ptr for next local
                   8021: #
                   8022: #      LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE
                   8023: #
                   8024: bpf06: movl    r10,r8          # save pointer
                   8025:        movl    4*vrval(r10),r10# load next value
                   8026:        cmpl    (r10),$b$trt    # loop back if trblk
                   8027:        beqlu   bpf06
                   8028: #
                   8029: #      SAVE OLD VALUE AND SET NULL AS NEW VALUE
                   8030: #
                   8031:        movl    r10,-(sp)       # stack old value
                   8032:        movl    r8,r10          # point back to block with value
                   8033:        movl    r7,4*vrval(r10) # set null as new value
                   8034:        sobgtr  r6,bpf05        # loop till all locals processed
                   8035:        #page   
                   8036: #
                   8037: #      PFBLK (CONTINUED)
                   8038: #
                   8039: #      HERE AFTER PROCESSING ARGUMENTS AND LOCALS
                   8040: #
                   8041: bpf07: clrl    r9              # zero reg xr in case
                   8042:        tstl    kvpfl           # skip if profiling is off
                   8043:        beqlu   bpf7c
                   8044:        cmpl    kvpfl,$num02    # branch on type of profile
                   8045:        beqlu   bpf7a
                   8046: #
                   8047: #      HERE IF &PROFILE = 1
                   8048: #
                   8049:        jsb     systm           # get current time
                   8050:        movl    r5,pfetm        # save for a sec
                   8051:        subl2   pfstm,r5        # find time used by caller
                   8052:        jsb     icbld           # build into an icblk
                   8053:        movl    pfetm,r5        # reload current time
                   8054:        jmp     bpf7b           # merge
                   8055: #
                   8056: #       HERE IF &PROFILE = 2
                   8057: #
                   8058: bpf7a: movl    pfstm,r5        # get start time of calling stmt
                   8059:        jsb     icbld           # assemble an icblk round it
                   8060:        jsb     systm           # get now time
                   8061: #
                   8062: #      BOTH TYPES OF PROFILE MERGE HERE
                   8063: #
                   8064: bpf7b: movl    r5,pfstm        # set start time of 1st func stmt
                   8065:        movl    sp,pffnc        # flag function entry
                   8066: #
                   8067: #      NO PROFILING MERGES HERE
                   8068: #
                   8069: bpf7c: movl    r9,-(sp)        # stack icblk ptr (or zero)
                   8070:        movl    r$cod,r6        # load old code block pointer
                   8071:        movl    r3,r7           # get code pointer
                   8072:        subl2   r6,r7           # make code pointer into offset
                   8073:        movl    bpfpf,r10       # recall pfblk pointer
                   8074:        movl    bpfsv,-(sp)     # stack old value of function name
                   8075:        movl    r6,-(sp)        # stack code block pointer
                   8076:        movl    r7,-(sp)        # stack code offset
                   8077:        movl    flprt,-(sp)     # stack old flprt
                   8078:        movl    flptr,-(sp)     # stack old failure pointer
                   8079:        movl    r10,-(sp)       # stack pointer to pfblk
                   8080:        clrl    -(sp)           # dummy zero entry for fail return
                   8081:        jsb     sbchk           # check for stack overflow
                   8082:        movl    sp,flptr        # set new fail return value
                   8083:        movl    sp,flprt        # set new flprt
                   8084:        movl    kvtra,r6        # load trace value
                   8085:        addl2   kvftr,r6        # add ftrace value
                   8086:        tstl    r6              # jump if tracing possible
                   8087:        bnequ   bpf09
                   8088:        incl    kvfnc           # else bump fnclevel
                   8089: #
                   8090: #      HERE TO ACTUALLY JUMP TO FUNCTION
                   8091: #
                   8092: bpf08: movl    4*pfcod(r10),r9 # point to code
                   8093:        movl    (r9),r11        # off to execute function
                   8094:        jmp     (r11)
                   8095: #
                   8096: #      HERE IF TRACING IS POSSIBLE
                   8097: #
                   8098: bpf09: movl    4*pfctr(r10),r9 # load possible call trace trblk
                   8099:        movl    4*pfvbl(r10),r10# load vrblk pointer for function
                   8100:        movl    $4*vrval,r6     # set name offset for variable
                   8101:        tstl    kvtra           # jump if trace mode is off
                   8102:        beqlu   bpf10
                   8103:        tstl    r9              # or if there is no call trace
                   8104:        beqlu   bpf10
                   8105: #
                   8106: #      HERE IF CALL TRACED
                   8107: #
                   8108:        decl    kvtra           # decrement trace count
                   8109:        tstl    4*trfnc(r9)     # jump if print trace
                   8110:        beqlu   bpf11
                   8111:        jsb     trxeq           # execute function type trace
                   8112:        #page   
                   8113: #
                   8114: #      PFBLK (CONTINUED)
                   8115: #
                   8116: #      HERE TO TEST FOR FTRACE TRACE
                   8117: #
                   8118: bpf10: tstl    kvftr           # jump if ftrace is off
                   8119:        beqlu   bpf16
                   8120:        decl    kvftr           # else decrement ftrace
                   8121: #
                   8122: #      HERE FOR PRINT TRACE
                   8123: #
                   8124: bpf11: jsb     prtsn           # print statement number
                   8125:        jsb     prtnm           # print function name
                   8126:        movl    $ch$pp,r6       # load left paren
                   8127:        jsb     prtch           # print left paren
                   8128:        movl    4*1(sp),r10     # recover pfblk pointer
                   8129:        tstl    4*fargs(r10)    # skip if no arguments
                   8130:        beqlu   bpf15
                   8131:        clrl    r7              # else set argument counter
                   8132:        jmp     bpf13           # jump into loop
                   8133: #
                   8134: #      LOOP TO PRINT ARGUMENT VALUES
                   8135: #
                   8136: bpf12: movl    $ch$cm,r6       # load comma
                   8137:        jsb     prtch           # print to separate from last arg
                   8138: #
                   8139: #      MERGE HERE FIRST TIME (NO COMMA REQUIRED)
                   8140: #
                   8141: bpf13: movl    r7,(sp)         # save arg ctr (over failoffs is ok)
                   8142:        moval   0[r7],r7        # convert to byte offset
                   8143:        addl2   r7,r10          # point to next argument pointer
                   8144:        movl    4*pfarg(r10),r9 # load next argument vrblk ptr
                   8145:        subl2   r7,r10          # restore pfblk pointer
                   8146:        movl    4*vrval(r9),r9  # load next value
                   8147:        jsb     prtvl           # print argument value
                   8148:        #page   
                   8149: #
                   8150: #      HERE AFTER DEALING WITH ONE ARGUMENT
                   8151: #
                   8152:        movl    (sp),r7         # restore argument counter
                   8153:        incl    r7              # increment argument counter
                   8154:        cmpl    r7,4*fargs(r10) # loop if more to print
                   8155:        blssu   bpf12
                   8156: #
                   8157: #      MERGE HERE IN NO ARGS CASE TO PRINT PAREN
                   8158: #
                   8159: bpf15: movl    $ch$rp,r6       # load right paren
                   8160:        jsb     prtch           # print to terminate output
                   8161:        jsb     prtnl           # terminate print line
                   8162: #
                   8163: #      MERGE HERE TO EXIT WITH TEST FOR FNCLEVEL TRACE
                   8164: #
                   8165: bpf16: incl    kvfnc           # increment fnclevel
                   8166:        movl    r$fnc,r10       # load ptr to possible trblk
                   8167:        jsb     ktrex           # call keyword trace routine
                   8168: #
                   8169: #      CALL FUNCTION AFTER TRACE TESTS COMPLETE
                   8170: #
                   8171:        movl    4*1(sp),r10     # restore pfblk pointer
                   8172:        jmp     bpf08           # jump back to execute function
                   8173:        #page   
                   8174: #
                   8175: #      RCBLK
                   8176: #
                   8177: #      THE ROUTINE FOR AN RCBLK IS EXECUTED FROM THE GENERATED
                   8178: #      CODE TO LOAD A REAL VALUE ONTO THE STACK.
                   8179: #
                   8180: #      (XR)                  POINTER TO RCBLK
                   8181: #
                   8182:        .align  2
                   8183:        .word   bl$rc
                   8184: b$rcl:                         # entry point (rcblk)
                   8185:        jmp     exixr           # stack xr and obey next code word
                   8186:        #page   
                   8187: #
                   8188: #      SCBLK
                   8189: #
                   8190: #      THE ROUTINE FOR AN SCBLK IS EXECUTED FROM THE GENERATED
                   8191: #      CODE TO LOAD A STRING VALUE ONTO THE STACK.
                   8192: #
                   8193: #      (XR)                  POINTER TO SCBLK
                   8194: #
                   8195:        .align  2
                   8196:        .word   bl$sc
                   8197: b$scl:                         # entry point (scblk)
                   8198:        jmp     exixr           # stack xr and obey next code word
                   8199:        #page   
                   8200: #
                   8201: #      TBBLK
                   8202: #
                   8203: #      THE ROUTINE FOR A TBBLK IS NEVER EXECUTED
                   8204: #
                   8205:        .align  2
                   8206:        .word   bl$tb
                   8207: b$tbt:                         # entry point (tbblk)
                   8208:        #page   
                   8209: #
                   8210: #      TEBLK
                   8211: #
                   8212: #      THE ROUTINE FOR A TEBLK IS NEVER EXECUTED
                   8213: #
                   8214:        .align  2
                   8215:        .word   bl$te
                   8216: b$tet:                         # entry point (teblk)
                   8217:        #page   
                   8218: #
                   8219: #      VCBLK
                   8220: #
                   8221: #      THE ROUTINE FOR A VCBLK IS NEVER EXECUTED
                   8222: #
                   8223:        .align  2
                   8224:        .word   bl$vc
                   8225: b$vct:                         # entry point (vcblk)
                   8226:        #page   
                   8227: #
                   8228: #      VRBLK
                   8229: #
                   8230: #      THE VRBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE.
                   8231: #      THERE ARE SIX ENTRIES FOR VRBLK COVERING VARIOUS CASES
                   8232: #
                   8233:        .align  2
                   8234:        .word   bl$$i
                   8235: b$vr$:                         # mark start of vrblk entry points
                   8236: #
                   8237: #      ENTRY FOR VRGET (TRAPPED CASE). THIS ROUTINE IS CALLED
                   8238: #      FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE.
                   8239: #      THIS ENTRY POINT IS USED IF AN ACCESS TRACE OR INPUT
                   8240: #      ASSOCIATION IS CURRENTLY ACTIVE.
                   8241: #
                   8242: #      (XR)                  POINTER TO VRGET FIELD OF VRBLK
                   8243: #
                   8244:        .align  2
                   8245:        .word   bl$$i
                   8246: b$vra:                         # entry point
                   8247:        movl    r9,r10          # copy name base (vrget = 0)
                   8248:        movl    $4*vrval,r6     # set name offset
                   8249:        jsb     acess           # access value
                   8250:        .long   exfal           # fail if access fails
                   8251:        jmp     exixr           # else exit with result in xr
                   8252:        #page   
                   8253: #
                   8254: #      VRBLK (CONTINUED)
                   8255: #
                   8256: #      ENTRY FOR VRSTO (ERROR CASE. THIS ROUTINE IS CALLED FROM
                   8257: #      THE EXECUTED CODE FOR AN ATTEMPT TO MODIFY THE VALUE
                   8258: #      OF A PROTECTED (PATTERN VALUED) NATURAL VARIABLE.
                   8259: #
                   8260: b$vre:                         # entry point
                   8261:        jmp     er_042          # attempt to change value of protected variable
                   8262:        #page   
                   8263: #
                   8264: #      VRBLK (CONTINUED)
                   8265: #
                   8266: #      ENTRY FOR VRTRA (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8267: #      FROM THE EXECUTED CODE TO TRANSFER TO A LABEL.
                   8268: #
                   8269: #      (XR)                  POINTER TO VRTRA FIELD OF VRBLK
                   8270: #
                   8271: b$vrg:                         # entry point
                   8272:        movl    4*vrlbo(r9),r9  # load code pointer
                   8273:        movl    (r9),r10        # load entry address
                   8274:        movl    r10,r11         # jump to routine for next code word
                   8275:        jmp     (r11)
                   8276:        #page   
                   8277: #
                   8278: #      VRBLK (CONTINUED)
                   8279: #
                   8280: #      ENTRY FOR VRGET (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8281: #      FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE.
                   8282: #
                   8283: #      (XR)                  POINTS TO VRGET FIELD OF VRBLK
                   8284: #
                   8285: b$vrl:                         # entry point
                   8286:        movl    4*vrval(r9),-(sp)# load value onto stack (vrget = 0)
                   8287:        jmp     exits           # obey next code word
                   8288:        #page   
                   8289: #
                   8290: #      VRBLK (CONTINUED)
                   8291: #
                   8292: #      ENTRY FOR VRSTO (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8293: #      FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE.
                   8294: #
                   8295: #      (XR)                  POINTER TO VRSTO FIELD OF VRBLK
                   8296: #
                   8297: b$vrs:                         # entry point
                   8298:        movl    (sp),4*vrvlo(r9)# store value, leave on stack
                   8299:        jmp     exits           # obey next code word
                   8300:        #page   
                   8301: #
                   8302: #      VRBLK (CONTINUED)
                   8303: #
                   8304: #      VRTRA (TRAPPED CASE). THIS ROUTINE IS CALLED FROM THE
                   8305: #      GENERATED CODE TO TRANSFER TO A LABEL WHEN A LABEL
                   8306: #      TRACE IS CURRENTLY ACTIVE.
                   8307: #
                   8308: b$vrt:                         # entry point
                   8309:        subl2   $4*vrtra,r9     # point back to start of vrblk
                   8310:        movl    r9,r10          # copy vrblk pointer
                   8311:        movl    $4*vrval,r6     # set name offset
                   8312:        movl    4*vrlbl(r10),r9 # load pointer to trblk
                   8313:        tstl    kvtra           # jump if trace is off
                   8314:        beqlu   bvrt2
                   8315:        decl    kvtra           # else decrement trace count
                   8316:        tstl    4*trfnc(r9)     # jump if print trace case
                   8317:        beqlu   bvrt1
                   8318:        jsb     trxeq           # else execute full trace
                   8319:        jmp     bvrt2           # merge to jump to label
                   8320: #
                   8321: #      HERE FOR PRINT TRACE -- PRINT COLON ( LABEL NAME )
                   8322: #
                   8323: bvrt1: jsb     prtsn           # print statement number
                   8324:        movl    r10,r9          # copy vrblk pointer
                   8325:        movl    $ch$cl,r6       # colon
                   8326:        jsb     prtch           # print it
                   8327:        movl    $ch$pp,r6       # left paren
                   8328:        jsb     prtch           # print it
                   8329:        jsb     prtvn           # print label name
                   8330:        movl    $ch$rp,r6       # right paren
                   8331:        jsb     prtch           # print it
                   8332:        jsb     prtnl           # terminate line
                   8333:        movl    4*vrlbl(r10),r9 # point back to trblk
                   8334: #
                   8335: #      MERGE HERE TO JUMP TO LABEL
                   8336: #
                   8337: bvrt2: movl    4*trlbl(r9),r9  # load pointer to actual code
                   8338:        movl    (r9),r11        # execute statement at label
                   8339:        jmp     (r11)
                   8340:        #page   
                   8341: #
                   8342: #      VRBLK (CONTINUED)
                   8343: #
                   8344: #      ENTRY FOR VRSTO (TRAPPED CASE). THIS ROUTINE IS CALLED
                   8345: #      FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE.
                   8346: #      THIS ENTRY IS USED WHEN A VALUE TRACE OR OUTPUT
                   8347: #      ASSOCIATION IS CURRENTLY ACTIVE.
                   8348: #
                   8349: #      (XR)                  POINTER TO VRSTO FIELD OF VRBLK
                   8350: #
                   8351: b$vrv:                         # entry point
                   8352:        movl    (sp),r7         # load value (leave copy on stack)
                   8353:        subl2   $4*vrsto,r9     # point to vrblk
                   8354:        movl    r9,r10          # copy vrblk pointer
                   8355:        movl    $4*vrval,r6     # set offset
                   8356:        jsb     asign           # call assignment routine
                   8357:        .long   exfal           # fail if assignment fails
                   8358:        jmp     exits           # else return with result on stack
                   8359:        #page   
                   8360: #
                   8361: #      XNBLK
                   8362: #
                   8363: #      THE ROUTINE FOR AN XNBLK IS NEVER EXECUTED
                   8364: #
                   8365:        .align  2
                   8366:        .word   bl$xn
                   8367: b$xnt:                         # entry point (xnblk)
                   8368:        #page   
                   8369: #
                   8370: #      XRBLK
                   8371: #
                   8372: #      THE ROUTINE FOR AN XRBLK IS NEVER EXECUTED
                   8373: #
                   8374:        .align  2
                   8375:        .word   bl$xr
                   8376: b$xrt:                         # entry point (xrblk)
                   8377: #
                   8378: #      MARK ENTRY ADDRESS PAST LAST BLOCK ACTION ROUTINE
                   8379: #
                   8380:        .align  2
                   8381:        .word   bl$$i
                   8382: b$yyy:                         # last block routine entry point
                   8383:        #title  s p i t b o l -- pattern matching routines
                   8384: #
                   8385: #      THE FOLLOWING SECTION CONSISTS OF THE PATTERN MATCHING
                   8386: #      ROUTINES. ALL PATTERN NODES CONTAIN A POINTER (PCODE)
                   8387: #      TO ONE OF THE ROUTINES IN THIS SECTION (P$XXX).
                   8388: #
                   8389: #      NOTE THAT THIS SECTION FOLLOWS THE B$XXX ROUTINES TO
                   8390: #      ENABLE A FAST TEST FOR THE PATTERN DATATYPE.
                   8391: #
                   8392:        .align  2
                   8393:        .word   bl$$i
                   8394: p$aaa:                         # entry to mark first pattern
                   8395: #
                   8396: #
                   8397: #      THE ENTRY CONDITIONS TO THE MATCH ROUTINE ARE AS FOLLOWS
                   8398: #      (SEE O$PMN, O$PMV, O$PMS AND PROCEDURE MATCH).
                   8399: #
                   8400: #      STACK CONTENTS.
                   8401: #
                   8402: #                            NAME BASE (O$PMN ONLY)
                   8403: #                            NAME OFFSET (O$PMN ONLY)
                   8404: #                            TYPE (0-O$PMN, 1-O$PMV, 2-O$PMS)
                   8405: #      PMHBS --------------- INITIAL CURSOR (ZERO)
                   8406: #                            INITIAL NODE POINTER
                   8407: #      XS ------------------ =NDABO (ANCHORED), =NDUNA (UNANCH)
                   8408: #
                   8409: #      REGISTER VALUES.
                   8410: #
                   8411: #           (XS)             SET AS SHOWN IN STACK DIAGRAM
                   8412: #           (XR)             POINTER TO INITIAL PATTERN NODE
                   8413: #           (WB)             INITIAL CURSOR (ZERO)
                   8414: #
                   8415: #      GLOBAL PATTERN VALUES
                   8416: #
                   8417: #           R$PMS            POINTER TO SUBJECT STRING SCBLK
                   8418: #           PMSSL            LENGTH OF SUBJECT STRING IN CHARS
                   8419: #           PMDFL            DOT FLAG, INITIALLY ZERO
                   8420: #           PMHBS            SET AS SHOWN IN STACK DIAGRAM
                   8421: #
                   8422: #      CONTROL IS PASSED BY BRANCHING THROUGH THE PCODE
                   8423: #      FIELD OF THE INITIAL PATTERN NODE (BRI (XR)).
                   8424:        #page   
                   8425: #
                   8426: #      DESCRIPTION OF ALGORITHM
                   8427: #
                   8428: #      A PATTERN STRUCTURE IS REPRESENTED AS A LINKED GRAPH
                   8429: #      OF NODES WITH THE FOLLOWING STRUCTURE.
                   8430: #
                   8431: #           +------------------------------------+
                   8432: #           I                PCODE               I
                   8433: #           +------------------------------------+
                   8434: #           I                PTHEN               I
                   8435: #           +------------------------------------+
                   8436: #           I                PARM1               I
                   8437: #           +------------------------------------+
                   8438: #           I                PARM2               I
                   8439: #           +------------------------------------+
                   8440: #
                   8441: #      PCODE IS A POINTER TO THE ROUTINE WHICH WILL PERFORM
                   8442: #      THE MATCH OF THIS PARTICULAR NODE TYPE.
                   8443: #
                   8444: #      PTHEN IS A POINTER TO THE SUCCESSOR NODE. I.E. THE NODE
                   8445: #      TO BE MATCHED IF THE ATTEMPT TO MATCH THIS NODE SUCCEEDS.
                   8446: #      IF THIS IS THE LAST NODE OF THE PATTERN PTHEN POINTS
                   8447: #      TO THE DUMMY NODE NDNTH WHICH INITIATES PATTERN EXIT.
                   8448: #
                   8449: #      PARM1, PARM2 ARE PARAMETERS WHOSE USE VARIES WITH THE
                   8450: #      PARTICULAR NODE. THEY ARE ONLY PRESENT IF REQUIRED.
                   8451: #
                   8452: #      ALTERNATIVES ARE HANDLED WITH THE SPECIAL ALTERNATIVE
                   8453: #      NODE WHOSE PARAMETER POINTS TO THE NODE TO BE MATCHED
                   8454: #      IF THERE IS A FAILURE ON THE SUCCESSOR PATH.
                   8455: #
                   8456: #      THE FOLLOWING EXAMPLE ILLUSTRATES THE MANNER IN WHICH
                   8457: #      THE STRUCTURE IS BUILT UP. THE PATTERN IS
                   8458: #
                   8459: #      (A / B / C) (D / E)   WHERE / IS ALTERNATION
                   8460: #
                   8461: #      IN THE DIAGRAM, THE NODE MARKED + REPRESENTS AN
                   8462: #      ALTERNATIVE NODE AND THE DOTTED LINE FROM A + NODE
                   8463: #      REPRESENTS THE PARAMETER POINTER TO THE ALTERNATIVE.
                   8464: #
                   8465: #      +---+     +---+     +---+     +---+
                   8466: #      I + I-----I A I-----I + I-----I D I-----
                   8467: #      +---+     +---+  I  +---+     +---+
                   8468: #        .              I    .
                   8469: #        .              I    .
                   8470: #      +---+     +---+  I  +---+
                   8471: #      I + I-----I B I--I  I E I-----
                   8472: #      +---+     +---+  I  +---+
                   8473: #        .              I
                   8474: #        .              I
                   8475: #      +---+            I
                   8476: #      I C I------------I
                   8477: #      +---+
                   8478:        #page   
                   8479: #
                   8480: #      DURING THE MATCH, THE REGISTERS ARE USED AS FOLLOWS.
                   8481: #
                   8482: #      (XR)                  POINTS TO THE CURRENT NODE
                   8483: #      (XL)                  SCRATCH
                   8484: #      (XS)                  MAIN STACK POINTER
                   8485: #      (WB)                  CURSOR (NUMBER OF CHARS MATCHED)
                   8486: #      (WA,WC)               SCRATCH
                   8487: #
                   8488: #      TO KEEP TRACK OF ALTERNATIVES, THE MAIN STACK IS USED AS
                   8489: #      A HISTORY STACK AND CONTAINS TWO WORD ENTRIES.
                   8490: #
                   8491: #      WORD 1                SAVED CURSOR VALUE
                   8492: #      WORD 2                NODE TO MATCH ON FAILURE
                   8493: #
                   8494: #      WHEN A FAILURE OCCURS, THE MOST RECENT ENTRY ON THIS
                   8495: #      STACK IS POPPED OFF TO RESTORE THE CURSOR AND POINT
                   8496: #      TO THE NODE TO BE MATCHED AS AN ALTERNATIVE. THE ENTRY
                   8497: #      AT THE BOTTOM OF THE STACK POINTS TO THE FOLLOWING
                   8498: #      SPECIAL NODES DEPENDING ON THE SCAN MODE.
                   8499: #
                   8500: #      ANCHORED MODE         THE BOTTOM ENTRY POINTS TO THE
                   8501: #                            SPECIAL NODE NDABO WHICH CAUSES AN
                   8502: #                            ABORT. THE CURSOR VALUE STORED
                   8503: #                            WITH THIS ENTRY IS ALWAYS ZERO.
                   8504: #
                   8505: #      UNANCHORED MODE       THE BOTTOM ENTRY POINTS TO THE
                   8506: #                            SPECIAL NODE NDUNA WHICH MOVES THE
                   8507: #                            ANCHOR POINT AND RESTARTS THE MATCH
                   8508: #                            THE CURSOR SAVED WITH THIS ENTRY
                   8509: #                            IS THE NUMBER OF CHARACTERS WHICH
                   8510: #                            LIE BEFORE THE INITIAL ANCHOR POINT
                   8511: #                            (I.E. THE NUMBER OF ANCHOR MOVES).
                   8512: #                            THIS ENTRY IS THREE WORDS LONG AND
                   8513: #                            ALSO CONTAINS THE INITIAL PATTERN.
                   8514: #
                   8515: #      ENTRIES ARE MADE ON THIS HISTORY STACK BY ALTERNATIVE
                   8516: #      NODES AND BY SOME SPECIAL COMPOUD PATTERNS AS DESCRIBED
                   8517: #      LATER ON. THE FOLLOWING GLOBAL LOCATIONS ARE USED DURING
                   8518: #      PATTERN MATCHING.
                   8519: #
                   8520: #      R$PMS                 POINTER TO SUBJECT STRING
                   8521: #      PMSSL                 LENGTH OF SUBJECT STRING
                   8522: #      PMDFL                 FLAG SET NON-ZERO FOR DOT PATTERNS
                   8523: #      PMHBS                 BASE PTR FOR CURRENT HISTORY STACK
                   8524: #
                   8525: #      THE FOLLOWING EXIT POINTS ARE AVAILABLE TO MATCH ROUTINES
                   8526: #
                   8527: #      SUCCP                 SUCCESS IN MATCHING CURRENT NODE
                   8528: #      FAILP                 FAILURE IN MATCHING CURRENT NODE
                   8529:        #page   
                   8530: #
                   8531: #      COMPOUND PATTERNS
                   8532: #
                   8533: #      SOME PATTERNS HAVE IMPLICIT ALTERNATIVES AND THEIR
                   8534: #      REPRESENTATION IN THE PATTERN STRUCTURE CONSISTS OF A
                   8535: #      LINKED SET OF NODES AS INDICATED BY THESE DIAGRAMS.
                   8536: #
                   8537: #      AS BEFORE, THE + REPRESENTS AN ALTERNATIVE NODE AND
                   8538: #      THE DOTTED LINE FROM A + NODE IS THE PARAMETER POINTER
                   8539: #      TO THE ALTERNATIVE PATTERN.
                   8540: #
                   8541: #      ARB
                   8542: #      ---
                   8543: #
                   8544: #           +---+            THIS NODE (P$ARB) MATCHES NULL
                   8545: #           I B I-----       AND STACKS CURSOR, SUCCESSOR PTR,
                   8546: #           +---+            CURSOR (COPY) AND A PTR TO NDARC.
                   8547: #
                   8548: #
                   8549: #
                   8550: #
                   8551: #      BAL
                   8552: #      ---
                   8553: #
                   8554: #           +---+            THE P$BAL NODE SCANS A BALANCED
                   8555: #           I B I-----       STRING AND THEN STACKS A POINTER
                   8556: #           +---+            TO ITSELF ON THE HISTORY STACK.
                   8557:        #page   
                   8558: #
                   8559: #      COMPOUND PATTERN STRUCTURES (CONTINUED)
                   8560: #
                   8561: #
                   8562: #      ARBNO
                   8563: #      -----
                   8564: #
                   8565: #           +---+            THIS ALTERNATIVE NODE MATCHES NULL
                   8566: #      +----I + I-----       THE FIRST TIME AND STACKS A POINTER
                   8567: #      I    +---+            TO THE ARGUMENT PATTERN X.
                   8568: #      I      .
                   8569: #      I      .
                   8570: #      I    +---+            NODE (P$ABA) TO STACK CURSOR
                   8571: #      I    I A I            AND HISTORY STACK BASE PTR.
                   8572: #      I    +---+
                   8573: #      I      I
                   8574: #      I      I
                   8575: #      I    +---+            THIS IS THE ARGUMENT PATTERN. AS
                   8576: #      I    I X I            INDICATED, THE SUCCESSOR OF THE
                   8577: #      I    +---+            PATTERN IS THE P$ABC NODE
                   8578: #      I      I
                   8579: #      I      I
                   8580: #      I    +---+            THIS NODE (P$ABC) POPS PMHBS,
                   8581: #      +----I C I            STACKS OLD PMHBS AND PTR TO NDABD
                   8582: #           +---+            (UNLESS OPTIMISATION HAS OCCURRED)
                   8583: #
                   8584: #      STRUCTURE AND EXECUTION OF THIS PATTERN RESEMBLE THOSE OF
                   8585: #      RECURSIVE PATTERN MATCHING AND IMMEDIATE ASSIGNMENT.
                   8586: #      THE ALTERNATIVE NODE AT THE HEAD OF THE STRUCTURE MATCHES
                   8587: #      NULL INITIALLY BUT ON SUBSEQUENT FAILURE ENSURES ATTEMPT
                   8588: #      TO MATCH THE ARGUMENT.  BEFORE THE ARGUMENT IS MATCHED
                   8589: #      P$ABA STACKS THE CURSOR,PMHBS AND A PTR TO P$ABB.  IF
                   8590: #      THE ARGUMENT CANT BE MATCHED , P$ABB REMOVES THIS SPECIAL
                   8591: #      STACK ENTRY AND FAILS.
                   8592: #      IF ARGUMENT IS MATCHED , P$ABC RESTORES THE OUTER PMHBS
                   8593: #      VALUE (SAVED BY P$ABA) .  THEN IF THE ARGUMENT HAS LEFT
                   8594: #      ALTERNATIVES ON STACK IT STACKS THE INNER VALUE OF PMHBS
                   8595: #      AND A PTR TO NDABD. IF ARGUMENT LEFT NOTHING ON THE STACK
                   8596: #      IT OPTIMISES BY REMOVING ITEMS STACKED BY P$ABA.  FINALLY
                   8597: #      A CHECK IS MADE THAT ARGUMENT MATCHED MORE THAN THE NULL
                   8598: #      STRING (CHECK IS INTENDED TO PREVENT USELESS LOOPING).
                   8599: #      IF SO THE SUCCESSOR IS AGAIN THE ALTERNATIVE NODE AT THE
                   8600: #      HEAD OF THE STRUCTURE , ENSURING A POSSIBLE EXTRA ATTEMPT
                   8601: #      TO MATCH THE ARG IF NECESSARY.  IF NOT , THE SUCCESSOR TO
                   8602: #      ALTERNATIVE IS TAKEN SO AS TO TERMINATE THE LOOP.  P$ABD
                   8603: #      RESTORES INNER PMHBS PTR AND FAILS , THUS TRYING TO MATCH
                   8604: #      ALTERNATIVES LEFT BY THE ARBNO ARGUMENT.
                   8605:        #page   
                   8606: #
                   8607: #      COMPOUND PATTERN STRUCTURES (CONTINUED)
                   8608: #
                   8609: #      BREAKX
                   8610: #      ------
                   8611: #
                   8612: #           +---+            THIS NODE IS A BREAK NODE FOR
                   8613: #      +----I B I            THE ARGUMENT TO BREAKX, IDENTICAL
                   8614: #      I    +---+            TO AN ORDINARY BREAK NODE.
                   8615: #      I      I
                   8616: #      I      I
                   8617: #      I    +---+            THIS ALTERNATIVE NODE STACKS A
                   8618: #      I    I + I-----       POINTER TO THE BREAKX NODE TO
                   8619: #      I    +---+            ALLOW FOR SUBSEQUENT FAILURE
                   8620: #      I      .
                   8621: #      I      .
                   8622: #      I    +---+            THIS IS THE BREAKX NODE ITSELF. IT
                   8623: #      +----I X I            MATCHES ONE CHARACTER AND THEN
                   8624: #           +---+            PROCEEDS BACK TO THE BREAK NODE.
                   8625: #
                   8626: #
                   8627: #
                   8628: #
                   8629: #      FENCE
                   8630: #      -----
                   8631: #
                   8632: #           +---+            THE FENCE NODE MATCHES NULL AND
                   8633: #           I F I-----       STACKS A POINTER TO NODE NDABO TO
                   8634: #           +---+            ABORT ON A SUBSEQUENT REMATCH
                   8635: #
                   8636: #
                   8637: #
                   8638: #
                   8639: #      SUCCEED
                   8640: #      -------
                   8641: #
                   8642: #           +---+            THE NODE FOR SUCCEED MATCHES NULL
                   8643: #           I S I-----       AND STACKS A POINTER TO ITSELF
                   8644: #           +---+            TO REPEAT THE MATCH ON A FAILURE.
                   8645:        #page   
                   8646: #
                   8647: #      COMPOUND PATTERNS (CONTINUED)
                   8648: #
                   8649: #      BINARY DOT (PATTERN ASSIGNMENT)
                   8650: #      -------------------------------
                   8651: #
                   8652: #           +---+            THIS NODE (P$PAA) SAVES THE CURRENT
                   8653: #           I A I            CURSOR AND A POINTER TO THE
                   8654: #           +---+            SPECIAL NODE NDPAB ON THE STACK.
                   8655: #             I
                   8656: #             I
                   8657: #           +---+            THIS IS THE STRUCTURE FOR THE
                   8658: #           I X I            PATTERN LEFT ARGUMENT OF THE
                   8659: #           +---+            PATTERN ASSIGNMENT CALL.
                   8660: #             I
                   8661: #             I
                   8662: #           +---+            THIS NODE (P$PAC) SAVES THE CURSOR,
                   8663: #           I C I-----       A PTR TO ITSELF, THE CURSOR (COPY)
                   8664: #           +---+            AND A PTR TO NDPAD ON THE STACK.
                   8665: #
                   8666: #
                   8667: #      THE FUNCTION OF THE MATCH ROUTINE FOR NDPAB (P$PAB)
                   8668: #      IS SIMPLY TO UNSTACK ITSELF AND FAIL BACK ONTO THE STACK.
                   8669: #
                   8670: #      THE MATCH ROUTINE FOR P$PAC ALSO SETS THE GLOBAL PATTERN
                   8671: #      FLAG PMDFL NON-ZERO TO INDICATE THAT PATTERN ASSIGNMENTS
                   8672: #      MAY HAVE OCCURED IN THE PATTERN MATCH
                   8673: #
                   8674: #      IF PMDFL IS SET AT THE END OF THE MATCH (SEE P$NTH), THE
                   8675: #      HISTORY STACK IS SCANNED FOR MATCHING NDPAB-NDPAD PAIRS
                   8676: #      AND THE CORRESPONDING PATTERN ASSIGNMENTS ARE EXECUTED.
                   8677: #
                   8678: #      THE FUNCTION OF THE MATCH ROUTINE FOR NDPAD (P$PAD)
                   8679: #      IS SIMPLY TO REMOVE ITS ENTRY FROM THE STACK AND FAIL.
                   8680: #      THIS INCLUDES REMOVING THE SPECIAL NODE POINTER STORED
                   8681: #      IN ADDITION TO THE STANDARD TWO ENTRIES ON THE STACK.
                   8682:        #page   
                   8683: #
                   8684: #      COMPOUNT PATTERN STRUCTURES (CONTINUED)
                   8685: #
                   8686: #      FENCE (FUNCTION)
                   8687: #      ----------------
                   8688: #
                   8689: #           +---+            THIS NODE (P$FNA) SAVES THE
                   8690: #           I A I            CURRENT HISTORY STACK AND A
                   8691: #           +---+            POINTER TO NDFNB ON THE STACK.
                   8692: #             I
                   8693: #             I
                   8694: #           +---+            THIS IS THE PATTERN STRUCTURE
                   8695: #           I X I            GIVEN AS THE ARGUMENT TO THE
                   8696: #           +---+            FENCE FUNCTION.
                   8697: #             I
                   8698: #             I
                   8699: #           +---+            THIS NODE P$FNC RESTORES THE OUTER
                   8700: #           I C I            HISTORY STACK PTR SAVED IN P$FNA,
                   8701: #           +---+            AND STACKS THE INNER STACK BASE
                   8702: #                            PTR AND A POINTER TO NDFND ON THE
                   8703: #                            STACK.
                   8704: #
                   8705: #      NDFNB (F$FNB) SIMPLY IS THE FAILURE EXIT FOR PATTERN
                   8706: #      ARGUMENT FAILURE, AND IT POPS ITSELF AND FAILS ONTO THE
                   8707: #      STACK.
                   8708: #
                   8709: #      THE MATCH ROUTINE P$FNC ALLOWS FOR AN OPTIMIZATION WHEN
                   8710: #      THE FENCE PATTERN LEAVES NO ALTERNATIVES.  IN THIS CASE,
                   8711: #      THE NDFNB ENTRY IS POPPED, AND THE MATCH CONTINUES.
                   8712: #
                   8713: #      NDFND (P$FND) IS ENTERED WHEN THE PATTERN FAILS AFTER
                   8714: #      GOING THROUGH A NON-OPTIMIZED P$FNC, AND IT POPS THE
                   8715: #      STACK BACK PAST THE INNTER STACK BASE CREATED BY P$FNA
                   8716:        #page   
                   8717: #
                   8718: #      COMPOUND PATTERNS (CONTINUED)
                   8719: #
                   8720: #      EXPRESSION PATTERNS (RECURSIVE PATTERN MATCHES)
                   8721: #      -----------------------------------------------
                   8722: #
                   8723: #      INITIAL ENTRY FOR A PATTERN NODE IS TO THE ROUTINE P$EXA.
                   8724: #      IF THE EVALUATED RESULT OF THE EXPRESSION IS ITSELF A
                   8725: #      PATTERN, THEN THE FOLLOWING STEPS ARE TAKEN TO ARRANGE
                   8726: #      FOR PROPER RECURSIVE PROCESSING.
                   8727: #
                   8728: #      1)   A POINTER TO THE CURRENT NODE (THE P$EXA NODE) IS
                   8729: #           STORED ON THE HISTORY STACK WITH A DUMMY CURSOR.
                   8730: #
                   8731: #      2)   A SPECIAL HISTORY STACK ENTRY IS MADE IN WHICH THE
                   8732: #           NODE POINTER POINTS TO NDEXB, AND THE CURSOR VALUE
                   8733: #           IS THE SAVED VALUE OF PMHBS ON ENTRY TO THIS NODE.
                   8734: #           THE MATCH ROUTINE FOR NDEXB (P$EXB) RESTORES PMHBS
                   8735: #           FROM THIS CURSOR ENTRY, POPS OFF THE P$EXA NODE
                   8736: #           POINTER AND FAILS.
                   8737: #
                   8738: #      3)   THE RESULTING HISTORY STACK POINTER IS SAVED IN
                   8739: #           PMHBS TO ESTABLISH A NEW LEVEL OF HISTORY STACK.
                   8740: #
                   8741: #      AFTER MATCHING A PATTERN, THE END OF MATCH ROUTINE GETS
                   8742: #      CONTROL (P$NTH). THIS ROUTINE PROCEEDS AS FOLLOWS.
                   8743: #
                   8744: #      1)   LOAD THE CURRENT VALUE OF PMHBS AND RECOGNIZE THE
                   8745: #           OUTER LEVEL CASE BY THE FACT THAT THE ASSOCIATED
                   8746: #           CURSOR IN THIS CASE IS THE PATTERN MATCH TYPE CODE
                   8747: #           WHICH IS LESS THAN 3. TERMINATE THE MATCH IN THIS
                   8748: #           CASE AND CONTINUE EXECUTION OF THE PROGRAM.
                   8749: #
                   8750: #      2)   OTHERWISE MAKE A SPECIAL HISTORY STACK ENTRY IN
                   8751: #           WHICH THE NODE POINTER POINTS TO THE SPECIAL NODE
                   8752: #           NDEXC AND THE CURSOR IS THE CURRENT VALUE OF PMHBS.
                   8753: #           THE MATCH ROUTINE FOR NDEXC (P$EXC) RESETS PMHBS TO
                   8754: #           THIS (INNER) VALUE AND AND THEN FAILS.
                   8755: #
                   8756: #      3)   USING THE HISTORY STACK ENTRY MADE ON STARTING THE
                   8757: #           EXPRESSION (ACCESSIBLE WITH THE CURRENT VALUE OF
                   8758: #           PMHBS), RESTORE THE P$EXA NODE POINTER AND THE OLD
                   8759: #           PMHBS SETTING. TAKE THE SUCCESSOR AND CONTINUE.
                   8760: #
                   8761: #      AN OPTIMIZATION IS POSSIBLE IF THE EXPRESSION PATTERN
                   8762: #      MAKES NO ENTRIES ON THE HISTORY STACK. IN THIS CASE,
                   8763: #      INSTEAD OF BUILDING THE P$EXC NODE IN STEP 2, IT IS MORE
                   8764: #      EFFICIENT TO SIMPLY POP OFF THE P$EXB ENTRY AND ITS
                   8765: #      ASSOCIATED NODE POINTER. THE EFFECT IS THE SAME.
                   8766:        #page   
                   8767: #
                   8768: #      COMPOUND PATTERNS (CONTINUED)
                   8769: #
                   8770: #      BINARY DOLLAR (IMMEDIATE ASSIGNMENT)
                   8771: #      ------------------------------------
                   8772: #
                   8773: #           +---+            THIS NODE (P$IMA) STACKS THE CURSOR
                   8774: #           I A I            PMHBS AND A PTR TO NDIMB AND RESETS
                   8775: #           +---+            THE STACK PTR PMHBS.
                   8776: #             I
                   8777: #             I
                   8778: #           +---+            THIS IS THE LEFT STRUCTURE FOR THE
                   8779: #           I X I            PATTERN LEFT ARGUMENT OF THE
                   8780: #           +---+            IMMEDIATE ASSIGNMENT CALL.
                   8781: #             I
                   8782: #             I
                   8783: #           +---+            THIS NODE (P$IMC) PERFORMS THE
                   8784: #           I C I-----       ASSIGNMENT, POPS PMHBS AND STACKS
                   8785: #           +---+            THE OLD PMHBS AND A PTR TO NDIMD.
                   8786: #
                   8787: #
                   8788: #      THE STRUCTURE AND EXECUTION OF THIS PATTERN ARE SIMILAR
                   8789: #      TO THOSE OF THE RECURSIVE EXPRESSION PATTERN MATCHING.
                   8790: #
                   8791: #      THE MATCH ROUTINE FOR NDIMB (P$IMB) RESTORES THE OUTER
                   8792: #      LEVEL VALUE OF PMHBS, UNSTACKS THE SAVED CURSOR AND FAILS
                   8793: #
                   8794: #      THE MATCH ROUTINE P$IMC USES THE CURRENT VALUE OF PMHBS
                   8795: #      TO LOCATE THE P$IMB ENTRY. THIS ENTRY IS USED TO MAKE
                   8796: #      THE ASSIGNMENT AND RESTORE THE OUTER LEVEL VALUE OF
                   8797: #      PMHBS. FINALLY, THE INNER LEVEL VALUE OF PMHBS AND A
                   8798: #      POINTER TO THE SPECIAL NODE NDIMD ARE STACKED.
                   8799: #
                   8800: #      THE MATCH ROUTINE FOR NDIMD (P$IMD) RESTORES THE INNER
                   8801: #      LEVEL VALUE OF PMHBS AND FAILS BACK INTO THE STACK.
                   8802: #
                   8803: #      AN OPTIMIZATION OCCURS IF THE INNER PATTERN MAKES NO
                   8804: #      ENTRIES ON THE HISTORY STACK. IN THIS CASE, P$IMC POPS
                   8805: #      THE P$IMB ENTRY INSTEAD OF MAKING A P$IMD ENTRY.
                   8806:        #page   
                   8807: #
                   8808: #      ARBNO
                   8809: #
                   8810: #      SEE COMPOUND PATTERNS SECTION FOR STUCTURE AND
                   8811: #      ALGORITHM FOR MATCHING THIS NODE TYPE.
                   8812: #
                   8813: #      NO PARAMETERS
                   8814: #
                   8815:        .align  2
                   8816:        .word   bl$p0
                   8817: p$aba:                         # p0blk
                   8818:        movl    r7,-(sp)        # stack cursor
                   8819:        movl    r9,-(sp)        # stack dummy node ptr
                   8820:        movl    pmhbs,-(sp)     # stack old stack base ptr
                   8821:        movl    $ndabb,-(sp)    # stack ptr to node ndabb
                   8822:        movl    sp,pmhbs        # store new stack base ptr
                   8823:        jmp     succp           # succeed
                   8824:        #page   
                   8825: #
                   8826: #      ARBNO (REMOVE P$ABA SPECIAL STACK ENTRY)
                   8827: #
                   8828: #      NO PARAMETERS (DUMMY PATTERN)
                   8829: #
                   8830: p$abb:                         # entry point
                   8831:        movl    r7,pmhbs        # restore history stack base ptr
                   8832:        jmp     flpop           # fail and pop dummy node ptr
                   8833:        #page   
                   8834: #
                   8835: #      ARBNO (CHECK IF ARG MATCHED NULL STRING)
                   8836: #
                   8837: #      NO PARAMETERS (DUMMY PATTERN)
                   8838: #
                   8839:        .align  2
                   8840:        .word   bl$p0
                   8841: p$abc:                         # p0blk
                   8842:        movl    pmhbs,r10       # keep p$abb stack base
                   8843:        movl    4*3(r10),r6     # load initial cursor
                   8844:        movl    4*1(r10),pmhbs  # restore outer stack base ptr
                   8845:        cmpl    r10,sp          # jump if no history stack entries
                   8846:        beqlu   pabc1
                   8847:        movl    r10,-(sp)       # else save inner pmhbs entry
                   8848:        movl    $ndabd,-(sp)    # stack ptr to special node ndabd
                   8849:        jmp     pabc2           # merge
                   8850: #
                   8851: #      OPTIMISE CASE OF NO EXTRA ENTRIES ON STACK FROM ARBNO ARG
                   8852: #
                   8853: pabc1: addl2   $4*num04,sp     # remove ndabb entry and cursor
                   8854: #
                   8855: #      MERGE TO CHECK FOR MATCHING OF NULL STRING
                   8856: #
                   8857: pabc2: cmpl    r6,r7           # allow further attempt if non-null
                   8858:        beqlu   0f
                   8859:        jmp     succp
                   8860: 0:             
                   8861:        movl    4*pthen(r9),r9  # bypass alternative node so as to ..
                   8862:        jmp     succp           # ... refuse further match attempts
                   8863:        #page   
                   8864: #
                   8865: #      ARBNO (TRY FOR ALTERNATIVES IN ARBNO ARGUMENT)
                   8866: #
                   8867: #      NO PARAMETERS (DUMMY PATTERN)
                   8868: #
                   8869: p$abd:                         # entry point
                   8870:        movl    r7,pmhbs        # restore inner stack base ptr
                   8871:        jmp     failp           # and fail
                   8872:        #page   
                   8873: #
                   8874: #      ABORT
                   8875: #
                   8876: #      NO PARAMETERS
                   8877: #
                   8878:        .align  2
                   8879:        .word   bl$p0
                   8880: p$abo:                         # p0blk
                   8881:        jmp     exfal           # signal statement failure
                   8882:        #page   
                   8883: #
                   8884: #      ALTERNATION
                   8885: #
                   8886: #      PARM1                 ALTERNATIVE NODE
                   8887: #
                   8888:        .align  2
                   8889:        .word   bl$p1
                   8890: p$alt:                         # p1blk
                   8891:        movl    r7,-(sp)        # stack cursor
                   8892:        movl    4*parm1(r9),-(sp)# stack pointer to alternative
                   8893:        jsb     sbchk           # check for stack overflow
                   8894:        jmp     succp           # if all ok, then succeed
                   8895:        #page   
                   8896: #
                   8897: #      ANY (ONE CHARACTER ARGUMENT) (1-CHAR STRING ALSO)
                   8898: #
                   8899: #      PARM1                 CHARACTER ARGUMENT
                   8900: #
                   8901:        .align  2
                   8902:        .word   bl$p1
                   8903: p$ans:                         # p1blk
                   8904:        cmpl    r7,pmssl        # fail if no chars left
                   8905:        bnequ   0f
                   8906:        jmp     failp
                   8907: 0:             
                   8908:        movl    r$pms,r10       # else point to subject string
                   8909:        movab   cfp$f(r10)[r7],r10 # point to current character
                   8910:        movzbl  (r10),r6        # load current character
                   8911:        cmpl    r6,4*parm1(r9)  # fail if no match
                   8912:        beqlu   0f
                   8913:        jmp     failp
                   8914: 0:             
                   8915:        incl    r7              # else bump cursor
                   8916:        jmp     succp           # and succeed
                   8917:        #page   
                   8918: #
                   8919: #      ANY (MULTI-CHARACTER ARGUMENT CASE)
                   8920: #
                   8921: #      PARM1                 POINTER TO CTBLK
                   8922: #      PARM2                 BIT MASK TO SELECT BIT IN CTBLK
                   8923: #
                   8924:        .align  2
                   8925:        .word   bl$p2
                   8926: p$any:                         # p2blk
                   8927: #
                   8928: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   8929: #
                   8930: pany1: cmpl    r7,pmssl        # fail if no characters left
                   8931:        bnequ   0f
                   8932:        jmp     failp
                   8933: 0:             
                   8934:        movl    r$pms,r10       # else point to subject string
                   8935:        movab   cfp$f(r10)[r7],r10 # get char ptr to current character
                   8936:        movzbl  (r10),r6        # load current character
                   8937:        movl    4*parm1(r9),r10 # point to ctblk
                   8938:        moval   0[r6],r6        # change to byte offset
                   8939:        addl2   r6,r10          # point to entry in ctblk
                   8940:        movl    4*ctchs(r10),r6 # load word from ctblk
                   8941:        mcoml   4*parm2(r9),r11 # and with selected bit
                   8942:        bicl2   r11,r6
                   8943:        tstl    r6              # fail if no match
                   8944:        bnequ   0f
                   8945:        jmp     failp
                   8946: 0:             
                   8947:        incl    r7              # else bump cursor
                   8948:        jmp     succp           # and succeed
                   8949:        #page   
                   8950: #
                   8951: #      ANY (EXPRESSION ARGUMENT)
                   8952: #
                   8953: #      PARM1                 EXPRESSION POINTER
                   8954: #
                   8955:        .align  2
                   8956:        .word   bl$p1
                   8957: p$ayd:                         # p1blk
                   8958:        jsb     evals           # evaluate string argument
                   8959:        .long   er_043          # any evaluated argument is not string
                   8960:        .long   failp           # fail if evaluation failure
                   8961:        .long   pany1           # merge multi-char case if ok
                   8962:        #page   
                   8963: #
                   8964: #      P$ARB                 INITIAL ARB MATCH
                   8965: #
                   8966: #      NO PARAMETERS
                   8967: #
                   8968: #      THE P$ARB NODE IS PART OF A COMPOUND PATTERN STRUCTURE
                   8969: #      FOR AN ARB PATTERN (SEE DESCRIPTION OF COMPOUND PATTERNS)
                   8970: #
                   8971:        .align  2
                   8972:        .word   bl$p0
                   8973: p$arb:                         # p0blk
                   8974:        movl    4*pthen(r9),r9  # load successor pointer
                   8975:        movl    r7,-(sp)        # stack dummy cursor
                   8976:        movl    r9,-(sp)        # stack successor pointer
                   8977:        movl    r7,-(sp)        # stack cursor
                   8978:        movl    $ndarc,-(sp)    # stack ptr to special node ndarc
                   8979:        movl    (r9),r11        # execute next node matching null
                   8980:        jmp     (r11)
                   8981:        #page   
                   8982: #
                   8983: #      P$ARC                 EXTEND ARB MATCH
                   8984: #
                   8985: #      NO PARAMETERS (DUMMY PATTERN)
                   8986: #
                   8987: p$arc:                         # entry point
                   8988:        cmpl    r7,pmssl        # fail and pop stack to successor
                   8989:        bnequ   0f
                   8990:        jmp     flpop
                   8991: 0:             
                   8992:        incl    r7              # else bump cursor
                   8993:        movl    r7,-(sp)        # stack updated cursor
                   8994:        movl    r9,-(sp)        # restack pointer to ndarc node
                   8995:        movl    4*2(sp),r9      # load successor pointer
                   8996:        movl    (r9),r11        # off to reexecute successor node
                   8997:        jmp     (r11)
                   8998:        #page   
                   8999: #
                   9000: #      BAL
                   9001: #
                   9002: #      NO PARAMETERS
                   9003: #
                   9004: #      THE P$BAL NODE IS PART OF THE COMPOUND STRUCTURE BUILT
                   9005: #      FOR BAL (SEE SECTION ON COMPOUND PATTERNS).
                   9006: #
                   9007:        .align  2
                   9008:        .word   bl$p0
                   9009: p$bal:                         # p0blk
                   9010:        clrl    r8              # zero parentheses level counter
                   9011:        movl    r$pms,r10       # point to subject string
                   9012:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9013:        jmp     pbal2           # jump into scan loop
                   9014: #
                   9015: #      LOOP TO SCAN OUT CHARACTERS
                   9016: #
                   9017: pbal1: movzbl  (r10)+,r6       # load next character, bump pointer
                   9018:        incl    r7              # push cursor for character
                   9019:        cmpl    r6,$ch$pp       # jump if left paren
                   9020:        beqlu   pbal3
                   9021:        cmpl    r6,$ch$rp       # jump if right paren
                   9022:        beqlu   pbal4
                   9023:        tstl    r8              # else succeed if at outer level
                   9024:        beqlu   pbal5
                   9025: #
                   9026: #      HERE AFTER PROCESSING ONE CHARACTER
                   9027: #
                   9028: pbal2: cmpl    r7,pmssl        # loop back unless end of string
                   9029:        bnequ   pbal1
                   9030:        jmp     failp           # in which case, fail
                   9031: #
                   9032: #      HERE ON LEFT PAREN
                   9033: #
                   9034: pbal3: incl    r8              # bump paren level
                   9035:        jmp     pbal2           # loop back to check end of string
                   9036: #
                   9037: #      HERE FOR RIGHT PAREN
                   9038: #
                   9039: pbal4: tstl    r8              # fail if no matching left paren
                   9040:        bnequ   0f
                   9041:        jmp     failp
                   9042: 0:             
                   9043:        decl    r8              # else decrement level counter
                   9044:        tstl    r8              # loop back if not at outer level
                   9045:        bnequ   pbal2
                   9046: #
                   9047: #      HERE AFTER SUCCESSFULLY SCANNING A BALANCED STRING
                   9048: #
                   9049: pbal5: movl    r7,-(sp)        # stack cursor
                   9050:        movl    r9,-(sp)        # stack ptr to bal node for extend
                   9051:        jmp     succp           # and succeed
                   9052:        #page   
                   9053: #
                   9054: #      BREAK (EXPRESSION ARGUMENT)
                   9055: #
                   9056: #      PARM1                 EXPRESSION POINTER
                   9057: #
                   9058:        .align  2
                   9059:        .word   bl$p1
                   9060: p$bkd:                         # p1blk
                   9061:        jsb     evals           # evaluate string expression
                   9062:        .long   er_044          # break evaluated argument is not string
                   9063:        .long   failp           # fail if evaluation fails
                   9064:        .long   pbrk1           # merge with multi-char case if ok
                   9065:        #page   
                   9066: #
                   9067: #      BREAK (ONE CHARACTER ARGUMENT)
                   9068: #
                   9069: #      PARM1                 CHARACTER ARGUMENT
                   9070: #
                   9071:        .align  2
                   9072:        .word   bl$p1
                   9073: p$bks:                         # p1blk
                   9074:        movl    pmssl,r8        # get subject string length
                   9075:        subl2   r7,r8           # get number of characters left
                   9076:        tstl    r8              # fail if no characters left
                   9077:        bnequ   0f
                   9078:        jmp     failp
                   9079: 0:             
                   9080:                                # set counter for chars left
                   9081:        movl    r$pms,r10       # point to subject string
                   9082:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9083: #
                   9084: #      LOOP TO SCAN TILL BREAK CHARACTER FOUND
                   9085: #
                   9086: pbks1: movzbl  (r10)+,r6       # load next char, bump pointer
                   9087:        cmpl    r6,4*parm1(r9)  # succeed if break character found
                   9088:        bnequ   0f
                   9089:        jmp     succp
                   9090: 0:             
                   9091:        incl    r7              # else push cursor
                   9092:        sobgtr  r8,pbks1        # loop back if more to go
                   9093:        jmp     failp           # fail if end of string, no break chr
                   9094:        #page   
                   9095: #
                   9096: #      BREAK (MULTI-CHARACTER ARGUMENT)
                   9097: #
                   9098: #      PARM1                 POINTER TO CTBLK
                   9099: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9100: #
                   9101:        .align  2
                   9102:        .word   bl$p2
                   9103: p$brk:                         # p2blk
                   9104: #
                   9105: #      EXPRESSION ARGUMENT MERGES HERE
                   9106: #
                   9107: pbrk1: movl    pmssl,r8        # load subject string length
                   9108:        subl2   r7,r8           # get number of characters left
                   9109:        tstl    r8              # fail if no characters left
                   9110:        bnequ   0f
                   9111:        jmp     failp
                   9112: 0:             
                   9113:                                # set counter for characters left
                   9114:        movl    r$pms,r10       # else point to subject string
                   9115:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9116:        movl    r9,psave        # save node pointer
                   9117: #
                   9118: #      LOOP TO SEARCH FOR BREAK CHARACTER
                   9119: #
                   9120: pbrk2: movzbl  (r10)+,r6       # load next char, bump pointer
                   9121:        movl    4*parm1(r9),r9  # load pointer to ctblk
                   9122:        moval   0[r6],r6        # convert to byte offset
                   9123:        addl2   r6,r9           # point to ctblk entry
                   9124:        movl    4*ctchs(r9),r6  # load ctblk word
                   9125:        movl    psave,r9        # restore node pointer
                   9126:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9127:        bicl2   r11,r6
                   9128:        tstl    r6              # succeed if break character found
                   9129:        beqlu   0f
                   9130:        jmp     succp
                   9131: 0:             
                   9132:        incl    r7              # else push cursor
                   9133:        sobgtr  r8,pbrk2        # loop back unless end of string
                   9134:        jmp     failp           # fail if end of string, no break chr
                   9135:        #page   
                   9136: #
                   9137: #      BREAKX (EXTENSION)
                   9138: #
                   9139: #      THIS IS THE ENTRY WHICH CAUSES AN EXTENSION OF A BREAKX
                   9140: #      MATCH WHEN FAILURE OCCURS. SEE SECTION ON COMPOUND
                   9141: #      PATTERNS FOR FULL DETAILS OF BREAKX MATCHING.
                   9142: #
                   9143: #      NO PARAMETERS
                   9144: #
                   9145:        .align  2
                   9146:        .word   bl$p0
                   9147: p$bkx:                         # p0blk
                   9148:        incl    r7              # step cursor past previous break chr
                   9149:        jmp     succp           # succeed to rematch break
                   9150:        #page   
                   9151: #
                   9152: #      BREAKX (EXPRESSION ARGUMENT)
                   9153: #
                   9154: #      SEE SECTION ON COMPOUND PATTERNS FOR FULL STRUCTURE OF
                   9155: #      BREAKX PATTERN. THE ACTUAL CHARACTER MATCHING USES A
                   9156: #      BREAK NODE. HOWEVER, THE ENTRY FOR THE EXPRESSION
                   9157: #      ARGUMENT CASE IS SEPARATED TO GET PROPER ERROR MESSAGES.
                   9158: #
                   9159: #      PARM1                 EXPRESSION POINTER
                   9160: #
                   9161:        .align  2
                   9162:        .word   bl$p1
                   9163: p$bxd:                         # p1blk
                   9164:        jsb     evals           # evaluate string argument
                   9165:        .long   er_045          # breakx evaluated argument is not string
                   9166:        .long   failp           # fail if evaluation fails
                   9167:        .long   pbrk1           # merge with break if all ok
                   9168:        #page   
                   9169: #
                   9170: #      CURSOR ASSIGNMENT
                   9171: #
                   9172: #      PARM1                 NAME BASE
                   9173: #      PARM2                 NAME OFFSET
                   9174: #
                   9175:        .align  2
                   9176:        .word   bl$p2
                   9177: p$cas:                         # p2blk
                   9178:        movl    r9,-(sp)        # save node pointer
                   9179:        movl    r7,-(sp)        # save cursor
                   9180:        movl    4*parm1(r9),r10 # load name base
                   9181:        movl    r7,r5           # load cursor as integer
                   9182:        movl    4*parm2(r9),r7  # load name offset
                   9183:        jsb     icbld           # get icblk for cursor value
                   9184:        movl    r7,r6           # move name offset
                   9185:        movl    r9,r7           # move value to assign
                   9186:        jsb     asinp           # perform assignment
                   9187:        .long   flpop           # fail on assignment failure
                   9188:        movl    (sp)+,r7        # else restore cursor
                   9189:        movl    (sp)+,r9        # restore node pointer
                   9190:        jmp     succp           # and succeed matching null
                   9191:        #page   
                   9192: #
                   9193: #      EXPRESSION NODE (P$EXA, INITIAL ENTRY)
                   9194: #
                   9195: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9196: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9197: #
                   9198: #      PARM1                 EXPRESSION POINTER
                   9199: #
                   9200:        .align  2
                   9201:        .word   bl$p1
                   9202: p$exa:                         # p1blk
                   9203:        jsb     evalp           # evaluate expression
                   9204:        .long   failp           # fail if evaluation fails
                   9205:        cmpl    r6,$p$aaa       # jump if result is not a pattern
                   9206:        blequ   pexa1
                   9207: #
                   9208: #      HERE IF RESULT OF EXPRESSION IS A PATTERN
                   9209: #
                   9210:        movl    r7,-(sp)        # stack dummy cursor
                   9211:        movl    r9,-(sp)        # stack ptr to p$exa node
                   9212:        movl    pmhbs,-(sp)     # stack history stack base ptr
                   9213:        movl    $ndexb,-(sp)    # stack ptr to special node ndexb
                   9214:        movl    sp,pmhbs        # store new stack base pointer
                   9215:        movl    r10,r9          # copy node pointer
                   9216:        movl    (r9),r11        # match first node in expression pat
                   9217:        jmp     (r11)
                   9218: #
                   9219: #      HERE IF RESULT OF EXPRESSION IS NOT A PATTERN
                   9220: #
                   9221: pexa1: cmpl    r6,$b$scl       # jump if it is already a string
                   9222:        beqlu   pexa2
                   9223:        movl    r10,-(sp)       # else stack result
                   9224:        movl    r9,r10          # save node pointer
                   9225:        jsb     gtstg           # convert result to string
                   9226:        .long   er_046          # expression does not evaluate to pattern
                   9227:        movl    r9,r8           # copy string pointer
                   9228:        movl    r10,r9          # restore node pointer
                   9229:        movl    r8,r10          # copy string pointer again
                   9230: #
                   9231: #      MERGE HERE WITH STRING POINTER IN XL
                   9232: #
                   9233: pexa2: tstl    4*sclen(r10)    # just succeed if null string
                   9234:        bnequ   0f
                   9235:        jmp     succp
                   9236: 0:             
                   9237:        jmp     pstr1           # else merge with string circuit
                   9238:        #page   
                   9239: #
                   9240: #      EXPRESSION NODE (P$EXB, REMOVE NDEXB ENTRY)
                   9241: #
                   9242: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9243: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9244: #
                   9245: #      NO PARAMETERS (DUMMY PATTERN)
                   9246: #
                   9247: p$exb:                         # entry point
                   9248:        movl    r7,pmhbs        # restore outer level stack pointer
                   9249:        jmp     flpop           # fail and pop p$exa node ptr
                   9250:        #page   
                   9251: #
                   9252: #      EXPRESSION NODE (P$EXC, REMOVE NDEXC ENTRY)
                   9253: #
                   9254: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9255: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9256: #
                   9257: #      NO PARAMETERS (DUMMY PATTERN)
                   9258: #
                   9259: p$exc:                         # entry point
                   9260:        movl    r7,pmhbs        # restore inner stack base pointer
                   9261:        jmp     failp           # and fail into expr pattern alternvs
                   9262:        #page   
                   9263: #
                   9264: #      FAIL
                   9265: #
                   9266: #      NO PARAMETERS
                   9267: #
                   9268:        .align  2
                   9269:        .word   bl$p0
                   9270: p$fal:                         # p0blk
                   9271:        jmp     failp           # just signal failure
                   9272:        #page   
                   9273: #
                   9274: #      FENCE
                   9275: #
                   9276: #      SEE COMPOUND PATTERNS SECTION FOR THE STRUCTURE AND
                   9277: #      ALGORITHM FOR MATCHING THIS NODE TYPE.
                   9278: #
                   9279: #      NO PARAMETERS
                   9280: #
                   9281:        .align  2
                   9282:        .word   bl$p0
                   9283: p$fen:                         # p0blk
                   9284:        movl    r7,-(sp)        # stack dummy cursor
                   9285:        movl    $ndabo,-(sp)    # stack ptr to abort node
                   9286:        jmp     succp           # and succeed matching null
                   9287:        #page   
                   9288: #
                   9289: #      FENCE (FUNCTION)
                   9290: #
                   9291: #      SEE COMPOUND PATTERNS COMMENTS AT START OF THIS SECTION
                   9292: #      FOR DETAILS OF SCHEME
                   9293: #
                   9294: #      NO PARAMETERS
                   9295: #
                   9296:        .align  2
                   9297:        .word   bl$p0
                   9298: p$fna:                         # p0blk
                   9299:        movl    pmhbs,-(sp)     # stack current history stack base
                   9300:        movl    $ndfnb,-(sp)    # stack indir ptr to p$fnb (failure)
                   9301:        movl    sp,pmhbs        # begin new history stack
                   9302:        jmp     succp           # succeed
                   9303:        #page   
                   9304: #
                   9305: #      FENCE (FUNCTION) (RESET HISTORY STACK AND FAIL)
                   9306: #
                   9307: #      NO PARAMETERS (DUMMY PATTERN)
                   9308: #
                   9309:        .align  2
                   9310:        .word   bl$p0
                   9311: p$fnb:                         # p0blk
                   9312:        movl    r7,pmhbs        # restore outer pmhbs stack base
                   9313:        jmp     failp           # ...and fail
                   9314:        #page   
                   9315: #
                   9316: #      FENCE (FUNCTION) (MAKE FENCE TRAP ENTRY ON STACK)
                   9317: #
                   9318: #      NO PARAMETERS (DUMMY PATTERN)
                   9319: #
                   9320:        .align  2
                   9321:        .word   bl$p0
                   9322: p$fnc:                         # p0blk
                   9323:        movl    pmhbs,r10       # get inner stack base ptr
                   9324:        movl    4*num01(r10),pmhbs # restore outer stack base
                   9325:        cmpl    r10,sp          # optimize if no alternatives
                   9326:        beqlu   pfnc1
                   9327:        movl    r10,-(sp)       # else stack inner stack base
                   9328:        movl    $ndfnd,-(sp)    # stack ptr to ndfnd
                   9329:        jmp     succp           # succeed
                   9330: #
                   9331: #      HERE WHEN FENCE FUNCTION LEFT NOTHING ON THE STACK
                   9332: #
                   9333: pfnc1: addl2   $4*num02,sp     # pop off p$fnb entry
                   9334:        jmp     succp           # succeed
                   9335:        #page   
                   9336: #
                   9337: #      FENCE (FUNCTION) (SKIP PAST ALTERNATIVES ON FAILURE)
                   9338: #
                   9339: #      NO PARAMETERS (DUMMY PATTERN)
                   9340: #
                   9341:        .align  2
                   9342:        .word   bl$p0
                   9343: p$fnd:                         # p0blk
                   9344:        movl    r7,sp           # pop stack to fence() history base
                   9345:        jmp     flpop           # pop base entry and fail
                   9346:        #page   
                   9347: #
                   9348: #      IMMEDIATE ASSIGNMENT (INITIAL ENTRY, SAVE CURRENT CURSOR)
                   9349: #
                   9350: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9351: #      STRUCTURE AND ALGORITHM FOR MATCHING THIS NODE TYPE.
                   9352: #
                   9353: #      NO PARAMETERS
                   9354: #
                   9355:        .align  2
                   9356:        .word   bl$p0
                   9357: p$ima:                         # p0blk
                   9358:        movl    r7,-(sp)        # stack cursor
                   9359:        movl    r9,-(sp)        # stack dummy node pointer
                   9360:        movl    pmhbs,-(sp)     # stack old stack base pointer
                   9361:        movl    $ndimb,-(sp)    # stack ptr to special node ndimb
                   9362:        movl    sp,pmhbs        # store new stack base pointer
                   9363:        jmp     succp           # and succeed
                   9364:        #page   
                   9365: #
                   9366: #      IMMEDIATE ASSIGNMENT (REMOVE CURSOR MARK ENTRY)
                   9367: #
                   9368: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9369: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9370: #
                   9371: #      NO PARAMETERS (DUMMY PATTERN)
                   9372: #
                   9373: p$imb:                         # entry point
                   9374:        movl    r7,pmhbs        # restore history stack base ptr
                   9375:        jmp     flpop           # fail and pop dummy node ptr
                   9376:        #page   
                   9377: #
                   9378: #      IMMEDIATE ASSIGNMENT (PERFORM ACTUAL ASSIGNMENT)
                   9379: #
                   9380: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9381: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9382: #
                   9383: #      PARM1                 NAME BASE OF VARIABLE
                   9384: #      PARM2                 NAME OFFSET OF VARIABLE
                   9385: #
                   9386:        .align  2
                   9387:        .word   bl$p2
                   9388: p$imc:                         # p2blk
                   9389:        movl    pmhbs,r10       # load pointer to p$imb entry
                   9390:        movl    r7,r6           # copy final cursor
                   9391:        movl    4*3(r10),r7     # load initial cursor
                   9392:        movl    4*1(r10),pmhbs  # restore outer stack base pointer
                   9393:        cmpl    r10,sp          # jump if no history stack entries
                   9394:        beqlu   pimc1
                   9395:        movl    r10,-(sp)       # else save inner pmhbs pointer
                   9396:        movl    $ndimd,-(sp)    # and a ptr to special node ndimd
                   9397:        jmp     pimc2           # merge
                   9398: #
                   9399: #      HERE IF NO ENTRIES MADE ON HISTORY STACK
                   9400: #
                   9401: pimc1: addl2   $4*num04,sp     # remove ndimb entry and cursor
                   9402: #
                   9403: #      MERGE HERE TO PERFORM ASSIGNMENT
                   9404: #
                   9405: pimc2: movl    r6,-(sp)        # save current (final) cursor
                   9406:        movl    r9,-(sp)        # save current node pointer
                   9407:        movl    r$pms,r10       # point to subject string
                   9408:        subl2   r7,r6           # compute substring length
                   9409:        jsb     sbstr           # build substring
                   9410:        movl    r9,r7           # move result
                   9411:        movl    (sp),r9         # reload node pointer
                   9412:        movl    4*parm1(r9),r10 # load name base
                   9413:        movl    4*parm2(r9),r6  # load name offset
                   9414:        jsb     asinp           # perform assignment
                   9415:        .long   flpop           # fail if assignment fails
                   9416:        movl    (sp)+,r9        # else restore node pointer
                   9417:        movl    (sp)+,r7        # restore cursor
                   9418:        jmp     succp           # and succeed
                   9419:        #page   
                   9420: #
                   9421: #      IMMEDIATE ASSIGNMENT (REMOVE NDIMD ENTRY ON FAILURE)
                   9422: #
                   9423: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9424: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9425: #
                   9426: #      NO PARAMETERS (DUMMY PATTERN)
                   9427: #
                   9428: p$imd:                         # entry point
                   9429:        movl    r7,pmhbs        # restore inner stack base pointer
                   9430:        jmp     failp           # and fail
                   9431:        #page   
                   9432: #
                   9433: #      LEN (INTEGER ARGUMENT)
                   9434: #
                   9435: #      PARM1                 INTEGER ARGUMENT
                   9436: #
                   9437:        .align  2
                   9438:        .word   bl$p1
                   9439: p$len:                         # p1blk
                   9440: #
                   9441: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9442: #
                   9443: plen1: addl2   4*parm1(r9),r7  # push cursor indicated amount
                   9444:        cmpl    r7,pmssl        # succeed if not off end
                   9445:        bgtru   0f
                   9446:        jmp     succp
                   9447: 0:             
                   9448:        jmp     failp           # else fail
                   9449:        #page   
                   9450: #
                   9451: #      LEN (EXPRESSION ARGUMENT)
                   9452: #
                   9453: #      PARM1                 EXPRESSION POINTER
                   9454: #
                   9455:        .align  2
                   9456:        .word   bl$p1
                   9457: p$lnd:                         # p1blk
                   9458:        jsb     evali           # evaluate integer argument
                   9459:        .long   er_047          # len evaluated argument is not integer
                   9460:        .long   er_048          # len evaluated argument is negative or too large
                   9461:        .long   failp           # fail if evaluation fails
                   9462:        .long   plen1           # merge with normal circuit if ok
                   9463:        #page   
                   9464: #
                   9465: #      NOTANY (EXPRESSION ARGUMENT)
                   9466: #
                   9467: #      PARM1                 EXPRESSION POINTER
                   9468: #
                   9469:        .align  2
                   9470:        .word   bl$p1
                   9471: p$nad:                         # p1blk
                   9472:        jsb     evals           # evaluate string argument
                   9473:        .long   er_049          # notany evaluated argument is not string
                   9474:        .long   failp           # fail if evaluation fails
                   9475:        .long   pnay1           # merge with multi-char case if ok
                   9476:        #page   
                   9477: #
                   9478: #      NOTANY (ONE CHARACTER ARGUMENT)
                   9479: #
                   9480: #      PARM1                 CHARACTER ARGUMENT
                   9481: #
                   9482:        .align  2
                   9483:        .word   bl$p1
                   9484: p$nas:                         # entry point
                   9485:        cmpl    r7,pmssl        # fail if no chars left
                   9486:        bnequ   0f
                   9487:        jmp     failp
                   9488: 0:             
                   9489:        movl    r$pms,r10       # else point to subject string
                   9490:        movab   cfp$f(r10)[r7],r10 # point to current character in strin
                   9491:        movzbl  (r10),r6        # load current character
                   9492:        cmpl    r6,4*parm1(r9)  # fail if match
                   9493:        bnequ   0f
                   9494:        jmp     failp
                   9495: 0:             
                   9496:        incl    r7              # else bump cursor
                   9497:        jmp     succp           # and succeed
                   9498:        #page   
                   9499: #
                   9500: #      NOTANY (MULTI-CHARACTER STRING ARGUMENT)
                   9501: #
                   9502: #      PARM1                 POINTER TO CTBLK
                   9503: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9504: #
                   9505:        .align  2
                   9506:        .word   bl$p2
                   9507: p$nay:                         # p2blk
                   9508: #
                   9509: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9510: #
                   9511: pnay1: cmpl    r7,pmssl        # fail if no characters left
                   9512:        bnequ   0f
                   9513:        jmp     failp
                   9514: 0:             
                   9515:        movl    r$pms,r10       # else point to subject string
                   9516:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9517:        movzbl  (r10),r6        # load current character
                   9518:        moval   0[r6],r6        # convert to byte offset
                   9519:        movl    4*parm1(r9),r10 # load pointer to ctblk
                   9520:        addl2   r6,r10          # point to entry in ctblk
                   9521:        movl    4*ctchs(r10),r6 # load entry from ctblk
                   9522:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9523:        bicl2   r11,r6
                   9524:        tstl    r6              # fail if character is matched
                   9525:        beqlu   0f
                   9526:        jmp     failp
                   9527: 0:             
                   9528:        incl    r7              # else bump cursor
                   9529:        jmp     succp           # and succeed
                   9530:        #page   
                   9531: #
                   9532: #      END OF PATTERN MATCH
                   9533: #
                   9534: #      THIS ROUTINE IS ENTERED ON SUCCESSFUL COMPLETION.
                   9535: #      SEE DESCRIPTION OF EXPRESSION PATTERNS IN COMPOUND
                   9536: #      PATTERN SECTION FOR HANDLING OF RECURSION IN MATCHING.
                   9537: #
                   9538: #      NO PARAMETERS (DUMMY PATTERN)
                   9539: #
                   9540: p$nth:                         # entry point
                   9541:        movl    pmhbs,r10       # load pointer to base of stack
                   9542:        movl    4*1(r10),r6     # load saved pmhbs (or pattern type)
                   9543:        cmpl    r6,$num02       # jump if outer level (pattern type)
                   9544:        blequ   pnth2
                   9545: #
                   9546: #      HERE WE ARE AT THE END OF MATCHING AN EXPRESSION PATTERN
                   9547: #
                   9548:        movl    r6,pmhbs        # restore outer stack base pointer
                   9549:        movl    4*2(r10),r9     # restore pointer to p$exa node
                   9550:        cmpl    r10,sp          # jump if no history stack entries
                   9551:        beqlu   pnth1
                   9552:        movl    r10,-(sp)       # else stack inner stack base ptr
                   9553:        movl    $ndexc,-(sp)    # stack ptr to special node ndexc
                   9554:        jmp     succp           # and succeed
                   9555: #
                   9556: #      HERE IF NO HISTORY STACK ENTRIES DURING PATTERN
                   9557: #
                   9558: pnth1: addl2   $4*num04,sp     # remove p$exb entry and node ptr
                   9559:        jmp     succp           # and succeed
                   9560: #
                   9561: #      HERE IF END OF MATCH AT OUTER LEVEL
                   9562: #
                   9563: pnth2: movl    r7,pmssl        # save final cursor in safe place
                   9564:        tstl    pmdfl           # jump if no pattern assignments
                   9565:        beqlu   pnth6
                   9566:        #page   
                   9567: #
                   9568: #      END OF PATTERN MATCH (CONTINUED)
                   9569: #
                   9570: #      NOW WE MUST PERFORM PATTERN ASSIGNMENTS. THIS IS DONE BY
                   9571: #      SCANNING THE HISTORY STACK FOR MATCHING NDPAB-NDPAD PAIRS
                   9572: #
                   9573: pnth3: subl2   $4,r10          # point past cursor entry
                   9574:        movl    -(r10),r6       # load node pointer
                   9575:        cmpl    r6,$ndpad       # jump if ndpad entry
                   9576:        beqlu   pnth4
                   9577:        cmpl    r6,$ndpab       # jump if not ndpab entry
                   9578:        bnequ   pnth5
                   9579: #
                   9580: #      HERE FOR NDPAB ENTRY, STACK INITIAL CURSOR
                   9581: #      NOTE THAT THERE MUST BE MORE ENTRIES ON THE STACK.
                   9582: #
                   9583:        movl    4*1(r10),-(sp)  # stack initial cursor
                   9584:        jsb     sbchk           # check for stack overflow
                   9585:        jmp     pnth3           # loop back if ok
                   9586: #
                   9587: #      HERE FOR NDPAD ENTRY. THE STARTING CURSOR FROM THE
                   9588: #      MATCHING NDPAD ENTRY IS NOW THE TOP STACK ENTRY.
                   9589: #
                   9590: pnth4: movl    4*1(r10),r6     # load final cursor
                   9591:        movl    (sp),r7         # load initial cursor from stack
                   9592:        movl    r10,(sp)        # save history stack scan ptr
                   9593:        subl2   r7,r6           # compute length of string
                   9594: #
                   9595: #      BUILD SUBSTRING AND PERFORM ASSIGNMENT
                   9596: #
                   9597:        movl    r$pms,r10       # point to subject string
                   9598:        jsb     sbstr           # construct substring
                   9599:        movl    r9,r7           # copy substring pointer
                   9600:        movl    (sp),r10        # reload history stack scan ptr
                   9601:        movl    4*2(r10),r10    # load pointer to p$pac node with nam
                   9602:        movl    4*parm2(r10),r6 # load name offset
                   9603:        movl    4*parm1(r10),r10# load name base
                   9604:        jsb     asinp           # perform assignment
                   9605:        .long   exfal           # match fails if name eval fails
                   9606:        movl    (sp)+,r10       # else restore history stack ptr
                   9607:        #page   
                   9608: #
                   9609: #      END OF PATTERN MATCH (CONTINUED)
                   9610: #
                   9611: #      HERE CHECK FOR END OF ENTRIES
                   9612: #
                   9613: pnth5: cmpl    r10,sp          # loop if more entries to scan
                   9614:        bnequ   pnth3
                   9615: #
                   9616: #      HERE AFTER DEALING WITH PATTERN ASSIGNMENTS
                   9617: #
                   9618: pnth6: movl    pmhbs,sp        # wipe out history stack
                   9619:        movl    (sp)+,r7        # load initial cursor
                   9620:        movl    (sp)+,r8        # load match type code
                   9621:        movl    pmssl,r6        # load final cursor value
                   9622:        movl    r$pms,r10       # point to subject string
                   9623:        clrl    r$pms           # clear subject string ptr for gbcol
                   9624:        tstl    r8              # jump if call by name
                   9625:        beqlu   pnth7
                   9626:        cmpl    r8,$num02       # exit if statement level call
                   9627:        bnequ   0f
                   9628:        jmp     exits
                   9629: 0:             
                   9630: #
                   9631: #      HERE WE HAVE A CALL BY VALUE, BUILD SUBSTRING
                   9632: #
                   9633:        subl2   r7,r6           # compute length of string
                   9634:        jsb     sbstr           # build substring
                   9635:        jmp     exixr           # and exit with substring value
                   9636: #
                   9637: #      HERE FOR CALL BY NAME, MAKE STACK ENTRIES FOR O$RPL
                   9638: #
                   9639: pnth7: movl    r7,-(sp)        # stack initial cursor
                   9640:        movl    r6,-(sp)        # stack final cursor
                   9641:        tstl    r$pmb           # skip if subject not buffer
                   9642:        beqlu   pnth8
                   9643:        movl    r$pmb,r10       # else get ptr to bcblk instead
                   9644: #
                   9645: #      HERE WITH XL POINTING TO SCBLK OR BCBLK
                   9646: #
                   9647: pnth8: movl    r10,-(sp)       # stack subject pointer
                   9648:        jmp     exits           # exit with special entry on stack
                   9649:        #page   
                   9650: #
                   9651: #      POS (INTEGER ARGUMENT)
                   9652: #
                   9653: #      PARM1                 INTEGER ARGUMENT
                   9654: #
                   9655:        .align  2
                   9656:        .word   bl$p1
                   9657: p$pos:                         # p1blk
                   9658: #
                   9659: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9660: #
                   9661: ppos1: cmpl    r7,4*parm1(r9)  # succeed if at right location
                   9662:        bnequ   0f
                   9663:        jmp     succp
                   9664: 0:             
                   9665:        jmp     failp           # else fail
                   9666:        #page   
                   9667: #
                   9668: #      POS (EXPRESSION ARGUMENT)
                   9669: #
                   9670: #      PARM1                 EXPRESSION POINTER
                   9671: #
                   9672:        .align  2
                   9673:        .word   bl$p1
                   9674: p$psd:                         # p1blk
                   9675:        jsb     evali           # evaluate integer argument
                   9676:        .long   er_050          # pos evaluated argument is not integer
                   9677:        .long   er_051          # pos evaluated argument is negative or too large
                   9678:        .long   failp           # fail if evaluation fails
                   9679:        .long   ppos1           # merge with normal case if ok
                   9680:        #page   
                   9681: #
                   9682: #      PATTERN ASSIGNMENT (INITIAL ENTRY, SAVE CURSOR)
                   9683: #
                   9684: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9685: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9686: #
                   9687: #      NO PARAMETERS
                   9688: #
                   9689:        .align  2
                   9690:        .word   bl$p0
                   9691: p$paa:                         # p0blk
                   9692:        movl    r7,-(sp)        # stack initial cursor
                   9693:        movl    $ndpab,-(sp)    # stack ptr to ndpab special node
                   9694:        jmp     succp           # and succeed matching null
                   9695:        #page   
                   9696: #
                   9697: #      PATTERN ASSIGNMENT (REMOVE SAVED CURSOR)
                   9698: #
                   9699: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9700: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9701: #
                   9702: #      NO PARAMETERS (DUMMY PATTERN)
                   9703: #
                   9704: p$pab:                         # entry point
                   9705:        jmp     failp           # just fail (entry is already popped)
                   9706:        #page   
                   9707: #
                   9708: #      PATTERN ASSIGNMENT (END OF MATCH, MAKE ASSIGN ENTRY)
                   9709: #
                   9710: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9711: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9712: #
                   9713: #      PARM1                 NAME BASE OF VARIABLE
                   9714: #      PARM2                 NAME OFFSET OF VARIABLE
                   9715: #
                   9716:        .align  2
                   9717:        .word   bl$p2
                   9718: p$pac:                         # p2blk
                   9719:        movl    r7,-(sp)        # stack dummy cursor value
                   9720:        movl    r9,-(sp)        # stack pointer to p$pac node
                   9721:        movl    r7,-(sp)        # stack final cursor
                   9722:        movl    $ndpad,-(sp)    # stack ptr to special ndpad node
                   9723:        movl    sp,pmdfl        # set dot flag non-zero
                   9724:        jmp     succp           # and succeed
                   9725:        #page   
                   9726: #
                   9727: #      PATTERN ASSIGNMENT (REMOVE ASSIGN ENTRY)
                   9728: #
                   9729: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9730: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9731: #
                   9732: #      NO PARAMETERS (DUMMY NODE)
                   9733: #
                   9734: p$pad:                         # entry point
                   9735:        jmp     flpop           # fail and remove p$pac node
                   9736:        #page   
                   9737: #
                   9738: #      REM
                   9739: #
                   9740: #      NO PARAMETERS
                   9741: #
                   9742:        .align  2
                   9743:        .word   bl$p0
                   9744: p$rem:                         # p0blk
                   9745:        movl    pmssl,r7        # point cursor to end of string
                   9746:        jmp     succp           # and succeed
                   9747:        #page   
                   9748: #
                   9749: #      RPOS (EXPRESSION ARGUMENT)
                   9750: #
                   9751: #      PARM1                 EXPRESSION POINTER
                   9752: #
                   9753:        .align  2
                   9754:        .word   bl$p1
                   9755: p$rpd:                         # p1blk
                   9756:        jsb     evali           # evaluate integer argument
                   9757:        .long   er_052          # rpos evaluated argument is not integer
                   9758:        .long   er_053          # rpos evaluated argument is negative or too large
                   9759:        .long   failp           # fail if evaluation fails
                   9760:        .long   prps1           # merge with normal case if ok
                   9761:        #page   
                   9762: #
                   9763: #      RPOS (INTEGER ARGUMENT)
                   9764: #
                   9765: #      PARM1                 INTEGER ARGUMENT
                   9766: #
                   9767:        .align  2
                   9768:        .word   bl$p1
                   9769: p$rps:                         # p1blk
                   9770: #
                   9771: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9772: #
                   9773: prps1: movl    pmssl,r8        # get length of string
                   9774:        subl2   r7,r8           # get number of characters remaining
                   9775:        cmpl    r8,4*parm1(r9)  # succeed if at right location
                   9776:        bnequ   0f
                   9777:        jmp     succp
                   9778: 0:             
                   9779:        jmp     failp           # else fail
                   9780:        #page   
                   9781: #
                   9782: #      RTAB (INTEGER ARGUMENT)
                   9783: #
                   9784: #      PARM1                 INTEGER ARGUMENT
                   9785: #
                   9786:        .align  2
                   9787:        .word   bl$p1
                   9788: p$rtb:                         # p1blk
                   9789: #
                   9790: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9791: #
                   9792: prtb1: movl    r7,r8           # save initial cursor
                   9793:        movl    pmssl,r7        # point to end of string
                   9794:        cmpl    r7,4*parm1(r9)  # fail if string not long enough
                   9795:        bgequ   0f
                   9796:        jmp     failp
                   9797: 0:             
                   9798:        subl2   4*parm1(r9),r7  # else set new cursor
                   9799:        cmpl    r7,r8           # and succeed if not too far already
                   9800:        blssu   0f
                   9801:        jmp     succp
                   9802: 0:             
                   9803:        jmp     failp           # in which case, fail
                   9804:        #page   
                   9805: #
                   9806: #      RTAB (EXPRESSION ARGUMENT)
                   9807: #
                   9808: #      PARM1                 EXPRESSION POINTER
                   9809: #
                   9810:        .align  2
                   9811:        .word   bl$p1
                   9812: p$rtd:                         # p1blk
                   9813:        jsb     evali           # evaluate integer argument
                   9814:        .long   er_054          # rtab evaluated argument is not integer
                   9815:        .long   er_055          # rtab evaluated argument is negative or too large
                   9816:        .long   failp           # fail if evaluation fails
                   9817:        .long   prtb1           # merge with normal case if success
                   9818:        #page   
                   9819: #
                   9820: #      SPAN (EXPRESSION ARGUMENT)
                   9821: #
                   9822: #      PARM1                 EXPRESSION POINTER
                   9823: #
                   9824:        .align  2
                   9825:        .word   bl$p1
                   9826: p$spd:                         # p1blk
                   9827:        jsb     evals           # evaluate string argument
                   9828:        .long   er_056          # span evaluated argument is not string
                   9829:        .long   failp           # fail if evaluation fails
                   9830:        .long   pspn1           # merge with multi-char case if ok
                   9831:        #page   
                   9832: #
                   9833: #      SPAN (MULTI-CHARACTER ARGUMENT CASE)
                   9834: #
                   9835: #      PARM1                 POINTER TO CTBLK
                   9836: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9837: #
                   9838:        .align  2
                   9839:        .word   bl$p2
                   9840: p$spn:                         # p2blk
                   9841: #
                   9842: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9843: #
                   9844: pspn1: movl    pmssl,r8        # copy subject string length
                   9845:        subl2   r7,r8           # calculate number of characters left
                   9846:        tstl    r8              # fail if no characters left
                   9847:        bnequ   0f
                   9848:        jmp     failp
                   9849: 0:             
                   9850:        movl    r$pms,r10       # point to subject string
                   9851:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9852:        movl    r7,psavc        # save initial cursor
                   9853:        movl    r9,psave        # save node pointer
                   9854:                                # set counter for chars left
                   9855: #
                   9856: #      LOOP TO SCAN MATCHING CHARACTERS
                   9857: #
                   9858: pspn2: movzbl  (r10)+,r6       # load next character, bump pointer
                   9859:        moval   0[r6],r6        # convert to byte offset
                   9860:        movl    4*parm1(r9),r9  # point to ctblk
                   9861:        addl2   r6,r9           # point to ctblk entry
                   9862:        movl    4*ctchs(r9),r6  # load ctblk entry
                   9863:        movl    psave,r9        # restore node pointer
                   9864:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9865:        bicl2   r11,r6
                   9866:        tstl    r6              # jump if no match
                   9867:        beqlu   pspn3
                   9868:        incl    r7              # else push cursor
                   9869:        sobgtr  r8,pspn2        # loop back unless end of string
                   9870: #
                   9871: #      HERE AFTER SCANNING MATCHING CHARACTERS
                   9872: #
                   9873: pspn3: cmpl    r7,psavc        # succeed if chars matched
                   9874:        beqlu   0f
                   9875:        jmp     succp
                   9876: 0:             
                   9877:        jmp     failp           # else fail if null string matched
                   9878:        #page   
                   9879: #
                   9880: #      SPAN (ONE CHARACTER ARGUMENT)
                   9881: #
                   9882: #      PARM1                 CHARACTER ARGUMENT
                   9883: #
                   9884:        .align  2
                   9885:        .word   bl$p1
                   9886: p$sps:                         # p1blk
                   9887:        movl    pmssl,r8        # get subject string length
                   9888:        subl2   r7,r8           # calculate number of characters left
                   9889:        tstl    r8              # fail if no characters left
                   9890:        bnequ   0f
                   9891:        jmp     failp
                   9892: 0:             
                   9893:        movl    r$pms,r10       # else point to subject string
                   9894:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9895:        movl    r7,psavc        # save initial cursor
                   9896:                                # set counter for characters left
                   9897: #
                   9898: #      LOOP TO SCAN MATCHING CHARACTERS
                   9899: #
                   9900: psps1: movzbl  (r10)+,r6       # load next character, bump pointer
                   9901:        cmpl    r6,4*parm1(r9)  # jump if no match
                   9902:        bnequ   psps2
                   9903:        incl    r7              # else push cursor
                   9904:        sobgtr  r8,psps1        # and loop unless end of string
                   9905: #
                   9906: #      HERE AFTER SCANNING MATCHING CHARACTERS
                   9907: #
                   9908: psps2: cmpl    r7,psavc        # succeed if chars matched
                   9909:        beqlu   0f
                   9910:        jmp     succp
                   9911: 0:             
                   9912:        jmp     failp           # fail if null string matched
                   9913:        #page   
                   9914: #
                   9915: #      MULTI-CHARACTER STRING
                   9916: #
                   9917: #      NOTE THAT ONE CHARACTER STRINGS USE THE CIRCUIT FOR
                   9918: #      ONE CHARACTER ANY ARGUMENTS (P$AN1).
                   9919: #
                   9920: #      PARM1                 POINTER TO SCBLK FOR STRING ARG
                   9921: #
                   9922:        .align  2
                   9923:        .word   bl$p1
                   9924: p$str:                         # p1blk
                   9925:        movl    4*parm1(r9),r10 # get pointer to string
                   9926: #
                   9927: #      MERGE HERE AFTER EVALUATING EXPRESSION WITH STRING VALUE
                   9928: #
                   9929: pstr1: movl    r9,psave        # save node pointer
                   9930:        movl    r$pms,r9        # load subject string pointer
                   9931:        movab   cfp$f(r9)[r7],r9# point to current character
                   9932:        addl2   4*sclen(r10),r7 # compute new cursor position
                   9933:        cmpl    r7,pmssl        # fail if past end of string
                   9934:        blequ   0f
                   9935:        jmp     failp
                   9936: 0:             
                   9937:        movl    r7,psavc        # save updated cursor
                   9938:        movl    4*sclen(r10),r6 # get number of chars to compare
                   9939:        movab   cfp$f(r10),r10  # point to chars of test string
                   9940:        jsb     sbcmc           # compare, fail if not equal
                   9941:        .long   failp
                   9942:        .long   failp
                   9943:        movl    psave,r9        # if all matched, restore node ptr
                   9944:        movl    psavc,r7        # restore updated cursor
                   9945:        jmp     succp           # and succeed
                   9946:        #page   
                   9947: #
                   9948: #      SUCCEED
                   9949: #
                   9950: #      SEE SECTION ON COMPOUND PATTERNS FOR DETAILS OF THE
                   9951: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE
                   9952: #
                   9953: #      NO PARAMETERS
                   9954: #
                   9955:        .align  2
                   9956:        .word   bl$p0
                   9957: p$suc:                         # p0blk
                   9958:        movl    r7,-(sp)        # stack cursor
                   9959:        movl    r9,-(sp)        # stack pointer to this node
                   9960:        jmp     succp           # succeed matching null
                   9961:        #page   
                   9962: #
                   9963: #      TAB (INTEGER ARGUMENT)
                   9964: #
                   9965: #      PARM1                 INTEGER ARGUMENT
                   9966: #
                   9967:        .align  2
                   9968:        .word   bl$p1
                   9969: p$tab:                         # p1blk
                   9970: #
                   9971: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9972: #
                   9973: ptab1: cmpl    r7,4*parm1(r9)  # fail if too far already
                   9974:        blequ   0f
                   9975:        jmp     failp
                   9976: 0:             
                   9977:        movl    4*parm1(r9),r7  # else set new cursor position
                   9978:        cmpl    r7,pmssl        # succeed if not off end
                   9979:        bgtru   0f
                   9980:        jmp     succp
                   9981: 0:             
                   9982:        jmp     failp           # else fail
                   9983:        #page   
                   9984: #
                   9985: #      TAB (EXPRESSION ARGUMENT)
                   9986: #
                   9987: #      PARM1                 EXPRESSION POINTER
                   9988: #
                   9989:        .align  2
                   9990:        .word   bl$p1
                   9991: p$tbd:                         # p1blk
                   9992:        jsb     evali           # evaluate integer argument
                   9993:        .long   er_057          # tab evaluated argument is not integer
                   9994:        .long   er_058          # tab evaluated argument is negative or too large
                   9995:        .long   failp           # fail if evaluation fails
                   9996:        .long   ptab1           # merge with normal case if ok
                   9997:        #page   
                   9998: #
                   9999: #      ANCHOR MOVEMENT
                   10000: #
                   10001: #      NO PARAMETERS (DUMMY NODE)
                   10002: #
                   10003: p$una:                         # entry point
                   10004:        movl    r7,r9           # copy initial pattern node pointer
                   10005:        movl    (sp),r7         # get initial cursor
                   10006:        cmpl    r7,pmssl        # match fails if at end of string
                   10007:        bnequ   0f
                   10008:        jmp     exfal
                   10009: 0:             
                   10010:        incl    r7              # else increment cursor
                   10011:        movl    r7,(sp)         # store incremented cursor
                   10012:        movl    r9,-(sp)        # restack initial node ptr
                   10013:        movl    $nduna,-(sp)    # restack unanchored node
                   10014:        movl    (r9),r11        # rematch first node
                   10015:        jmp     (r11)
                   10016:        #page   
                   10017: #
                   10018: #      END OF PATTERN MATCH ROUTINES
                   10019: #
                   10020: #      THE FOLLOWING ENTRY POINT MARKS THE END OF THE PATTERN
                   10021: #      MATCHING ROUTINES AND ALSO THE END OF THE ENTRY POINTS
                   10022: #      REFERENCED FROM THE FIRST WORD OF BLOCKS IN DYNAMIC STORE
                   10023: #
                   10024:        .align  2
                   10025:        .word   bl$$i
                   10026: p$yyy:                         # mark last entry in pattern section
                   10027:        #title  s p i t b o l -- predefined snobol4 functions
                   10028: #
                   10029: #      THE FOLLOWING SECTION CONTAINS CODING FOR FUNCTIONS
                   10030: #      WHICH ARE PREDEFINED AND AVAILABLE AT THE SNOBOL LEVEL.
                   10031: #
                   10032: #      THESE ROUTINES RECEIVE CONTROL DIRECTLY FROM THE CODE OR
                   10033: #      INDIRECTLY THROUGH THE O$FNC, O$FNS OR CFUNC ROUTINES.
                   10034: #      IN BOTH CASES THE CONDITIONS ON ENTRY ARE AS FOLLOWS
                   10035: #
                   10036: #      THE ARGUMENTS ARE ON THE STACK. THE NUMBER OF ARGUMENTS
                   10037: #      HAS BEEN ADJUSTED TO CORRESPOND TO THE SVBLK SVNAR FIELD.
                   10038: #
                   10039: #      IN CERTAIN FUNCTIONS THE DIRECT CALL IS NOT PERMITTED
                   10040: #      AND IN THESE INSTANCES WE ALSO HAVE.
                   10041: #
                   10042: #      (WA)                  ACTUAL NUMBER OF ARGUMENTS IN CALL
                   10043: #
                   10044: #      CONTROL RETURNS BY PLACING THE FUNCTION RESULT VALUE ON
                   10045: #      ON THE STACK AND CONTINUING EXECUTION WITH THE NEXT
                   10046: #      WORD FROM THE GENERATED CODE.
                   10047: #
                   10048: #      THE NAMES OF THE ENTRY POINTS OF THESE FUNCTIONS ARE OF
                   10049: #      THE FORM S$XXX WHERE XXX IS THE THREE LETTER CODE FOR
                   10050: #      THE SYSTEM VARIABLE NAME. THE FUNCTIONS ARE IN ORDER
                   10051: #      ALPHABETICALLY BY THEIR ENTRY NAMES.
                   10052:        #page   
                   10053: #
                   10054: #      ANY
                   10055: #
                   10056: s$any:                         # entry point
                   10057:        movl    $p$ans,r7       # set pcode for single char case
                   10058:        movl    $p$any,r10      # pcode for multi-char case
                   10059:        movl    $p$ayd,r8       # pcode for expression case
                   10060:        jsb     patst           # call common routine to build node
                   10061:        .long   er_059          # any argument is not string or expression
                   10062:        jmp     exixr           # jump for next code word
                   10063:        #page   
                   10064: #
                   10065: #      APPEND
                   10066: #
                   10067: s$apn:                         # entry point
                   10068:        movl    (sp)+,r10       # get append argument
                   10069:        movl    (sp)+,r9        # get bcblk
                   10070:        cmpl    (r9),$b$bct     # ok if first arg is bcblk
                   10071:        beqlu   sapn1
                   10072:        jmp     er_275          # append first argument is not buffer
                   10073: #
                   10074: #      HERE TO DO THE APPEND
                   10075: #
                   10076: sapn1: jsb     apndb           # do the append
                   10077:        .long   er_276          # append second argument is not string
                   10078:        .long   exfal           # no room - fail
                   10079:        jmp     exnul           # exit with null result
                   10080:        #page   
                   10081: #
                   10082: #      APPLY
                   10083: #
                   10084: #      APPLY DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT
                   10085: #      WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED.
                   10086: #
                   10087: s$app:                         # entry point
                   10088:        tstl    r6              # jump if no arguments
                   10089:        beqlu   sapp3
                   10090:        decl    r6              # else get applied func arg count
                   10091:        movl    r6,r7           # copy
                   10092:        moval   0[r7],r7        # convert to bytes
                   10093:        movl    sp,r10          # copy stack pointer
                   10094:        addl2   r7,r10          # point to function argument on stack
                   10095:        movl    (r10),r9        # load function ptr (apply 1st arg)
                   10096:        tstl    r6              # jump if no args for applied func
                   10097:        beqlu   sapp2
                   10098:        movl    r6,r7           # else set counter for loop
                   10099: #
                   10100: #      LOOP TO MOVE ARGUMENTS UP ON STACK
                   10101: #
                   10102: sapp1: subl2   $4,r10          # point to next argument
                   10103:        movl    (r10),4*1(r10)  # move argument up
                   10104:        sobgtr  r7,sapp1        # loop till all moved
                   10105: #
                   10106: #      MERGE HERE TO CALL FUNCTION (WA = NUMBER OF ARGUMENTS)
                   10107: #
                   10108: sapp2: addl2   $4,sp           # adjust stack ptr for apply 1st arg
                   10109:        jsb     gtnvr           # get variable block addr for func
                   10110:        .long   sapp3           # jump if not natural variable
                   10111:        movl    4*vrfnc(r9),r10 # else point to function block
                   10112:        jmp     cfunc           # go call applied function
                   10113: #
                   10114: #      HERE FOR INVALID FIRST ARGUMENT
                   10115: #
                   10116: sapp3: jmp     er_060          # apply first arg is not natural variable name
                   10117:        #page   
                   10118: #
                   10119: #      ARBNO
                   10120: #
                   10121: #      ARBNO BUILDS A COMPOUND PATTERN. SEE DESCRIPTION AT
                   10122: #      START OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED.
                   10123: #
                   10124: s$abn:                         # entry point
                   10125:        clrl    r9              # set parm1 = 0 for the moment
                   10126:        movl    $p$alt,r7       # set pcode for alternative node
                   10127:        jsb     pbild           # build alternative node
                   10128:        movl    r9,r10          # save ptr to alternative pattern
                   10129:        movl    $p$abc,r7       # pcode for p$abc
                   10130:        clrl    r9              # p0blk
                   10131:        jsb     pbild           # build p$abc node
                   10132:        movl    r10,4*pthen(r9) # put alternative node as successor
                   10133:        movl    r10,r6          # remember alternative node pointer
                   10134:        movl    r9,r10          # copy p$abc node ptr
                   10135:        movl    (sp),r9         # load arbno argument
                   10136:        movl    r6,(sp)         # stack alternative node pointer
                   10137:        jsb     gtpat           # get arbno argument as pattern
                   10138:        .long   er_061          # arbno argument is not pattern
                   10139:        jsb     pconc           # concat arg with p$abc node
                   10140:        movl    r9,r10          # remember ptr to concd patterns
                   10141:        movl    $p$aba,r7       # pcode for p$aba
                   10142:        clrl    r9              # p0blk
                   10143:        jsb     pbild           # build p$aba node
                   10144:        movl    r10,4*pthen(r9) # concatenate nodes
                   10145:        movl    (sp),r10        # recall ptr to alternative node
                   10146:        movl    r9,4*parm1(r10) # point alternative back to argument
                   10147:        jmp     exits           # jump for next code word
                   10148:        #page   
                   10149: #
                   10150: #      ARG
                   10151: #
                   10152: s$arg:                         # entry point
                   10153:        jsb     gtsmi           # get second arg as small integer
                   10154:        .long   er_062          # arg second argument is not integer
                   10155:        .long   exfal           # fail if out of range or negative
                   10156:        movl    r9,r6           # save argument number
                   10157:        movl    (sp)+,r9        # load first argument
                   10158:        jsb     gtnvr           # locate vrblk
                   10159:        .long   sarg1           # jump if not natural variable
                   10160:        movl    4*vrfnc(r9),r9  # else load function block pointer
                   10161:        cmpl    (r9),$b$pfc     # jump if not program defined
                   10162:        bnequ   sarg1
                   10163:        tstl    r6              # fail if arg number is zero
                   10164:        bnequ   0f
                   10165:        jmp     exfal
                   10166: 0:             
                   10167:        cmpl    r6,4*fargs(r9)  # fail if arg number is too large
                   10168:        blequ   0f
                   10169:        jmp     exfal
                   10170: 0:             
                   10171:        moval   0[r6],r6        # else convert to byte offset
                   10172:        addl2   r6,r9           # point to argument selected
                   10173:        movl    4*pfagb(r9),r9  # load argument vrblk pointer
                   10174:        jmp     exvnm           # exit to build nmblk
                   10175: #
                   10176: #      HERE IF 1ST ARGUMENT IS BAD
                   10177: #
                   10178: sarg1: jmp     er_063          # arg first argument is not program function name
                   10179:        #page   
                   10180: #
                   10181: #      ARRAY
                   10182: #
                   10183: s$arr:                         # entry point
                   10184:        movl    (sp)+,r10       # load initial element value
                   10185:        movl    (sp)+,r9        # load first argument
                   10186:        jsb     gtint           # convert first arg to integer
                   10187:        .long   sar02           # jump if not integer
                   10188: #
                   10189: #      HERE FOR INTEGER FIRST ARGUMENT, BUILD VCBLK
                   10190: #
                   10191:        movl    4*icval(r9),r5  # load integer value
                   10192:        tstl    r5              # jump if zero or neg (bad dimension)
                   10193:        bgtr    0f
                   10194:        jmp     sar10
                   10195: 0:             
                   10196:        movl    r5,r6           # else convert to one word, test ovfl
                   10197:        bgeq    0f
                   10198:        jmp     sar11
                   10199: 0:             
                   10200:        movl    r6,r7           # copy elements for loop later on
                   10201:        addl2   $vcsi$,r6       # add space for standard fields
                   10202:        moval   0[r6],r6        # convert length to bytes
                   10203:        cmpl    r6,mxlen        # fail if too large
                   10204:        blssu   0f
                   10205:        jmp     sar11
                   10206: 0:             
                   10207:        jsb     alloc           # allocate space for vcblk
                   10208:        movl    $b$vct,(r9)     # store type word
                   10209:        movl    r6,4*vclen(r9)  # set length
                   10210:        movl    r10,r8          # copy default value
                   10211:        movl    r9,r10          # copy vcblk pointer
                   10212:        addl2   $4*vcvls,r10    # point to first element value
                   10213: #
                   10214: #      LOOP TO SET VECTOR ELEMENTS TO DEFAULT VALUE
                   10215: #
                   10216: sar01: movl    r8,(r10)+       # store one value
                   10217:        sobgtr  r7,sar01        # loop till all stored
                   10218:        jmp     exsid           # exit setting idval
                   10219:        #page   
                   10220: #
                   10221: #      ARRAY (CONTINUED)
                   10222: #
                   10223: #      HERE IF FIRST ARGUMENT IS NOT AN INTEGER
                   10224: #
                   10225: sar02: movl    r9,-(sp)        # replace argument on stack
                   10226:        jsb     xscni           # initialize scan of first argument
                   10227:        .long   er_064          # array first argument is not integer or string
                   10228:        .long   exnul           # dummy (unused) null string exit
                   10229:        movl    r$xsc,-(sp)     # save prototype pointer
                   10230:        movl    r10,-(sp)       # save default value
                   10231:        clrl    arcdm           # zero count of dimensions
                   10232:        clrl    arptr           # zero offset to indicate pass one
                   10233:        movl    intv1,r5        # load integer one
                   10234:        movl    r5,arnel        # initialize element count
                   10235: #
                   10236: #      THE FOLLOWING CODE IS EXECUTED TWICE. THE FIRST TIME
                   10237: #      (ARPTR EQ 0), IT IS USED TO COUNT THE NUMBER OF ELEMENTS
                   10238: #      AND NUMBER OF DIMENSIONS. THE SECOND TIME (ARPTR GT 0) IS
                   10239: #      USED TO ACTUALLY FILL IN THE DIM,LBD FIELDS OF THE ARBLK.
                   10240: #
                   10241: sar03: movl    intv1,r5        # load one as default low bound
                   10242:        movl    r5,arsvl        # save as low bound
                   10243:        movl    $ch$cl,r8       # set delimiter one = colon
                   10244:        movl    $ch$cm,r10      # set delimiter two = comma
                   10245:        jsb     xscan           # scan next bound
                   10246:        cmpl    r6,$num01       # jump if not colon
                   10247:        bnequ   sar04
                   10248: #
                   10249: #      HERE WE HAVE A COLON ENDING A LOW BOUND
                   10250: #
                   10251:        jsb     gtint           # convert low bound
                   10252:        .long   er_065          # array first argument lower bound is not integer
                   10253:        movl    4*icval(r9),r5  # load value of low bound
                   10254:        movl    r5,arsvl        # store low bound value
                   10255:        movl    $ch$cm,r8       # set delimiter one = comma
                   10256:        movl    r8,r10          # and delimiter two = comma
                   10257:        jsb     xscan           # scan high bound
                   10258:        #page   
                   10259: #
                   10260: #      ARRAY (CONTINUED)
                   10261: #
                   10262: #      MERGE HERE TO PROCESS UPPER BOUND
                   10263: #
                   10264: sar04: jsb     gtint           # convert high bound to integer
                   10265:        .long   er_066          # array first argument upper bound is not integer
                   10266:        movl    4*icval(r9),r5  # get high bound
                   10267:        subl2   arsvl,r5        # subtract lower bound
                   10268:        bvc     0f
                   10269:        jmp     sar10
                   10270: 0:             
                   10271:        tstl    r5              # bad dimension if negative
                   10272:        bgeq    0f
                   10273:        jmp     sar10
                   10274: 0:             
                   10275:        addl2   intv1,r5        # add 1 to get dimension
                   10276:        bvc     0f
                   10277:        jmp     sar10
                   10278: 0:             
                   10279:        movl    arptr,r10       # load offset (also pass indicator)
                   10280:        tstl    r10             # jump if first pass
                   10281:        beqlu   sar05
                   10282: #
                   10283: #      HERE IN SECOND PASS TO STORE LBD AND DIM IN ARBLK
                   10284: #
                   10285:        addl2   (sp),r10        # point to current location in arblk
                   10286:        movl    r5,4*cfp$i(r10) # store dimension
                   10287:        movl    arsvl,r5        # load low bound
                   10288:        movl    r5,(r10)        # store low bound
                   10289:        addl2   $4*ardms,arptr  # bump offset to next bounds
                   10290:        jmp     sar06           # jump to check for end of bounds
                   10291: #
                   10292: #      HERE IN PASS 1
                   10293: #
                   10294: sar05: incl    arcdm           # bump dimension count
                   10295:        mull2   arnel,r5        # multiply dimension by count so far
                   10296:        bvc     0f
                   10297:        jmp     sar11
                   10298: 0:             
                   10299:        movl    r5,arnel        # else store updated element count
                   10300: #
                   10301: #      MERGE HERE AFTER PROCESSING ONE SET OF BOUNDS
                   10302: #
                   10303: sar06: tstl    r6              # loop back unless end of bounds
                   10304:        beqlu   0f
                   10305:        jmp     sar03
                   10306: 0:             
                   10307:        tstl    arptr           # jump if end of pass 2
                   10308:        beqlu   0f
                   10309:        jmp     sar09
                   10310: 0:             
                   10311:        #page   
                   10312: #
                   10313: #      ARRAY (CONTINUED)
                   10314: #
                   10315: #      HERE AT END OF PASS ONE, BUILD ARBLK
                   10316: #
                   10317:        movl    arnel,r5        # get number of elements
                   10318:        movl    r5,r7           # get as addr integer, test ovflo
                   10319:        bgeq    0f
                   10320:        jmp     sar11
                   10321: 0:             
                   10322:        moval   0[r7],r7        # else convert to length in bytes
                   10323:        movl    $4*arsi$,r6     # set size of standard fields
                   10324:        movl    arcdm,r8        # set dimension count to control loop
                   10325: #
                   10326: #      LOOP TO ALLOW SPACE FOR DIMENSIONS
                   10327: #
                   10328: sar07: addl2   $4*ardms,r6     # allow space for one set of bounds
                   10329:        sobgtr  r8,sar07        # loop back till all accounted for
                   10330:        movl    r6,r10          # save size (=arofs)
                   10331: #
                   10332: #      NOW ALLOCATE SPACE FOR ARBLK
                   10333: #
                   10334:        addl2   r7,r6           # add space for elements
                   10335:        addl2   $4,r6           # allow for arpro prototype field
                   10336:        cmpl    r6,mxlen        # fail if too large
                   10337:        blssu   0f
                   10338:        jmp     sar11
                   10339: 0:             
                   10340:        jsb     alloc           # else allocate arblk
                   10341:        movl    (sp),r7         # load default value
                   10342:        movl    r9,(sp)         # save arblk pointer
                   10343:        movl    r6,r8           # save length in bytes
                   10344:        ashl    $-2,r6,r6       # convert length back to words
                   10345:                                # set counter to control loop
                   10346: #
                   10347: #      LOOP TO CLEAR ENTIRE ARBLK TO DEFAULT VALUE
                   10348: #
                   10349: sar08: movl    r7,(r9)+        # set one word
                   10350:        sobgtr  r6,sar08        # loop till all set
                   10351:        #page   
                   10352: #
                   10353: #      ARRAY (CONTINUED)
                   10354: #
                   10355: #      NOW SET INITIAL FIELDS OF ARBLK
                   10356: #
                   10357:        movl    (sp)+,r9        # reload arblk pointer
                   10358:        movl    (sp),r7         # load prototype
                   10359:        movl    $b$art,(r9)     # set type word
                   10360:        movl    r8,4*arlen(r9)  # store length in bytes
                   10361:        clrl    4*idval(r9)     # zero id till we get it built
                   10362:        movl    r10,4*arofs(r9) # set prototype field ptr
                   10363:        movl    arcdm,4*arndm(r9)# set number of dimensions
                   10364:        movl    r9,r8           # save arblk pointer
                   10365:        addl2   r10,r9          # point to prototype field
                   10366:        movl    r7,(r9)         # store prototype ptr in arblk
                   10367:        movl    $4*arlbd,arptr  # set offset for pass 2 bounds scan
                   10368:        movl    r7,r$xsc        # reset string pointer for xscan
                   10369:        movl    r8,(sp)         # store arblk pointer on stack
                   10370:        clrl    xsofs           # reset offset ptr to start of string
                   10371:        jmp     sar03           # jump back to rescan bounds
                   10372: #
                   10373: #      HERE AFTER FILLING IN BOUNDS INFORMATION (END PASS TWO)
                   10374: #
                   10375: sar09: movl    (sp)+,r9        # reload pointer to arblk
                   10376:        jmp     exsid           # exit setting idval
                   10377: #
                   10378: #      HERE FOR BAD DIMENSION
                   10379: #
                   10380: sar10: jmp     er_067          # array dimension is zero,negative or out of range
                   10381: #
                   10382: #      HERE IF ARRAY IS TOO LARGE
                   10383: #
                   10384: sar11: jmp     er_068          # array size exceeds maximum permitted
                   10385:        #page   
                   10386: #
                   10387: #      BUFFER
                   10388: #
                   10389: s$buf:                         # entry point
                   10390:        movl    (sp)+,r10       # get initial value
                   10391:        movl    (sp)+,r9        # get requested allocation
                   10392:        jsb     gtint           # convert to integer
                   10393:        .long   er_269          # buffer first argument is not integer
                   10394:        movl    4*icval(r9),r5  # get value
                   10395:        tstl    r5              # branch if negative or zero
                   10396:        bleq    sbf01
                   10397:        movl    r5,r6           # move with overflow check
                   10398:        bgeq    0f
                   10399:        jmp     sbf02
                   10400: 0:             
                   10401:        jsb     alobf           # allocate the buffer
                   10402:        jsb     apndb           # copy it in
                   10403:        .long   er_270          # buffer second argument is not string or buffer
                   10404:        .long   er_271          # buffer initial value too big for allocation
                   10405:        jmp     exsid           # exit setting idval
                   10406: #
                   10407: #      HERE FOR INVALID ALLOCATION SIZE
                   10408: #
                   10409: sbf01: jmp     er_272          # buffer first argument is not positive
                   10410: #
                   10411: #      HERE FOR ALLOCATION SIZE INTEGER OVERFLOW
                   10412: #
                   10413: sbf02: jmp     er_273          # buffer size is too big
                   10414:        #page   
                   10415: #
                   10416: #      BREAK
                   10417: #
                   10418: s$brk:                         # entry point
                   10419:        movl    $p$bks,r7       # set pcode for single char case
                   10420:        movl    $p$brk,r10      # pcode for multi-char case
                   10421:        movl    $p$bkd,r8       # pcode for expression case
                   10422:        jsb     patst           # call common routine to build node
                   10423:        .long   er_069          # break argument is not string or expression
                   10424:        jmp     exixr           # jump for next code word
                   10425:        #page   
                   10426: #
                   10427: #      BREAKX
                   10428: #
                   10429: #      BREAKX IS A COMPOUND PATTERN. SEE DESCRIPTION AT START
                   10430: #      OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED.
                   10431: #
                   10432: s$bkx:                         # entry point
                   10433:        movl    $p$bks,r7       # pcode for single char argument
                   10434:        movl    $p$brk,r10      # pcode for multi-char argument
                   10435:        movl    $p$bxd,r8       # pcode for expression case
                   10436:        jsb     patst           # call common routine to build node
                   10437:        .long   er_070          # breakx argument is not string or expression
                   10438: #
                   10439: #      NOW HOOK BREAKX NODE ON AT FRONT END
                   10440: #
                   10441:        movl    r9,-(sp)        # save ptr to break node
                   10442:        movl    $p$bkx,r7       # set pcode for breakx node
                   10443:        jsb     pbild           # build it
                   10444:        movl    (sp),4*pthen(r9)# set break node as successor
                   10445:        movl    $p$alt,r7       # set pcode for alternation node
                   10446:        jsb     pbild           # build (parm1=alt=breakx node)
                   10447:        movl    r9,r6           # save ptr to alternation node
                   10448:        movl    (sp),r9         # point to break node
                   10449:        movl    r6,4*pthen(r9)  # set alternate node as successor
                   10450:        jmp     exits           # exit with result on stack
                   10451:        #page   
                   10452: #
                   10453: #      CHAR
                   10454: #
                   10455: s$chr:                         # entry point
                   10456:        jsb     gtsmi           # convert arg to integer
                   10457:        .long   er_281          # char argument not integer
                   10458:        .long   schr1           # too big error exit
                   10459:        cmpl    r8,$cfp$a       # see if out of range of host set
                   10460:        bgequ   schr1
                   10461:        movl    $num01,r6       # if not set scblk allocation
                   10462:        movl    r8,r7           # save char code
                   10463:        jsb     alocs           # allocate 1 bau scblk
                   10464:        movl    r9,r10          # copy scblk pointer
                   10465:        movab   cfp$f(r10),r10  # get set to stuff char
                   10466:        movb    r7,(r10)+       # stuff it
                   10467:        clrl    r10             # clear slop in xl
                   10468:        jmp     exixr           # exit with scblk pointer
                   10469: #
                   10470: #      HERE IF CHAR ARGUMENT IS OUT OF RANGE
                   10471: #
                   10472: schr1: jmp     er_282          # char argument not in range
                   10473:        #page   
                   10474: #
                   10475: #      CLEAR
                   10476: #
                   10477: s$clr:                         # entry point
                   10478:        jsb     xscni           # initialize to scan argument
                   10479:        .long   er_071          # clear argument is not string
                   10480:        .long   sclr2           # jump if null
                   10481: #
                   10482: #      LOOP TO SCAN OUT NAMES IN FIRST ARGUMENT. VARIABLES IN
                   10483: #      THE LIST ARE FALGGED BY SETTING VRGET OF VRBLK TO ZERO.
                   10484: #
                   10485: sclr1: movl    $ch$cm,r8       # set delimiter one = comma
                   10486:        movl    r8,r10          # delimiter two = comma
                   10487:        jsb     xscan           # scan next variable name
                   10488:        jsb     gtnvr           # locate vrblk
                   10489:        .long   er_072          # clear argument has null variable name
                   10490:        clrl    4*vrget(r9)     # else flag by zeroing vrget field
                   10491:        tstl    r6              # loop back if stopped by comma
                   10492:        bnequ   sclr1
                   10493: #
                   10494: #      HERE AFTER FLAGGING VARIABLES IN ARGUMENT LIST
                   10495: #
                   10496: sclr2: movl    hshtb,r7        # point to start of hash table
                   10497: #
                   10498: #      LOOP THROUGH SLOTS IN HASH TABLE
                   10499: #
                   10500: sclr3: cmpl    r7,hshte        # exit returning null if none left
                   10501:        bnequ   0f
                   10502:        jmp     exnul
                   10503: 0:             
                   10504:        movl    r7,r9           # else copy slot pointer
                   10505:        addl2   $4,r7           # bump slot pointer
                   10506:        subl2   $4*vrnxt,r9     # set offset to merge into loop
                   10507: #
                   10508: #      LOOP THROUGH VRBLKS ON ONE HASH CHAIN
                   10509: #
                   10510: sclr4: movl    4*vrnxt(r9),r9  # point to next vrblk on chain
                   10511:        tstl    r9              # jump for next bucket if chain end
                   10512:        beqlu   sclr3
                   10513:        tstl    4*vrget(r9)     # jump if not flagged
                   10514:        bnequ   sclr5
                   10515:        #page   
                   10516: #
                   10517: #      CLEAR (CONTINUED)
                   10518: #
                   10519: #      HERE FOR FLAGGED VARIABLE, DO NOT SET VALUE TO NULL
                   10520: #
                   10521:        jsb     setvr           # for flagged var, restore vrget
                   10522:        jmp     sclr4           # and loop back for next vrblk
                   10523: #
                   10524: #      HERE TO SET VALUE OF A VARIABLE TO NULL
                   10525: #      PRROTECTED VARIABLES (ARB, ETC) ARE EXEMPT
                   10526: #
                   10527: sclr5: cmpl    4*vrsto(r9),$b$vre # check for protected variable (reg05)
                   10528:        beqlu   sclr4
                   10529:        movl    r9,r10          # copy vrblk pointer (reg05)
                   10530: #
                   10531: #      LOOP TO LOCATE VALUE AT END OF POSSIBLE TRBLK CHAIN
                   10532: #
                   10533: sclr6: movl    r10,r6          # save block pointer
                   10534:        movl    4*vrval(r10),r10# load next value field
                   10535:        cmpl    (r10),$b$trt    # loop back if trapped
                   10536:        beqlu   sclr6
                   10537: #
                   10538: #      NOW STORE THE NULL VALUE
                   10539: #
                   10540:        movl    r6,r10          # restore block pointer
                   10541:        movl    $nulls,4*vrval(r10) # store null constant value
                   10542:        jmp     sclr4           # loop back for next vrblk
                   10543:        #page   
                   10544: #
                   10545: #      CODE
                   10546: #
                   10547: s$cod:                         # entry point
                   10548:        movl    (sp)+,r9        # load argument
                   10549:        jsb     gtcod           # convert to code
                   10550:        .long   exfal           # fail if conversion is impossible
                   10551:        jmp     exixr           # else return code as result
                   10552:        #page   
                   10553: #
                   10554: #      COLLECT
                   10555: #
                   10556: s$col:                         # entry point
                   10557:        movl    (sp)+,r9        # load argument
                   10558:        jsb     gtint           # convert to integer
                   10559:        .long   er_073          # collect argument is not integer
                   10560:        movl    4*icval(r9),r5  # load collect argument
                   10561:        movl    r5,clsvi        # save collect argument
                   10562:        clrl    r7              # set no move up
                   10563:        jsb     gbcol           # perform garbage collection
                   10564:        movl    dname,r6        # point to end of memory
                   10565:        subl2   dnamp,r6        # subtract next location
                   10566:        ashl    $-2,r6,r6       # convert bytes to words
                   10567:        movl    r6,r5           # convert words available as integer
                   10568:        subl2   clsvi,r5        # subtract argument
                   10569:        bvc     0f
                   10570:        jmp     exfal
                   10571: 0:             
                   10572:        tstl    r5              # fail if not enough
                   10573:        bgeq    0f
                   10574:        jmp     exfal
                   10575: 0:             
                   10576:        addl2   clsvi,r5        # else recompute available
                   10577:        jmp     exint           # and exit with integer result
                   10578:        #page   
                   10579: #
                   10580: #      CONVERT
                   10581: #
                   10582: s$cnv:                         # entry point
                   10583:        jsb     gtstg           # convert second argument to string
                   10584:        .long   er_074          # convert second argument is not string
                   10585:        jsb     flstg           # fold lower case to upper case
                   10586:        movl    (sp),r10        # load first argument
                   10587:        cmpl    (r10),$b$pdt    # jump if not program defined
                   10588:        bnequ   scv01
                   10589: #
                   10590: #      HERE FOR PROGRAM DEFINED DATATYPE
                   10591: #
                   10592:        movl    4*pddfp(r10),r10# point to dfblk
                   10593:        movl    4*dfnam(r10),r10# load datatype name
                   10594:        jsb     ident           # compare with second arg
                   10595:        .long   exits           # exit if ident with arg as result
                   10596:        jmp     exfal           # else fail
                   10597: #
                   10598: #      HERE IF NOT PROGRAM DEFINED DATATYPE
                   10599: #
                   10600: scv01: movl    r9,-(sp)        # save string argument
                   10601:        movl    $svctb,r10      # point to table of names to compare
                   10602:        clrl    r7              # initialize counter
                   10603:        movl    r6,r8           # save length of argument string
                   10604: #
                   10605: #      LOOP THROUGH TABLE ENTRIES
                   10606: #
                   10607: scv02: movl    (r10)+,r9       # load next table entry, bump pointer
                   10608:        tstl    r9              # fail if zero marking end of list
                   10609:        bnequ   0f
                   10610:        jmp     exfal
                   10611: 0:             
                   10612:        cmpl    r8,4*sclen(r9)  # jump if wrong length
                   10613:        beqlu   0f
                   10614:        jmp     scv05
                   10615: 0:             
                   10616:        movl    r10,cnvtp       # else store table pointer
                   10617:        movab   cfp$f(r9),r9    # point to chars of table entry
                   10618:        movl    (sp),r10        # load pointer to string argument
                   10619:        movab   cfp$f(r10),r10  # point to chars of string arg
                   10620:        movl    r8,r6           # set number of chars to compare
                   10621:        jsb     sbcmc           # compare, jump if no match
                   10622:        .long   scv04
                   10623:        .long   scv04
                   10624:        #page   
                   10625: #
                   10626: #      CONVERT (CONTINUED)
                   10627: #
                   10628: #      HERE WE HAVE A MATCH
                   10629: #
                   10630: scv03: movl    r7,r10          # copy entry number
                   10631:        addl2   $4,sp           # pop string arg off stack
                   10632:        movl    (sp)+,r9        # load first argument
                   10633:        casel   r10,$0,$cnvtt   # jump to appropriate routine
                   10634: 5:             
                   10635:        .word   scv06-5b        # string
                   10636:        .word   scv07-5b        # integer
                   10637:        .word   scv09-5b        # name
                   10638:        .word   scv10-5b        # pattern
                   10639:        .word   scv11-5b        # array
                   10640:        .word   scv19-5b        # table
                   10641:        .word   scv25-5b        # expression
                   10642:        .word   scv26-5b        # code
                   10643:        .word   scv27-5b        # numeric
                   10644:        .word   scv08-5b        # real
                   10645:        .word   scv28-5b        # buffer
                   10646:        #esw                    # end of switch table
                   10647: #
                   10648: #      HERE IF NO MATCH WITH TABLE ENTRY
                   10649: #
                   10650: scv04: movl    cnvtp,r10       # restore table pointer, merge
                   10651: #
                   10652: #      MERGE HERE IF LENGTHS DID NOT MATCH
                   10653: #
                   10654: scv05: incl    r7              # bump entry number
                   10655:        jmp     scv02           # loop back to check next entry
                   10656: #
                   10657: #      HERE TO CONVERT TO STRING
                   10658: #
                   10659: scv06: movl    r9,-(sp)        # replace string argument on stack
                   10660:        jsb     gtstg           # convert to string
                   10661:        .long   exfal           # fail if conversion not possible
                   10662:        jmp     exixr           # else return string
                   10663:        #page   
                   10664: #
                   10665: #      CONVERT (CONTINUED)
                   10666: #
                   10667: #      HERE TO CONVERT TO INTEGER
                   10668: #
                   10669: scv07: jsb     gtint           # convert to integer
                   10670:        .long   exfal           # fail if conversion not possible
                   10671:        jmp     exixr           # else return integer
                   10672: #
                   10673: #      HERE TO CONVERT TO REAL
                   10674: #
                   10675: scv08: jsb     gtrea           # convert to real
                   10676:        .long   exfal           # fail if conversion not possible
                   10677:        jmp     exixr           # else return real
                   10678: #
                   10679: #      HERE TO CONVERT TO NAME
                   10680: #
                   10681: scv09: cmpl    (r9),$b$nml     # return if already a name
                   10682:        bnequ   0f
                   10683:        jmp     exixr
                   10684: 0:             
                   10685:        jsb     gtnvr           # else try string to name convert
                   10686:        .long   exfal           # fail if conversion not possible
                   10687:        jmp     exvnm           # else exit building nmblk for vrblk
                   10688: #
                   10689: #      HERE TO CONVERT TO PATTERN
                   10690: #
                   10691: scv10: jsb     gtpat           # convert to pattern
                   10692:        .long   exfal           # fail if conversion not possible
                   10693:        jmp     exixr           # else return pattern
                   10694: #
                   10695: #      CONVERT TO ARRAY
                   10696: #
                   10697: scv11: jsb     gtarr           # get an array
                   10698:        .long   exfal           # fail if not convertible
                   10699:        jmp     exsid           # exit setting id field
                   10700: #
                   10701: #      CONVERT TO TABLE
                   10702: #
                   10703: scv19: movl    (r9),r6         # load first word of block
                   10704:        movl    r9,-(sp)        # replace arblk pointer on stack
                   10705:        cmpl    r6,$b$tbt       # return arg if already a table
                   10706:        bnequ   0f
                   10707:        jmp     exits
                   10708: 0:             
                   10709:        cmpl    r6,$b$art       # else fail if not an array
                   10710:        beqlu   0f
                   10711:        jmp     exfal
                   10712: 0:             
                   10713:        #page   
                   10714: #
                   10715: #      CONVERT (CONTINUED)
                   10716: #
                   10717: #      HERE TO CONVERT AN ARRAY TO TABLE
                   10718: #
                   10719:        cmpl    4*arndm(r9),$num02 # fail if not 2-dim array
                   10720:        beqlu   0f
                   10721:        jmp     exfal
                   10722: 0:             
                   10723:        movl    4*ardm2(r9),r5  # load dim 2
                   10724:        subl2   intv2,r5        # subtract 2 to compare
                   10725:        tstl    r5              # fail if dim2 not 2
                   10726:        beql    0f
                   10727:        jmp     exfal
                   10728: 0:             
                   10729: #
                   10730: #      HERE WE HAVE AN ARBLK OF THE RIGHT SHAPE
                   10731: #
                   10732:        movl    4*ardim(r9),r5  # load dim 1 (number of elements)
                   10733:        movl    r5,r6           # get as one word integer
                   10734:        movl    r6,r7           # copy to control loop
                   10735:        addl2   $tbsi$,r6       # add space for standard fields
                   10736:        moval   0[r6],r6        # convert length to bytes
                   10737:        jsb     alloc           # allocate space for tbblk
                   10738:        movl    r9,r8           # copy tbblk pointer
                   10739:        movl    r9,-(sp)        # save tbblk pointer
                   10740:        movl    $b$tbt,(r9)+    # store type word
                   10741:        clrl    (r9)+           # store zero for idval for now
                   10742:        movl    r6,(r9)+        # store length
                   10743:        movl    $nulls,(r9)+    # null initial lookup value
                   10744: #
                   10745: #      LOOP TO INITIALIZE BUCKET PTRS TO POINT TO TABLE
                   10746: #
                   10747: scv20: movl    r8,(r9)+        # set bucket ptr to point to tbblk
                   10748:        sobgtr  r7,scv20        # loop till all initialized
                   10749:        movl    $4*arvl2,r7     # set offset to first arblk element
                   10750: #
                   10751: #      LOOP TO COPY ELEMENTS FROM ARRAY TO TABLE
                   10752: #
                   10753: scv21: movl    4*1(sp),r10     # point to arblk
                   10754:        cmpl    r7,4*arlen(r10) # jump if all moved
                   10755:        beqlu   scv24
                   10756:        addl2   r7,r10          # else point to current location
                   10757:        addl2   $4*num02,r7     # bump offset
                   10758:        movl    (r10),r9        # load subscript name
                   10759:        subl2   $4,r10          # adjust ptr to merge (trval=1+1)
                   10760:        #page   
                   10761: #
                   10762: #      CONVERT (CONTINUED)
                   10763: #
                   10764: #      LOOP TO CHASE DOWN TRBLK CHAIN FOR VALUE
                   10765: #
                   10766: scv22: movl    4*trval(r10),r10# point to next value
                   10767:        cmpl    (r10),$b$trt    # loop back if trapped
                   10768:        beqlu   scv22
                   10769: #
                   10770: #      HERE WITH NAME IN XR, VALUE IN XL
                   10771: #
                   10772: scv23: movl    r10,-(sp)       # stack value
                   10773:        movl    4*1(sp),r10     # load tbblk pointer
                   10774:        jsb     tfind           # build teblk (note wb gt 0 by name)
                   10775:        .long   exfal           # fail if acess fails
                   10776:        movl    (sp)+,4*teval(r10) # store value in teblk
                   10777:        jmp     scv21           # loop back for next element
                   10778: #
                   10779: #      HERE AFTER MOVING ALL ELEMENTS TO TBBLK
                   10780: #
                   10781: scv24: movl    (sp)+,r9        # load tbblk pointer
                   10782:        addl2   $4,sp           # pop arblk pointer
                   10783:        jmp     exsid           # exit setting idval
                   10784: #
                   10785: #      CONVERT TO EXPRESSION
                   10786: #
                   10787: scv25: jsb     gtexp           # convert to expression
                   10788:        .long   exfal           # fail if conversion not possible
                   10789:        jmp     exixr           # else return expression
                   10790: #
                   10791: #      CONVERT TO CODE
                   10792: #
                   10793: scv26: jsb     gtcod           # convert to code
                   10794:        .long   exfal           # fail if conversion is not possible
                   10795:        jmp     exixr           # else return code
                   10796: #
                   10797: #      CONVERT TO NUMERIC
                   10798: #
                   10799: scv27: jsb     gtnum           # convert to numeric
                   10800:        .long   exfal           # fail if unconvertible
                   10801:        jmp     exixr           # return number
                   10802:        #page   
                   10803: #
                   10804: #      CONVERT TO BUFFER
                   10805: #
                   10806: scv28: movl    r9,-(sp)        # stack string for procedure
                   10807:        jsb     gtstg           # convert to string
                   10808:        .long   exfal           # fail if conversion not possible
                   10809:        movl    r9,r10          # save string pointer
                   10810:        jsb     alobf           # allocate buffer of same size
                   10811:        jsb     apndb           # copy in the string
                   10812:        .long   invalid$        # already string - cant fail to cnv
                   10813:        .long   invalid$        # must be enough room
                   10814:        jmp     exsid           # exit setting idval field
                   10815:        #page   
                   10816: #
                   10817: #      COPY
                   10818: #
                   10819: s$cop:                         # entry point
                   10820:        jsb     copyb           # copy the block
                   10821:        .long   exits           # return if no idval field
                   10822:        jmp     exsid           # exit setting id value
                   10823:        #page   
                   10824: #
                   10825: #      DATA
                   10826: #
                   10827: s$dat:                         # entry point
                   10828:        jsb     xscni           # prepare to scan argument
                   10829:        .long   er_075          # data argument is not string
                   10830:        .long   er_076          # data argument is null
                   10831: #
                   10832: #      SCAN OUT DATATYPE NAME
                   10833: #
                   10834:        movl    $ch$pp,r8       # delimiter one = left paren
                   10835:        movl    r8,r10          # delimiter two = left paren
                   10836:        jsb     xscan           # scan datatype name
                   10837:        tstl    r6              # skip if left paren found
                   10838:        bnequ   sdat1
                   10839:        jmp     er_077          # data argument is missing a left paren
                   10840: #
                   10841: #      HERE AFTER SCANNING DATATYPE NAME
                   10842: #
                   10843: sdat1: movl    4*sclen(r9),r6  # get length
                   10844:        jsb     flstg           # fold lower case to upper case
                   10845:        movl    r9,r10          # save name ptr
                   10846:        movl    4*sclen(r9),r6  # get length
                   10847:        movab   3+(4*scsi$)(r6),r6 # compute space needed
                   10848:        bicl2   $3,r6
                   10849:        jsb     alost           # request static store for name
                   10850:        movl    r9,-(sp)        # save datatype name
                   10851:        jsb     sbmvw           # copy name to static
                   10852:        movl    (sp),r9         # get name ptr
                   10853:        clrl    r10             # scrub dud register
                   10854:        jsb     gtnvr           # locate vrblk for datatype name
                   10855:        .long   er_078          # data argument has null datatype name
                   10856:        movl    r9,datdv        # save vrblk pointer for datatype
                   10857:        movl    sp,datxs        # store starting stack value
                   10858:        clrl    r7              # zero count of field names
                   10859: #
                   10860: #      LOOP TO SCAN FIELD NAMES AND STACK VRBLK POINTERS
                   10861: #
                   10862: sdat2: movl    $ch$rp,r8       # delimiter one = right paren
                   10863:        movl    $ch$cm,r10      # delimiter two = comma
                   10864:        jsb     xscan           # scan next field name
                   10865:        tstl    r6              # jump if delimiter found
                   10866:        bnequ   sdat3
                   10867:        jmp     er_079          # data argument is missing a right paren
                   10868: #
                   10869: #      HERE AFTER SCANNING OUT ONE FIELD NAME
                   10870: #
                   10871: sdat3: jsb     gtnvr           # locate vrblk for field name
                   10872:        .long   er_080          # data argument has null field name
                   10873:        movl    r9,-(sp)        # stack vrblk pointer
                   10874:        incl    r7              # increment counter
                   10875:        cmpl    r6,$num02       # loop back if stopped by comma
                   10876:        beqlu   sdat2
                   10877:        #page   
                   10878: #
                   10879: #      DATA (CONTINUED)
                   10880: #
                   10881: #      NOW BUILD THE DFBLK
                   10882: #
                   10883:        movl    $dfsi$,r6       # set size of dfblk standard fields
                   10884:        addl2   r7,r6           # add number of fields
                   10885:        moval   0[r6],r6        # convert length to bytes
                   10886:        movl    r7,r8           # preserve no. of fields
                   10887:        jsb     alost           # allocate space for dfblk
                   10888:        movl    r8,r7           # get no of fields
                   10889:        movl    datxs,r10       # point to start of stack
                   10890:        movl    (r10),r8        # load datatype name
                   10891:        movl    r9,(r10)        # save dfblk pointer on stack
                   10892:        movl    $b$dfc,(r9)+    # store type word
                   10893:        movl    r7,(r9)+        # store number of fields (fargs)
                   10894:        movl    r6,(r9)+        # store length (dflen)
                   10895:        subl2   $4*pddfs,r6     # compute pdblk length (for dfpdl)
                   10896:        movl    r6,(r9)+        # store pdblk length (dfpdl)
                   10897:        movl    r8,(r9)+        # store datatype name (dfnam)
                   10898:        movl    r7,r8           # copy number of fields
                   10899: #
                   10900: #      LOOP TO MOVE FIELD NAME VRBLK POINTERS TO DFBLK
                   10901: #
                   10902: sdat4: movl    -(r10),(r9)+    # move one field name vrblk pointer
                   10903:        sobgtr  r8,sdat4        # loop till all moved
                   10904: #
                   10905: #      NOW DEFINE THE DATATYPE FUNCTION
                   10906: #
                   10907:        movl    r6,r8           # copy length of pdblk for later loop
                   10908:        movl    datdv,r9        # point to vrblk
                   10909:        movl    datxs,r10       # point back on stack
                   10910:        movl    (r10),r10       # load dfblk pointer
                   10911:        jsb     dffnc           # define function
                   10912:        #page   
                   10913: #
                   10914: #      DATA (CONTINUED)
                   10915: #
                   10916: #      LOOP TO BUILD FFBLKS
                   10917: #
                   10918: #
                   10919: #      NOTICE THAT THE FFBLKS ARE CONSTRUCTED IN REVERSE ORDER
                   10920: #      SO THAT THE REQUIRED OFFSETS CAN BE OBTAINED FROM
                   10921: #      SUCCESSIVE DECREMENTATION OF THE PDBLK LENGTH (IN WC).
                   10922: #
                   10923: sdat5: movl    $4*ffsi$,r6     # set length of ffblk
                   10924:        jsb     alloc           # allocate space for ffblk
                   10925:        movl    $b$ffc,(r9)     # set type word
                   10926:        movl    $num01,4*fargs(r9) # store fargs (always one)
                   10927:        movl    datxs,r10       # point back on stack
                   10928:        movl    (r10),4*ffdfp(r9)# copy dfblk ptr to ffblk
                   10929:        subl2   $4,r8           # decrement old dfpdl to get next ofs
                   10930:        movl    r8,4*ffofs(r9)  # set offset to this field
                   10931:        clrl    4*ffnxt(r9)     # tentatively set zero forward ptr
                   10932:        movl    r9,r10          # copy ffblk pointer for dffnc
                   10933:        movl    (sp),r9         # load vrblk pointer for field
                   10934:        movl    4*vrfnc(r9),r9  # load current function pointer
                   10935:        cmpl    (r9),$b$ffc     # skip if not currently a field func
                   10936:        bnequ   sdat6
                   10937: #
                   10938: #      HERE WE MUST CHAIN AN OLD FFBLK PTR TO PRESERVE IT IN THE
                   10939: #      CASE OF MULTIPLE FIELD FUNCTIONS WITH THE SAME NAME
                   10940: #
                   10941:        movl    r9,4*ffnxt(r10) # link new ffblk to previous chain
                   10942: #
                   10943: #      MERGE HERE TO DEFINE FIELD FUNCTION
                   10944: #
                   10945: sdat6: movl    (sp)+,r9        # load vrblk pointer
                   10946:        jsb     dffnc           # define field function
                   10947:        cmpl    sp,datxs        # loop back till all done
                   10948:        bnequ   sdat5
                   10949:        addl2   $4,sp           # pop dfblk pointer
                   10950:        jmp     exnul           # return with null result
                   10951:        #page   
                   10952: #
                   10953: #      DATATYPE
                   10954: #
                   10955: s$dtp:                         # entry point
                   10956:        movl    (sp)+,r9        # load argument
                   10957:        jsb     dtype           # get datatype
                   10958:        jmp     exixr           # and return it as result
                   10959:        #page   
                   10960: #
                   10961: #      DATE
                   10962: #
                   10963: s$dte:                         # entry point
                   10964:        jsb     sysdt           # call system date routine
                   10965:        movl    4*1(r10),r6     # load length for sbstr
                   10966:        tstl    r6              # return null if length is zero
                   10967:        bnequ   0f
                   10968:        jmp     exnul
                   10969: 0:             
                   10970:        clrl    r7              # set zero offset
                   10971:        jsb     sbstr           # use sbstr to build scblk
                   10972:        jmp     exixr           # return date string
                   10973:        #page   
                   10974: #
                   10975: #      DEFINE
                   10976: #
                   10977: s$def:                         # entry point
                   10978:        movl    (sp)+,r9        # load second argument
                   10979:        clrl    deflb           # zero label pointer in case null
                   10980:        cmpl    r9,$nulls       # jump if null second argument
                   10981:        beqlu   sdf01
                   10982:        jsb     gtnvr           # else find vrblk for label
                   10983:        .long   sdf13           # jump if not a variable name
                   10984:        movl    r9,deflb        # else set specified entry
                   10985: #
                   10986: #      SCAN FUNCTION NAME
                   10987: #
                   10988: sdf01: jsb     xscni           # prepare to scan first argument
                   10989:        .long   er_081          # define first argument is not string
                   10990:        .long   er_082          # define first argument is null
                   10991:        movl    $ch$pp,r8       # delimiter one = left paren
                   10992:        movl    r8,r10          # delimiter two = left paren
                   10993:        jsb     xscan           # scan out function name
                   10994:        tstl    r6              # jump if left paren found
                   10995:        bnequ   sdf02
                   10996:        jmp     er_083          # define first argument is missing a left paren
                   10997: #
                   10998: #      HERE AFTER SCANNING OUT FUNCTION NAME
                   10999: #
                   11000: sdf02: jsb     gtnvr           # get variable name
                   11001:        .long   er_084          # define first argument has null function name
                   11002:        movl    r9,defvr        # save vrblk pointer for function nam
                   11003:        clrl    r7              # zero count of arguments
                   11004:        movl    sp,defxs        # save initial stack pointer
                   11005:        tstl    deflb           # jump if second argument given
                   11006:        bnequ   sdf03
                   11007:        movl    r9,deflb        # else default is function name
                   11008: #
                   11009: #      LOOP TO SCAN ARGUMENT NAMES AND STACK VRBLK POINTERS
                   11010: #
                   11011: sdf03: movl    $ch$rp,r8       # delimiter one = right paren
                   11012:        movl    $ch$cm,r10      # delimiter two = comma
                   11013:        jsb     xscan           # scan out next argument name
                   11014:        tstl    r6              # skip if delimiter found
                   11015:        bnequ   sdf04
                   11016:        jmp     er_085          # null arg name or missing ) in define first arg.
                   11017:        #page   
                   11018: #
                   11019: #      DEFINE (CONTINUED)
                   11020: #
                   11021: #      HERE AFTER SCANNING AN ARGUMENT NAME
                   11022: #
                   11023: sdf04: cmpl    r9,$nulls       # skip if non-null
                   11024:        bnequ   sdf05
                   11025:        tstl    r7              # ignore null if case of no arguments
                   11026:        beqlu   sdf06
                   11027: #
                   11028: #      HERE AFTER DEALING WITH THE CASE OF NO ARGUMENTS
                   11029: #
                   11030: sdf05: jsb     gtnvr           # get vrblk pointer
                   11031:        .long   sdf03           # loop back to ignore null name
                   11032:        movl    r9,-(sp)        # stack argument vrblk pointer
                   11033:        incl    r7              # increment counter
                   11034:        cmpl    r6,$num02       # loop back if stopped by a comma
                   11035:        beqlu   sdf03
                   11036: #
                   11037: #      HERE AFTER SCANNING OUT FUNCTION ARGUMENT NAMES
                   11038: #
                   11039: sdf06: movl    r7,defna        # save number of arguments
                   11040:        clrl    r7              # zero count of locals
                   11041: #
                   11042: #      LOOP TO SCAN LOCAL NAMES AND STACK VRBLK POINTERS
                   11043: #
                   11044: sdf07: movl    $ch$cm,r8       # set delimiter one = comma
                   11045:        movl    r8,r10          # set delimiter two = comma
                   11046:        jsb     xscan           # scan out next local name
                   11047:        cmpl    r9,$nulls       # skip if non-null
                   11048:        bnequ   sdf08
                   11049:        tstl    r7              # ignore null if case of no locals
                   11050:        beqlu   sdf09
                   11051: #
                   11052: #      HERE AFTER SCANNING OUT A LOCAL NAME
                   11053: #
                   11054: sdf08: jsb     gtnvr           # get vrblk pointer
                   11055:        .long   sdf07           # loop back to ignore null name
                   11056:        incl    r7              # if ok, increment count
                   11057:        movl    r9,-(sp)        # stack vrblk pointer
                   11058:        tstl    r6              # loop back if stopped by a comma
                   11059:        bnequ   sdf07
                   11060:        #page   
                   11061: #
                   11062: #      DEFINE (CONTINUED)
                   11063: #
                   11064: #      HERE AFTER SCANNING LOCALS, BUILD PFBLK
                   11065: #
                   11066: sdf09: movl    r7,r6           # copy count of locals
                   11067:        addl2   defna,r6        # add number of arguments
                   11068:        movl    r6,r8           # set sum args+locals as loop count
                   11069:        addl2   $pfsi$,r6       # add space for standard fields
                   11070:        moval   0[r6],r6        # convert length to bytes
                   11071:        jsb     alloc           # allocate space for pfblk
                   11072:        movl    r9,r10          # save pointer to pfblk
                   11073:        movl    $b$pfc,(r9)+    # store first word
                   11074:        movl    defna,(r9)+     # store number of arguments
                   11075:        movl    r6,(r9)+        # store length (pflen)
                   11076:        movl    defvr,(r9)+     # store vrblk ptr for function name
                   11077:        movl    r7,(r9)+        # store number of locals
                   11078:        clrl    (r9)+           # deal with label later
                   11079:        clrl    (r9)+           # zero pfctr
                   11080:        clrl    (r9)+           # zero pfrtr
                   11081:        tstl    r8              # skip if no args or locals
                   11082:        beqlu   sdf11
                   11083:        movl    r10,r6          # keep pfblk pointer
                   11084:        movl    defxs,r10       # point before arguments
                   11085:                                # get count of args+locals for loop
                   11086: #
                   11087: #      LOOP TO MOVE LOCALS AND ARGS TO PFBLK
                   11088: #
                   11089: sdf10: movl    -(r10),(r9)+    # store one entry and bump pointers
                   11090:        sobgtr  r8,sdf10        # loop till all stored
                   11091:        movl    r6,r10          # recover pfblk pointer
                   11092:        #page   
                   11093: #
                   11094: #      DEFINE (CONTINUED)
                   11095: #
                   11096: #      NOW DEAL WITH LABEL
                   11097: #
                   11098: sdf11: movl    defxs,sp        # pop stack
                   11099:        movl    deflb,r9        # point to vrblk for label
                   11100:        movl    4*vrlbl(r9),r9  # load label pointer
                   11101:        cmpl    (r9),$b$trt     # skip if not trapped
                   11102:        bnequ   sdf12
                   11103:        movl    4*trlbl(r9),r9  # else point to real label
                   11104: #
                   11105: #      HERE AFTER LOCATING REAL LABEL POINTER
                   11106: #
                   11107: sdf12: cmpl    r9,$stndl       # jump if label is not defined
                   11108:        beqlu   sdf13
                   11109:        movl    r9,4*pfcod(r10) # else store label pointer
                   11110:        movl    defvr,r9        # point back to vrblk for function
                   11111:        jsb     dffnc           # define function
                   11112:        jmp     exnul           # and exit returning null
                   11113: #
                   11114: #      HERE FOR ERRONEOUS LABEL
                   11115: #
                   11116: sdf13: jmp     er_086          # define function entry point is not defined label
                   11117:        #page   
                   11118: #
                   11119: #      DETACH
                   11120: #
                   11121: s$det:                         # entry point
                   11122:        movl    (sp)+,r9        # load argument
                   11123:        jsb     gtvar           # locate variable
                   11124:        .long   er_087          # detach argument is not appropriate name
                   11125:        jsb     dtach           # detach i/o association from name
                   11126:        jmp     exnul           # return null result
                   11127:        #page   
                   11128: #
                   11129: #      DIFFER
                   11130: #
                   11131: s$dif:                         # entry point
                   11132:        movl    (sp)+,r9        # load second argument
                   11133:        movl    (sp)+,r10       # load first argument
                   11134:        jsb     ident           # call ident comparison routine
                   11135:        .long   exfal           # fail if ident
                   11136:        jmp     exnul           # return null if differ
                   11137:        #page   
                   11138: #
                   11139: #      DUMP
                   11140: #
                   11141: s$dmp:                         # entry point
                   11142:        jsb     gtsmi           # load dump arg as small integer
                   11143:        .long   er_088          # dump argument is not integer
                   11144:        .long   er_089          # dump argument is negative or too large
                   11145:        jsb     dumpr           # else call dump routine
                   11146:        jmp     exnul           # and return null as result
                   11147:        #page   
                   11148: #
                   11149: #      DUPL
                   11150: #
                   11151: s$dup:                         # entry point
                   11152:        jsb     gtsmi           # get second argument as small intege
                   11153:        .long   er_090          # dupl second argument is not integer
                   11154:        .long   sdup7           # jump if negative ot too big
                   11155:        movl    r9,r7           # save duplication factor
                   11156:        jsb     gtstg           # get first arg as string
                   11157:        .long   sdup4           # jump if not a string
                   11158: #
                   11159: #      HERE FOR CASE OF DUPLICATION OF A STRING
                   11160: #
                   11161:        movl    r6,r5           # acquire length as integer
                   11162:        movl    r5,dupsi        # save for the moment
                   11163:        movl    r7,r5           # get duplication factor as integer
                   11164:        mull2   dupsi,r5        # form product
                   11165:        bvs     sdup3
                   11166:        tstl    r5              # return null if result length = 0
                   11167:        bneq    0f
                   11168:        jmp     exnul
                   11169: 0:             
                   11170:        movl    r5,r6           # get as addr integer, check ovflo
                   11171:        bgeq    0f
                   11172:        jmp     sdup3
                   11173: 0:             
                   11174: #
                   11175: #      MERGE HERE WITH RESULT LENGTH IN WA
                   11176: #
                   11177: sdup1: movl    r9,r10          # save string pointer
                   11178:        jsb     alocs           # allocate space for string
                   11179:        movl    r9,-(sp)        # save as result pointer
                   11180:        movl    r10,r8          # save pointer to argument string
                   11181:        movab   cfp$f(r9),r9    # prepare to store chars of result
                   11182:                                # set counter to control loop
                   11183: #
                   11184: #      LOOP THROUGH DUPLICATIONS
                   11185: #
                   11186: sdup2: movl    r8,r10          # point back to argument string
                   11187:        movl    4*sclen(r10),r6 # get number of characters
                   11188:        movab   cfp$f(r10),r10  # point to chars in argument string
                   11189:        jsb     sbmvc           # move characters to result string
                   11190:        sobgtr  r7,sdup2        # loop till all duplications done
                   11191:        jmp     exits           # then exit for next code word
                   11192:        #page   
                   11193: #
                   11194: #      DUPL (CONTINUED)
                   11195: #
                   11196: #      HERE IF TOO LARGE, SET MAX LENGTH AND LET ALOCS CATCH IT
                   11197: #
                   11198: sdup3: movl    dname,r6        # set impossible length for alocs
                   11199:        jmp     sdup1           # merge back
                   11200: #
                   11201: #      HERE IF NOT A STRING
                   11202: #
                   11203: sdup4: jsb     gtpat           # convert argument to pattern
                   11204:        .long   er_091          # dupl first argument is not string or pattern
                   11205: #
                   11206: #      HERE TO DUPLICATE A PATTERN ARGUMENT
                   11207: #
                   11208:        movl    r9,-(sp)        # store pattern on stack
                   11209:        movl    $ndnth,r9       # start off with null pattern
                   11210:        tstl    r7              # null pattern is result if dupfac=0
                   11211:        beqlu   sdup6
                   11212:        movl    r7,-(sp)        # preserve loop count
                   11213: #
                   11214: #      LOOP TO DUPLICATE BY SUCCESSIVE CONCATENATION
                   11215: #
                   11216: sdup5: movl    r9,r10          # copy current value as right argumnt
                   11217:        movl    4*1(sp),r9      # get a new copy of left
                   11218:        jsb     pconc           # concatenate
                   11219:        decl    (sp)            # count down
                   11220:        tstl    (sp)            # loop
                   11221:        bnequ   sdup5
                   11222:        addl2   $4,sp           # pop loop count
                   11223: #
                   11224: #      HERE TO EXIT AFTER CONSTRUCTING PATTERN
                   11225: #
                   11226: sdup6: movl    r9,(sp)         # store result on stack
                   11227:        jmp     exits           # exit with result on stack
                   11228: #
                   11229: #      FAIL IF SECOND ARG IS OUT OF RANGE
                   11230: #
                   11231: sdup7: addl2   $4,sp           # pop first argument
                   11232:        jmp     exfal           # fail
                   11233:        #page   
                   11234: #
                   11235: #      EJECT
                   11236: #
                   11237: s$ejc:                         # entry point
                   11238:        jsb     iofcb           # call fcblk routine
                   11239:        .long   er_092          # eject argument is not a suitable name
                   11240:        .long   sejc1           # null argument
                   11241:        jsb     sysef           # call eject file function
                   11242:        .long   er_093          # eject file does not exist
                   11243:        .long   er_094          # eject file does not permit page eject
                   11244:        .long   er_095          # eject caused non-recoverable output error
                   11245:        jmp     exnul           # return null as result
                   11246: #
                   11247: #      HERE TO EJECT STANDARD OUTPUT FILE
                   11248: #
                   11249: sejc1: jsb     sysep           # call routine to eject printer
                   11250:        jmp     exnul           # exit with null result
                   11251:        #page   
                   11252: #
                   11253: #      ENDFILE
                   11254: #
                   11255: s$enf:                         # entry point
                   11256:        jsb     iofcb           # call fcblk routine
                   11257:        .long   er_096          # endfile argument is not a suitable name
                   11258:        .long   er_097          # endfile argument is null
                   11259:        jsb     sysen           # call endfile routine
                   11260:        .long   er_098          # endfile file does not exist
                   11261:        .long   er_099          # endfile file does not permit endfile
                   11262:        .long   er_100          # endfile caused non-recoverable output error
                   11263:        movl    r10,r7          # remember vrblk ptr from iofcb call
                   11264: #
                   11265: #      LOOP TO FIND TRTRF BLOCK
                   11266: #
                   11267: senf1: movl    r10,r9          # copy pointer
                   11268:        movl    4*trval(r9),r9  # chain along
                   11269:        cmpl    (r9),$b$trt     # skip out if chain end
                   11270:        beqlu   0f
                   11271:        jmp     exnul
                   11272: 0:             
                   11273:        cmpl    4*trtyp(r9),$trtfc # loop if not found
                   11274:        bnequ   senf1
                   11275:        movl    4*trval(r9),4*trval(r10) # remove trtrf
                   11276:        movl    4*trtrf(r9),enfch# point to head of iochn
                   11277:        movl    4*trfpt(r9),r8  # point to fcblk
                   11278:        movl    r7,r9           # filearg1 vrblk from iofcb
                   11279:        jsb     setvr           # reset it
                   11280:        movl    $r$fcb,r10      # ptr to head of fcblk chain
                   11281:        subl2   $4*num02,r10    # adjust ready to enter loop
                   11282: #
                   11283: #      FIND FCBLK
                   11284: #
                   11285: senf2: movl    r10,r9          # copy ptr
                   11286:        movl    4*2(r10),r10    # get next link
                   11287:        tstl    r10             # stop if chain end
                   11288:        beqlu   senf4
                   11289:        cmpl    4*3(r10),r8     # jump if fcblk found
                   11290:        beqlu   senf3
                   11291:        jmp     senf2           # loop
                   11292: #
                   11293: #      REMOVE FCBLK
                   11294: #
                   11295: senf3: movl    4*2(r10),4*2(r9)# delete fcblk from chain
                   11296: #
                   11297: #      LOOP WHICH DETACHES ALL VBLS ON IOCHN CHAIN
                   11298: #
                   11299: senf4: movl    enfch,r10       # get chain head
                   11300:        tstl    r10             # finished if chain end
                   11301:        bnequ   0f
                   11302:        jmp     exnul
                   11303: 0:             
                   11304:        movl    4*trtrf(r10),enfch # chain along
                   11305:        movl    4*ionmo(r10),r6 # name offset
                   11306:        movl    4*ionmb(r10),r10# name base
                   11307:        jsb     dtach           # detach name
                   11308:        jmp     senf4           # loop till done
                   11309:        #page   
                   11310: #
                   11311: #      EQ
                   11312: #
                   11313: s$eqf:                         # entry point
                   11314:        jsb     acomp           # call arithmetic comparison routine
                   11315:        .long   er_101          # eq first argument is not numeric
                   11316:        .long   er_102          # eq second argument is not numeric
                   11317:        .long   exfal           # fail if lt
                   11318:        .long   exnul           # return null if eq
                   11319:        .long   exfal           # fail if gt
                   11320:        #page   
                   11321: #
                   11322: #      EVAL
                   11323: #
                   11324: s$evl:                         # entry point
                   11325:        movl    (sp)+,r9        # load argument
                   11326:        jsb     gtexp           # convert to expression
                   11327:        .long   er_103          # eval argument is not expression
                   11328:        movl    (r3)+,r8        # load next code word
                   11329:        cmpl    r8,$ofne$       # jump if called by value
                   11330:        bnequ   sevl1
                   11331:        movl    r3,r10          # copy code pointer
                   11332:        movl    (r10),r6        # get next code word
                   11333:        cmpl    r6,$ornm$       # by name unless expression
                   11334:        bnequ   sevl2
                   11335:        tstl    4*1(sp) # jump if by name
                   11336:        bnequ   sevl2
                   11337: #
                   11338: #      HERE IF CALLED BY VALUE
                   11339: #
                   11340: sevl1: clrl    r7              # set flag for by value
                   11341:        movl    r8,-(sp)        # save code word
                   11342:        jsb     evalx           # evaluate expression by value
                   11343:        .long   exfal           # fail if evaluation fails
                   11344:        movl    r9,r10          # copy result
                   11345:        movl    (sp),r9         # reload next code word
                   11346:        movl    r10,(sp)        # stack result
                   11347:        movl    (r9),r11        # jump to execute next code word
                   11348:        jmp     (r11)
                   11349: #
                   11350: #      HERE IF CALLED BY NAME
                   11351: #
                   11352: sevl2: movl    $num01,r7       # set flag for by name
                   11353:        jsb     evalx           # evaluate expression by name
                   11354:        .long   exfal           # fail if evaluation fails
                   11355:        jmp     exnam           # exit with name
                   11356:        #page   
                   11357: #
                   11358: #      EXIT
                   11359: #
                   11360: s$ext:                         # entry point
                   11361:        clrl    r7              # clear amount of static shift
                   11362:        jsb     gbcol           # compact memory by collecting
                   11363:        jsb     gtstg           # convert arg to string
                   11364:        .long   er_104          # exit argument is not suitable integer or string
                   11365:        movl    r9,r10          # copy string ptr
                   11366:        jsb     gtint           # check it is integer
                   11367:        .long   sext1           # skip if unconvertible
                   11368:        clrl    r10             # note it is integer
                   11369:        movl    4*icval(r9),r5  # get integer arg
                   11370:        movl    r$fcb,r7        # get fcblk chain header
                   11371: #
                   11372: #      MERGE TO CALL OSINT EXIT ROUTINE
                   11373: #
                   11374: sext1: movl    $headv,r9       # point to v.v string
                   11375:        jsb     sysxi           # call external routine
                   11376:        .long   er_105          # exit action not available in this implementation
                   11377:        .long   er_106          # exit action caused irrecoverable error
                   11378:        tstl    r5              # return if argument 0
                   11379:        bneq    0f
                   11380:        jmp     exnul
                   11381: 0:             
                   11382:        clrl    gbcnt           # resuming execution so reset
                   11383:        tstl    r5              # skip if positive
                   11384:        bgtr    sext2
                   11385:        mnegl   r5,r5           # make positive
                   11386: #
                   11387: #      CHECK FOR OPTION RESPECIFICATION
                   11388: #
                   11389: sext2: movl    r5,r8           # get value in work reg
                   11390:        cmpl    r8,$num03       # skip if was 3
                   11391:        beqlu   sext3
                   11392:        movl    r8,-(sp)        # save value
                   11393:        clrl    r8              # set to read options
                   11394:        jsb     prpar           # read syspp options
                   11395:        movl    (sp)+,r8        # restore value
                   11396: #
                   11397: #      DEAL WITH HEADER OPTION (FIDDLED BY PRPAR)
                   11398: #
                   11399: sext3: movl    sp,headp        # assume no headers
                   11400:        cmpl    r8,$num01       # skip if not 1
                   11401:        bnequ   sext4
                   11402:        clrl    headp           # request header printing
                   11403: #
                   11404: #      ALMOST READY TO RESUME RUNNING
                   11405: #
                   11406: sext4: jsb     systm           # get execution time start (sgd11)
                   11407:        movl    r5,timsx        # save as initial time
                   11408:        movl    kvstc,r5        # reset to ensure ...
                   11409:        movl    r5,kvstl        # ... correct execution stats
                   11410:        jmp     exnul           # resume execution
                   11411:        #page   
                   11412: #
                   11413: #      FIELD
                   11414: #
                   11415: s$fld:                         # entry point
                   11416:        jsb     gtsmi           # get second argument (field number)
                   11417:        .long   er_107          # field second argument is not integer
                   11418:        .long   exfal           # fail if out of range
                   11419:        movl    r9,r7           # else save integer value
                   11420:        movl    (sp)+,r9        # load first argument
                   11421:        jsb     gtnvr           # point to vrblk
                   11422:        .long   sfld1           # jump (error) if not variable name
                   11423:        movl    4*vrfnc(r9),r9  # else point to function block
                   11424:        cmpl    (r9),$b$dfc     # error if not datatype function
                   11425:        bnequ   sfld1
                   11426: #
                   11427: #      HERE IF FIRST ARGUMENT IS A DATATYPE FUNCTION NAME
                   11428: #
                   11429:        tstl    r7              # fail if argument number is zero
                   11430:        bnequ   0f
                   11431:        jmp     exfal
                   11432: 0:             
                   11433:        cmpl    r7,4*fargs(r9)  # fail if too large
                   11434:        blequ   0f
                   11435:        jmp     exfal
                   11436: 0:             
                   11437:        moval   0[r7],r7        # else convert to byte offset
                   11438:        addl2   r7,r9           # point to field name
                   11439:        movl    4*dfflb(r9),r9  # load vrblk pointer
                   11440:        jmp     exvnm           # exit to build nmblk
                   11441: #
                   11442: #      HERE FOR BAD FIRST ARGUMENT
                   11443: #
                   11444: sfld1: jmp     er_108          # field first argument is not datatype name
                   11445:        #page   
                   11446: #
                   11447: #      FENCE
                   11448: #
                   11449: s$fnc:                         # entry point
                   11450:        movl    $p$fnc,r7       # set pcode for p$fnc
                   11451:        clrl    r9              # p0blk
                   11452:        jsb     pbild           # build p$fnc node
                   11453:        movl    r9,r10          # save pointer to it
                   11454:        movl    (sp)+,r9        # get argument
                   11455:        jsb     gtpat           # convert to pattern
                   11456:        .long   er_259          # fence argument is not pattern
                   11457:        jsb     pconc           # concatenate to p$fnc node
                   11458:        movl    r9,r10          # save ptr to concatenated pattern
                   11459:        movl    $p$fna,r7       # set for p$fna pcode
                   11460:        clrl    r9              # p0blk
                   11461:        jsb     pbild           # construct p$fna node
                   11462:        movl    r10,4*pthen(r9) # set pattern as pthen
                   11463:        movl    r9,-(sp)        # set as result
                   11464:        jmp     exits           # do next code word
                   11465:        #page   
                   11466: #
                   11467: #      GE
                   11468: #
                   11469: s$gef:                         # entry point
                   11470:        jsb     acomp           # call arithmetic comparison routine
                   11471:        .long   er_109          # ge first argument is not numeric
                   11472:        .long   er_110          # ge second argument is not numeric
                   11473:        .long   exfal           # fail if lt
                   11474:        .long   exnul           # return null if eq
                   11475:        .long   exnul           # return null if gt
                   11476:        #page   
                   11477: #
                   11478: #      GT
                   11479: #
                   11480: s$gtf:                         # entry point
                   11481:        jsb     acomp           # call arithmetic comparison routine
                   11482:        .long   er_111          # gt first argument is not numeric
                   11483:        .long   er_112          # gt second argument is not numeric
                   11484:        .long   exfal           # fail if lt
                   11485:        .long   exfal           # fail if eq
                   11486:        .long   exnul           # return null if gt
                   11487:        #page   
                   11488: #
                   11489: #      HOST
                   11490: #
                   11491: s$hst:                         # entry point
                   11492:        movl    (sp)+,r9        # get third arg
                   11493:        movl    (sp)+,r10       # get second arg
                   11494:        movl    (sp)+,r6        # get first arg
                   11495:        jsb     syshs           # enter syshs routine
                   11496:        .long   er_254          # erroneous argument for host
                   11497:        .long   er_255          # error during execution of host
                   11498:        .long   shst1           # store host string
                   11499:        .long   exnul           # return null result
                   11500:        .long   exixr           # return xr
                   11501:        .long   exfal           # fail return
                   11502: #
                   11503: #      RETURN HOST STRING
                   11504: #
                   11505: shst1: tstl    r10             # null string if syshs uncooperative
                   11506:        bnequ   0f
                   11507:        jmp     exnul
                   11508: 0:             
                   11509:        movl    4*sclen(r10),r6 # length
                   11510:        clrl    r7              # zero offset
                   11511:        jsb     sbstr           # build copy of string
                   11512:        movl    r9,-(sp)        # stack the result
                   11513:        jmp     exits           # return result on stack
                   11514:        #page   
                   11515: #
                   11516: #      IDENT
                   11517: #
                   11518: s$idn:                         # entry point
                   11519:        movl    (sp)+,r9        # load second argument
                   11520:        movl    (sp)+,r10       # load first argument
                   11521:        jsb     ident           # call ident comparison routine
                   11522:        .long   exnul           # return null if ident
                   11523:        jmp     exfal           # fail if differ
                   11524:        #page   
                   11525: #
                   11526: #      INPUT
                   11527: #
                   11528: s$inp:                         # entry point
                   11529:        clrl    r7              # input flag
                   11530:        jsb     ioput           # call input/output assoc. routine
                   11531:        .long   er_113          # input third argument is not a string
                   11532:        .long   er_114          # inappropriate second argument for input
                   11533:        .long   er_115          # inappropriate first argument for input
                   11534:        .long   er_116          # inappropriate file specification for input
                   11535:        .long   exfal           # fail if file does not exist
                   11536:        .long   er_117          # input file cannot be read
                   11537:        jmp     exnul           # return null string
                   11538:        #page   
                   11539: #
                   11540: #      INSERT
                   11541: #
                   11542: s$ins:                         # entry point
                   11543:        movl    (sp)+,r10       # get string arg
                   11544:        jsb     gtsmi           # get replace length
                   11545:        .long   er_277          # insert third argument not integer
                   11546:        .long   exfal           # fail if out of range
                   11547:        movl    r8,r7           # copy to proper reg
                   11548:        jsb     gtsmi           # get replace position
                   11549:        .long   er_278          # insert second argument not integer
                   11550:        .long   exfal           # fail if out of range
                   11551:        tstl    r8              # fail if zero
                   11552:        bnequ   0f
                   11553:        jmp     exfal
                   11554: 0:             
                   11555:        decl    r8              # decrement to get offset
                   11556:        movl    r8,r6           # put in proper register
                   11557:        movl    (sp)+,r9        # get buffer
                   11558:        cmpl    (r9),$b$bct     # press on if type ok
                   11559:        beqlu   sins1
                   11560:        jmp     er_279          # insert first argument not buffer
                   11561: #
                   11562: #      HERE WHEN EVERYTHING LOADED UP
                   11563: #
                   11564: sins1: jsb     insbf           # call to insert
                   11565:        .long   er_280          # insert fourth argument not a string
                   11566:        .long   exfal           # fail if out of range
                   11567:        jmp     exnul           # else ok - exit with null
                   11568:        #page   
                   11569: #
                   11570: #      INTEGER
                   11571: #
                   11572: s$int:                         # entry point
                   11573:        movl    (sp)+,r9        # load argument
                   11574:        jsb     gtnum           # convert to numeric
                   11575:        .long   exfal           # fail if non-numeric
                   11576:        cmpl    r6,$b$icl       # return null if integer
                   11577:        bnequ   0f
                   11578:        jmp     exnul
                   11579: 0:             
                   11580:        jmp     exfal           # fail if real
                   11581:        #page   
                   11582: #
                   11583: #      ITEM
                   11584: #
                   11585: #      ITEM DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT
                   11586: #      WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED.
                   11587: #
                   11588: s$itm:                         # entry point
                   11589: #
                   11590: #      DEAL WITH CASE OF NO ARGS
                   11591: #
                   11592:        tstl    r6              # jump if at least one arg
                   11593:        bnequ   sitm1
                   11594:        movl    $nulls,-(sp)    # else supply garbage null arg
                   11595:        movl    $num01,r6       # and fix argument count
                   11596: #
                   11597: #      CHECK FOR NAME/VALUE CASES
                   11598: #
                   11599: sitm1: movl    r3,r9           # get current code pointer
                   11600:        movl    (r9),r10        # load next code word
                   11601:        decl    r6              # get number of subscripts
                   11602:        movl    r6,r9           # copy for arref
                   11603:        cmpl    r10,$ofne$      # jump if called by name
                   11604:        beqlu   sitm2
                   11605: #
                   11606: #      HERE IF CALLED BY VALUE
                   11607: #
                   11608:        clrl    r7              # set code for call by value
                   11609:        jmp     arref           # off to array reference routine
                   11610: #
                   11611: #      HERE FOR CALL BY NAME
                   11612: #
                   11613: sitm2: movl    sp,r7           # set code for call by name
                   11614:        movl    (r3)+,r6        # load and ignore ofne$ call
                   11615:        jmp     arref           # off to array reference routine
                   11616:        #page   
                   11617: #
                   11618: #      LE
                   11619: #
                   11620: s$lef:                         # entry point
                   11621:        jsb     acomp           # call arithmetic comparison routine
                   11622:        .long   er_118          # le first argument is not numeric
                   11623:        .long   er_119          # le second argument is not numeric
                   11624:        .long   exnul           # return null if lt
                   11625:        .long   exnul           # return null if eq
                   11626:        .long   exfal           # fail if gt
                   11627:        #page   
                   11628: #
                   11629: #      LEN
                   11630: #
                   11631: s$len:                         # entry point
                   11632:        movl    $p$len,r7       # set pcode for integer arg case
                   11633:        movl    $p$lnd,r6       # set pcode for expr arg case
                   11634:        jsb     patin           # call common routine to build node
                   11635:        .long   er_120          # len argument is not integer or expression
                   11636:        .long   er_121          # len argument is negative or too large
                   11637:        jmp     exixr           # return pattern node
                   11638:        #page   
                   11639: #
                   11640: #      LEQ
                   11641: #
                   11642: s$leq:                         # entry point
                   11643:        jsb     lcomp           # call string comparison routine
                   11644:        .long   er_122          # leq first argument is not string
                   11645:        .long   er_123          # leq second argument is not string
                   11646:        .long   exfal           # fail if llt
                   11647:        .long   exnul           # return null if leq
                   11648:        .long   exfal           # fail if lgt
                   11649:        #page   
                   11650: #
                   11651: #      LGE
                   11652: #
                   11653: s$lge:                         # entry point
                   11654:        jsb     lcomp           # call string comparison routine
                   11655:        .long   er_124          # lge first argument is not string
                   11656:        .long   er_125          # lge second argument is not string
                   11657:        .long   exfal           # fail if llt
                   11658:        .long   exnul           # return null if leq
                   11659:        .long   exnul           # return null if lgt
                   11660:        #page   
                   11661: #
                   11662: #      LGT
                   11663: #
                   11664: s$lgt:                         # entry point
                   11665:        jsb     lcomp           # call string comparison routine
                   11666:        .long   er_126          # lgt first argument is not string
                   11667:        .long   er_127          # lgt second argument is not string
                   11668:        .long   exfal           # fail if llt
                   11669:        .long   exfal           # fail if leq
                   11670:        .long   exnul           # return null if lgt
                   11671:        #page   
                   11672: #
                   11673: #      LLE
                   11674: #
                   11675: s$lle:                         # entry point
                   11676:        jsb     lcomp           # call string comparison routine
                   11677:        .long   er_128          # lle first argument is not string
                   11678:        .long   er_129          # lle second argument is not string
                   11679:        .long   exnul           # return null if llt
                   11680:        .long   exnul           # return null if leq
                   11681:        .long   exfal           # fail if lgt
                   11682:        #page   
                   11683: #
                   11684: #      LLT
                   11685: #
                   11686: s$llt:                         # entry point
                   11687:        jsb     lcomp           # call string comparison routine
                   11688:        .long   er_130          # llt first argument is not string
                   11689:        .long   er_131          # llt second argument is not string
                   11690:        .long   exnul           # return null if llt
                   11691:        .long   exfal           # fail if leq
                   11692:        .long   exfal           # fail if lgt
                   11693:        #page   
                   11694: #
                   11695: #      LNE
                   11696: #
                   11697: s$lne:                         # entry point
                   11698:        jsb     lcomp           # call string comparison routine
                   11699:        .long   er_132          # lne first argument is not string
                   11700:        .long   er_133          # lne second argument is not string
                   11701:        .long   exnul           # return null if llt
                   11702:        .long   exfal           # fail if leq
                   11703:        .long   exnul           # return null if lgt
                   11704:        #page   
                   11705: #
                   11706: #      LOCAL
                   11707: #
                   11708: s$loc:                         # entry point
                   11709:        jsb     gtsmi           # get second argument (local number)
                   11710:        .long   er_134          # local second argument is not integer
                   11711:        .long   exfal           # fail if out of range
                   11712:        movl    r9,r7           # save local number
                   11713:        movl    (sp)+,r9        # load first argument
                   11714:        jsb     gtnvr           # point to vrblk
                   11715:        .long   sloc1           # jump if not variable name
                   11716:        movl    4*vrfnc(r9),r9  # else load function pointer
                   11717:        cmpl    (r9),$b$pfc     # jump if not program defined
                   11718:        bnequ   sloc1
                   11719: #
                   11720: #      HERE IF WE HAVE A PROGRAM DEFINED FUNCTION NAME
                   11721: #
                   11722:        tstl    r7              # fail if second arg is zero
                   11723:        bnequ   0f
                   11724:        jmp     exfal
                   11725: 0:             
                   11726:        cmpl    r7,4*pfnlo(r9)  # or too large
                   11727:        blequ   0f
                   11728:        jmp     exfal
                   11729: 0:             
                   11730:        addl2   4*fargs(r9),r7  # else adjust offset to include args
                   11731:        moval   0[r7],r7        # convert to bytes
                   11732:        addl2   r7,r9           # point to local pointer
                   11733:        movl    4*pfagb(r9),r9  # load vrblk pointer
                   11734:        jmp     exvnm           # exit building nmblk
                   11735: #
                   11736: #      HERE IF FIRST ARGUMENT IS NO GOOD
                   11737: #
                   11738: sloc1: jmp     er_135          # local first arg is not a program function name
                   11739:        #page   
                   11740: #
                   11741: #      LOAD
                   11742: #
                   11743: s$lod:                         # entry point
                   11744:        jsb     gtstg           # load library name
                   11745:        .long   er_136          # load second argument is not string
                   11746:        movl    r9,r10          # save library name
                   11747:        jsb     xscni           # prepare to scan first argument
                   11748:        .long   er_137          # load first argument is not string
                   11749:        .long   er_138          # load first argument is null
                   11750:        movl    r10,-(sp)       # stack library name
                   11751:        movl    $ch$pp,r8       # set delimiter one = left paren
                   11752:        movl    r8,r10          # set delimiter two = left paren
                   11753:        jsb     xscan           # scan function name
                   11754:        movl    r9,-(sp)        # save ptr to function name
                   11755:        tstl    r6              # jump if left paren found
                   11756:        bnequ   slod1
                   11757:        jmp     er_139          # load first argument is missing a left paren
                   11758: #
                   11759: #      HERE AFTER SUCCESSFULLY SCANNING FUNCTION NAME
                   11760: #
                   11761: slod1: jsb     gtnvr           # locate vrblk
                   11762:        .long   er_140          # load first argument has null function name
                   11763:        movl    r9,lodfn        # save vrblk pointer
                   11764:        clrl    lodna           # zero count of arguments
                   11765: #
                   11766: #      LOOP TO SCAN ARGUMENT DATATYPE NAMES
                   11767: #
                   11768: slod2: movl    $ch$rp,r8       # delimiter one is right paren
                   11769:        movl    $ch$cm,r10      # delimiter two is comma
                   11770:        jsb     xscan           # scan next argument name
                   11771:        incl    lodna           # bump argument count
                   11772:        tstl    r6              # jump if ok delimiter was found
                   11773:        bnequ   slod3
                   11774:        jmp     er_141          # load first argument is missing a right paren
                   11775:        #page   
                   11776: #
                   11777: #      LOAD (CONTINUED)
                   11778: #
                   11779: #      COME HERE TO ANALYZE THE DATATYPE POINTER IN (XR). THIS
                   11780: #      CODE IS USED BOTH FOR ARGUMENTS (WA=1,2) AND FOR THE
                   11781: #      RESULT DATATYPE (WITH WA SET TO ZERO).
                   11782: #
                   11783: slod3: movl    r9,-(sp)        # stack datatype name pointer
                   11784:        movl    $num01,r7       # set string code in case
                   11785:        movl    $scstr,r10      # point to /string/
                   11786:        jsb     ident           # check for match
                   11787:        .long   slod4           # jump if match
                   11788:        movl    (sp),r9         # else reload name
                   11789:        addl2   r7,r7           # set code for integer (2)
                   11790:        movl    $scint,r10      # point to /integer/
                   11791:        jsb     ident           # check for match
                   11792:        .long   slod4           # jump if match
                   11793:        movl    (sp),r9         # else reload string pointer
                   11794:        incl    r7              # set code for real (3)
                   11795:        movl    $screa,r10      # point to /real/
                   11796:        jsb     ident           # check for match
                   11797:        .long   slod4           # jump if match
                   11798:        clrl    r7              # else get code for no convert
                   11799: #
                   11800: #      MERGE HERE WITH PROPER DATATYPE CODE IN WB
                   11801: #
                   11802: slod4: movl    r7,(sp)         # store code on stack
                   11803:        cmpl    r6,$num02       # loop back if arg stopped by comma
                   11804:        beqlu   slod2
                   11805:        tstl    r6              # jump if that was the result type
                   11806:        beqlu   slod5
                   11807: #
                   11808: #      HERE WE SCAN OUT THE RESULT TYPE (ARG STOPPED BY ) )
                   11809: #
                   11810:        movl    mxlen,r8        # set dummy (impossible) delimiter 1
                   11811:        movl    r8,r10          # and delimiter two
                   11812:        jsb     xscan           # scan result name
                   11813:        clrl    r6              # set code for processing result
                   11814:        jmp     slod3           # jump back to process result name
                   11815:        #page   
                   11816: #
                   11817: #      LOAD (CONTINUED)
                   11818: #
                   11819: #      HERE AFTER PROCESSING ALL ARGS AND RESULT
                   11820: #
                   11821: slod5: movl    lodna,r6        # get number of arguments
                   11822:        movl    r6,r8           # copy for later
                   11823:        moval   0[r6],r6        # convert length to bytes
                   11824:        addl2   $4*efsi$,r6     # add space for standard fields
                   11825:        jsb     alloc           # allocate efblk
                   11826:        movl    $b$efc,(r9)     # set type word
                   11827:        movl    r8,4*fargs(r9)  # set number of arguments
                   11828:        clrl    4*efuse(r9)     # set use count (dffnc will set to 1)
                   11829:        clrl    4*efcod(r9)     # zero code pointer for now
                   11830:        movl    (sp)+,4*efrsl(r9)# store result type code
                   11831:        movl    lodfn,4*efvar(r9)# store function vrblk pointer
                   11832:        movl    r6,4*eflen(r9)  # store efblk length
                   11833:        movl    r9,r7           # save efblk pointer
                   11834:        addl2   r6,r9           # point past end of efblk
                   11835:                                # set number of arguments for loop
                   11836: #
                   11837: #      LOOP TO SET ARGUMENT TYPE CODES FROM STACK
                   11838: #
                   11839: slod6: movl    (sp)+,-(r9)     # store one type code from stack
                   11840:        sobgtr  r8,slod6        # loop till all stored
                   11841: #
                   11842: #      NOW LOAD THE EXTERNAL FUNCTION AND PERFORM DEFINITION
                   11843: #
                   11844:        movl    (sp)+,r9        # load function string name
                   11845:        movl    (sp),r10        # load library name
                   11846:        movl    r7,(sp)         # store efblk pointer
                   11847:        jsb     sysld           # call function to load external func
                   11848:        .long   er_142          # load function does not exist
                   11849:        .long   er_143          # load function caused input error during load
                   11850:        movl    (sp)+,r10       # recall efblk pointer
                   11851:        movl    r9,4*efcod(r10) # store code pointer
                   11852:        movl    lodfn,r9        # point to vrblk for function
                   11853:        jsb     dffnc           # perform function definition
                   11854:        jmp     exnul           # return null result
                   11855:        #page   
                   11856: #
                   11857: #      LPAD
                   11858: #
                   11859: s$lpd:                         # entry point
                   11860:        jsb     gtstg           # get pad character
                   11861:        .long   er_144          # lpad third argument not a string
                   11862:        movab   cfp$f(r9),r9    # point to character (null is blank)
                   11863:        movzbl  (r9),r7         # load pad character
                   11864:        jsb     gtsmi           # get pad length
                   11865:        .long   er_145          # lpad second argument is not integer
                   11866:        .long   slpd3           # skip if negative or large
                   11867: #
                   11868: #      MERGE TO CHECK FIRST ARG
                   11869: #
                   11870: slpd1: jsb     gtstg           # get first argument (string to pad)
                   11871:        .long   er_146          # lpad first argument is not string
                   11872:        cmpl    r6,r8           # return 1st arg if too long to pad
                   11873:        blssu   0f
                   11874:        jmp     exixr
                   11875: 0:             
                   11876:        movl    r9,r10          # else move ptr to string to pad
                   11877: #
                   11878: #      NOW WE ARE READY FOR THE PAD
                   11879: #
                   11880: #      (XL)                  POINTER TO STRING TO PAD
                   11881: #      (WB)                  PAD CHARACTER
                   11882: #      (WC)                  LENGTH TO PAD STRING TO
                   11883: #
                   11884:        movl    r8,r6           # copy length
                   11885:        jsb     alocs           # allocate scblk for new string
                   11886:        movl    r9,-(sp)        # save as result
                   11887:        movl    4*sclen(r10),r6 # load length of argument
                   11888:        subl2   r6,r8           # calculate number of pad characters
                   11889:        movab   cfp$f(r9),r9    # point to chars in result string
                   11890:                                # set counter for pad loop
                   11891: #
                   11892: #      LOOP TO PERFORM PAD
                   11893: #
                   11894: slpd2: movb    r7,(r9)+        # store pad character, bump ptr
                   11895:        sobgtr  r8,slpd2        # loop till all pad chars stored
                   11896:        #csc    r9              # complete store characters
                   11897: #
                   11898: #      NOW COPY STRING
                   11899: #
                   11900:        tstl    r6              # exit if null string
                   11901:        bnequ   0f
                   11902:        jmp     exits
                   11903: 0:             
                   11904:        movab   cfp$f(r10),r10  # else point to chars in argument
                   11905:        jsb     sbmvc           # move characters to result string
                   11906:        jmp     exits           # jump for next code word
                   11907: #
                   11908: #      HERE IF 2ND ARG IS NEGATIVE OR LARGE
                   11909: #
                   11910: slpd3: clrl    r8              # zero pad count
                   11911:        jmp     slpd1           # merge
                   11912:        #page   
                   11913: #
                   11914: #      LT
                   11915: #
                   11916: s$ltf:                         # entry point
                   11917:        jsb     acomp           # call arithmetic comparison routine
                   11918:        .long   er_147          # lt first argument is not numeric
                   11919:        .long   er_148          # lt second argument is not numeric
                   11920:        .long   exnul           # return null if lt
                   11921:        .long   exfal           # fail if eq
                   11922:        .long   exfal           # fail if gt
                   11923:        #page   
                   11924: #
                   11925: #      NE
                   11926: #
                   11927: s$nef:                         # entry point
                   11928:        jsb     acomp           # call arithmetic comparison routine
                   11929:        .long   er_149          # ne first argument is not numeric
                   11930:        .long   er_150          # ne second argument is not numeric
                   11931:        .long   exnul           # return null if lt
                   11932:        .long   exfal           # fail if eq
                   11933:        .long   exnul           # return null if gt
                   11934:        #page   
                   11935: #
                   11936: #      NOTANY
                   11937: #
                   11938: s$nay:                         # entry point
                   11939:        movl    $p$nas,r7       # set pcode for single char arg
                   11940:        movl    $p$nay,r10      # pcode for multi-char arg
                   11941:        movl    $p$nad,r8       # set pcode for expr arg
                   11942:        jsb     patst           # call common routine to build node
                   11943:        .long   er_151          # notany argument is not string or expression
                   11944:        jmp     exixr           # jump for next code word
                   11945:        #page   
                   11946: #
                   11947: #      OPSYN
                   11948: #
                   11949: s$ops:                         # entry point
                   11950:        jsb     gtsmi           # load third argument
                   11951:        .long   er_152          # opsyn third argument is not integer
                   11952:        .long   er_153          # opsyn third argument is negative or too large
                   11953:        movl    r8,r7           # if ok, save third argumnet
                   11954:        movl    (sp)+,r9        # load second argument
                   11955:        jsb     gtnvr           # locate variable block
                   11956:        .long   er_154          # opsyn second arg is not natural variable name
                   11957:        movl    4*vrfnc(r9),r10 # if ok, load function block pointer
                   11958:        tstl    r7              # jump if operator opsyn case
                   11959:        bnequ   sops2
                   11960: #
                   11961: #      HERE FOR FUNCTION OPSYN (THIRD ARG ZERO)
                   11962: #
                   11963:        movl    (sp)+,r9        # load first argument
                   11964:        jsb     gtnvr           # get vrblk pointer
                   11965:        .long   er_155          # opsyn first arg is not natural variable name
                   11966: #
                   11967: #      MERGE HERE TO PERFORM FUNCTION DEFINITION
                   11968: #
                   11969: sops1: jsb     dffnc           # call function definer
                   11970:        jmp     exnul           # exit with null result
                   11971: #
                   11972: #      HERE FOR OPERATOR OPSYN (THIRD ARG NON-ZERO)
                   11973: #
                   11974: sops2: jsb     gtstg           # get operator name
                   11975:        .long   sops5           # jump if not string
                   11976:        cmpl    r6,$num01       # error if not one char long
                   11977:        bnequ   sops5
                   11978:        movab   cfp$f(r9),r9    # else point to character
                   11979:        movzbl  (r9),r8         # load character name
                   11980:        #page   
                   11981: #
                   11982: #      OPSYN (CONTINUED)
                   11983: #
                   11984: #      NOW SET TO SEARCH FOR MATCHING UNARY OR BINARY OPERATOR
                   11985: #      NAME AS APPROPRIATE. NOTE THAT THERE ARE =OPBUN UNDEFINED
                   11986: #      BINARY OPERATORS AND =OPUUN UNDEFINED UNARY OPERATORS.
                   11987: #
                   11988:        movl    $r$uub,r6       # point to unop pointers in case
                   11989:        movl    $opnsu,r9       # point to names of unary operators
                   11990:        addl2   $opbun,r7       # add no. of undefined binary ops
                   11991:        cmpl    r7,$opuun       # jump if unop (third arg was 1)
                   11992:        beqlu   sops3
                   11993:        movl    $r$uba,r6       # else point to binary operator ptrs
                   11994:        movl    $opsnb,r9       # point to names of binary operators
                   11995:        movl    $opbun,r7       # set number of undefined binops
                   11996: #
                   11997: #      MERGE HERE TO CHECK LIST (WB = NUMBER TO CHECK)
                   11998: #
                   11999: sops3:                         # set counter to control loop
                   12000: #
                   12001: #      LOOP TO SEARCH FOR NAME MATCH
                   12002: #
                   12003: sops4: cmpl    r8,(r9)         # jump if names match
                   12004:        beqlu   sops6
                   12005:        addl2   $4,r6           # else push pointer to function ptr
                   12006:        addl2   $4,r9           # bump pointer
                   12007:        sobgtr  r7,sops4        # loop back till all checked
                   12008: #
                   12009: #      HERE IF BAD OPERATOR NAME
                   12010: #
                   12011: sops5: jmp     er_156          # opsyn first arg is not correct operator name
                   12012: #
                   12013: #      COME HERE ON FINDING A MATCH IN THE OPERATOR NAME TABLE
                   12014: #
                   12015: sops6: movl    r6,r9           # copy pointer to function block ptr
                   12016:        subl2   $4*vrfnc,r9     # make it look like dummy vrblk
                   12017:        jmp     sops1           # merge back to define operator
                   12018:        #page   
                   12019: #
                   12020: #      OUTPUT
                   12021: #
                   12022: s$oup:                         # entry point
                   12023:        movl    $num03,r7       # output flag
                   12024:        jsb     ioput           # call input/output assoc. routine
                   12025:        .long   er_157          # output third argument is not a string
                   12026:        .long   er_158          # inappropriate second argument for output
                   12027:        .long   er_159          # inappropriate first argument for output
                   12028:        .long   er_160          # inappropriate file specification for output
                   12029:        .long   exfal           # fail if file does not exist
                   12030:        .long   er_161          # output file cannot be written to
                   12031:        jmp     exnul           # return null string
                   12032:        #page   
                   12033: #
                   12034: #      POS
                   12035: #
                   12036: s$pos:                         # entry point
                   12037:        movl    $p$pos,r7       # set pcode for integer arg case
                   12038:        movl    $p$psd,r6       # set pcode for expression arg case
                   12039:        jsb     patin           # call common routine to build node
                   12040:        .long   er_162          # pos argument is not integer or expression
                   12041:        .long   er_163          # pos argument is negative or too large
                   12042:        jmp     exixr           # return pattern node
                   12043:        #page   
                   12044: #
                   12045: #      PROTOTYPE
                   12046: #
                   12047: s$pro:                         # entry point
                   12048:        movl    (sp)+,r9        # load argument
                   12049:        movl    4*tblen(r9),r7  # length if table, vector (=vclen)
                   12050:        ashl    $-2,r7,r7       # convert to words
                   12051:        movl    (r9),r6         # load type word of argument block
                   12052:        cmpl    r6,$b$art       # jump if array
                   12053:        beqlu   spro4
                   12054:        cmpl    r6,$b$tbt       # jump if table
                   12055:        beqlu   spro1
                   12056:        cmpl    r6,$b$vct       # jump if vector
                   12057:        beqlu   spro3
                   12058:        cmpl    r6,$b$bct       # jump if buffer
                   12059:        beqlu   spr05
                   12060:        jmp     er_164          # prototype argument is not valid object
                   12061: #
                   12062: #      HERE FOR TABLE
                   12063: #
                   12064: spro1: subl2   $tbsi$,r7       # subtract standard fields
                   12065: #
                   12066: #      MERGE FOR VECTOR
                   12067: #
                   12068: spro2: movl    r7,r5           # convert to integer
                   12069:        jmp     exint           # exit with integer result
                   12070: #
                   12071: #      HERE FOR VECTOR
                   12072: #
                   12073: spro3: subl2   $vcsi$,r7       # subtract standard fields
                   12074:        jmp     spro2           # merge
                   12075: #
                   12076: #      HERE FOR ARRAY
                   12077: #
                   12078: spro4: addl2   4*arofs(r9),r9  # point to prototype field
                   12079:        movl    (r9),r9         # load prototype
                   12080:        jmp     exixr           # return prototype as result
                   12081: #
                   12082: #      HERE FOR BUFFER
                   12083: #
                   12084: spr05: movl    4*bcbuf(r9),r9  # point to bfblk
                   12085:        movl    4*bfalc(r9),r5  # load allocated length
                   12086:        jmp     exint           # exit with integer allocation
                   12087:        #page   
                   12088: #
                   12089: #      REMDR
                   12090: #
                   12091: s$rmd:                         # entry point
                   12092:        clrl    r7              # set positive flag
                   12093:        movl    (sp),r9         # load second argument
                   12094:        jsb     gtint           # convert to integer
                   12095:        .long   er_165          # remdr second argument is not integer
                   12096:        jsb     arith           # convert args
                   12097:        .long   srm01           # first arg not integer
                   12098:        .long   invalid$        # second arg checked above
                   12099:        .long   srm01           # first arg real
                   12100:        movl    4*icval(r9),r5  # load left argument value
                   12101:        ashq    $-32,r4,r4      # get remainder
                   12102:        ediv    4*icval(r10),r4,r11,r5
                   12103:        bvs     0f
                   12104:        jmp     exint
                   12105: 0:             
                   12106:        jmp     er_167          # remdr caused integer overflow
                   12107: #
                   12108: #      FAIL FIRST ARGUMENT
                   12109: #
                   12110: srm01: jmp     er_166          # remdr first argument is not integer
                   12111:        #page   
                   12112: #
                   12113: #      REPLACE
                   12114: #
                   12115: #      THE ACTUAL REPLACE OPERATION USES AN SCBLK WHOSE CFP$A
                   12116: #      CHARS CONTAIN THE TRANSLATED VERSIONS OF ALL THE CHARS.
                   12117: #      THE TABLE POINTER IS REMEMBERED FROM CALL TO CALL AND
                   12118: #      THE TABLE IS ONLY BUILT WHEN THE ARGUMENTS CHANGE.
                   12119: #
                   12120: s$rpl:                         # entry point
                   12121:        jsb     gtstg           # load third argument as string
                   12122:        .long   er_168          # replace third argument is not string
                   12123:        movl    r9,r10          # save third arg ptr
                   12124:        jsb     gtstg           # get second argument
                   12125:        .long   er_169          # replace second argument is not string
                   12126: #
                   12127: #      CHECK TO SEE IF THIS IS THE SAME TABLE AS LAST TIME
                   12128: #
                   12129:        cmpl    r9,r$ra2        # jump if 2nd argument different
                   12130:        bnequ   srpl1
                   12131:        cmpl    r10,r$ra3       # jump if args same as last time
                   12132:        bnequ   0f
                   12133:        jmp     srpl4
                   12134: 0:             
                   12135: #
                   12136: #      HERE WE BUILD A NEW REPLACE TABLE (NOTE WA = 2ND ARG LEN)
                   12137: #
                   12138: srpl1: movl    4*sclen(r10),r7 # load 3rd argument length
                   12139:        cmpl    r6,r7           # jump if arguments not same length
                   12140:        beqlu   0f
                   12141:        jmp     srpl5
                   12142: 0:             
                   12143:        tstl    r7              # jump if null 2nd argument
                   12144:        bnequ   0f
                   12145:        jmp     srpl5
                   12146: 0:             
                   12147:        movl    r10,r$ra3       # save third arg for next time in
                   12148:        movl    r9,r$ra2        # save second arg for next time in
                   12149:        movl    kvalp,r10       # point to alphabet string
                   12150:        movl    4*sclen(r10),r6 # load alphabet scblk length
                   12151:        movl    r$rpt,r9        # point to current table (if any)
                   12152:        tstl    r9              # jump if we already have a table
                   12153:        bnequ   srpl2
                   12154: #
                   12155: #      HERE WE ALLOCATE A NEW TABLE
                   12156: #
                   12157:        jsb     alocs           # allocate new table
                   12158:        movl    r8,r6           # keep scblk length
                   12159:        movl    r9,r$rpt        # save table pointer for next time
                   12160: #
                   12161: #      MERGE HERE WITH POINTER TO NEW TABLE BLOCK IN (XR)
                   12162: #
                   12163: srpl2: movab   3+(4*scsi$)(r6),r6 # compute length of scblk
                   12164:        bicl2   $3,r6
                   12165:        jsb     sbmvw           # copy to get initial table values
                   12166:        #page   
                   12167: #
                   12168: #      REPLACE (CONTINUED)
                   12169: #
                   12170: #      NOW WE MUST PLUG SELECTED ENTRIES AS REQUIRED. NOTE THAT
                   12171: #      WE ARE SHORT OF INDEX REGISTERS FOR THE FOLLOWING LOOP.
                   12172: #      HENCE THE NEED TO REPEATEDLY RE-INITIALISE CHAR PTR XL
                   12173: #
                   12174:        movl    r$ra2,r10       # point to second argument
                   12175:                                # number of chars to plug
                   12176:        clrl    r8              # zero char offset
                   12177:        movl    r$ra3,r9        # point to 3rd arg
                   12178:        movab   cfp$f(r9),r9    # get char ptr for 3rd arg
                   12179: #
                   12180: #      LOOP TO PLUG CHARS
                   12181: #
                   12182: srpl3: movl    r$ra2,r10       # point to 2nd arg
                   12183:        movab   cfp$f(r10)[r8],r10 # point to next char
                   12184:        incl    r8              # increment offset
                   12185:        movzbl  (r10),r6        # get next char
                   12186:        movl    r$rpt,r10       # point to translate table
                   12187:        movab   cfp$f(r10)[r6],r10 # convert char to offset into table
                   12188:        movzbl  (r9)+,r6        # get translated char
                   12189:        movb    r6,(r10)        # store in table
                   12190:        #csc    r10             # complete store characters
                   12191:        sobgtr  r7,srpl3        # loop till done
                   12192:        #page   
                   12193: #
                   12194: #      REPLACE (CONTINUED)
                   12195: #
                   12196: #      HERE TO PERFORM TRANSLATE
                   12197: #
                   12198: srpl4: jsb     gtstg           # get first argument
                   12199:        .long   er_170          # replace first argument is not string
                   12200:        tstl    r6              # return null if null argument
                   12201:        bnequ   0f
                   12202:        jmp     exnul
                   12203: 0:             
                   12204:        movl    r9,r10          # copy pointer
                   12205:        movl    r6,r8           # save length
                   12206:        movab   3+(4*schar)(r6),r6 # get scblk length
                   12207:        bicl2   $3,r6
                   12208:        jsb     alloc           # allocate space for copy
                   12209:        movl    r9,r7           # save address of copy
                   12210:        jsb     sbmvw           # move scblk contents to copy
                   12211:        movl    r$rpt,r9        # point to replace table
                   12212:        movab   cfp$f(r9),r9    # point to chars of table
                   12213:        movl    r7,r10          # point to string to translate
                   12214:        movab   cfp$f(r10),r10  # point to chars of string
                   12215:        movl    r8,r6           # set number of chars to translate
                   12216:        jsb     sbtrc           # perform translation
                   12217:        movl    r7,-(sp)        # stack new string as result
                   12218:        jmp     exits           # return with result on stack
                   12219: #
                   12220: #      ERROR POINT
                   12221: #
                   12222: srpl5: jmp     er_171          # null or unequally long 2nd, 3rd args to replace
                   12223:        #page   
                   12224: #
                   12225: #      REWIND
                   12226: #
                   12227: s$rew:                         # entry point
                   12228:        jsb     iofcb           # call fcblk routine
                   12229:        .long   er_172          # rewind argument is not a suitable name
                   12230:        .long   er_173          # rewind argument is null
                   12231:        jsb     sysrw           # call system rewind function
                   12232:        .long   er_174          # rewind file does not exist
                   12233:        .long   er_175          # rewind file does not permit rewind
                   12234:        .long   er_176          # rewind caused non-recoverable error
                   12235:        jmp     exnul           # exit with null result if no error
                   12236:        #page   
                   12237: #
                   12238: #      REVERSE
                   12239: #
                   12240: s$rvs:                         # entry point
                   12241:        jsb     gtstg           # load string argument
                   12242:        .long   er_177          # reverse argument is not string
                   12243:        tstl    r6              # return argument if null
                   12244:        bnequ   0f
                   12245:        jmp     exixr
                   12246: 0:             
                   12247:        movl    r9,r10          # else save pointer to string arg
                   12248:        jsb     alocs           # allocate space for new scblk
                   12249:        movl    r9,-(sp)        # store scblk ptr on stack as result
                   12250:        movab   cfp$f(r9),r9    # prepare to store in new scblk
                   12251:        movab   cfp$f(r10)[r8],r10 # point past last char in argument
                   12252:                                # set loop counter
                   12253: #
                   12254: #      LOOP TO MOVE CHARS IN REVERSE ORDER
                   12255: #
                   12256: srvs1: movzbl  -(r10),r7       # load next char from argument
                   12257:        movb    r7,(r9)+        # store in result
                   12258:        sobgtr  r8,srvs1        # loop till all moved
                   12259:        #csc    r9              # complete store characters
                   12260:        jmp     exits           # and then jump for next code word
                   12261:        #page   
                   12262: #
                   12263: #      RPAD
                   12264: #
                   12265: s$rpd:                         # entry point
                   12266:        jsb     gtstg           # get pad character
                   12267:        .long   er_178          # rpad third argument is not string
                   12268:        movab   cfp$f(r9),r9    # point to character (null is blank)
                   12269:        movzbl  (r9),r7         # load pad character
                   12270:        jsb     gtsmi           # get pad length
                   12271:        .long   er_179          # rpad second argument is not integer
                   12272:        .long   srpd3           # skip if negative or large
                   12273: #
                   12274: #      MERGE TO CHECK FIRST ARG.
                   12275: #
                   12276: srpd1: jsb     gtstg           # get first argument (string to pad)
                   12277:        .long   er_180          # rpad first argument is not string
                   12278:        cmpl    r6,r8           # return 1st arg if too long to pad
                   12279:        blssu   0f
                   12280:        jmp     exixr
                   12281: 0:             
                   12282:        movl    r9,r10          # else move ptr to string to pad
                   12283: #
                   12284: #      NOW WE ARE READY FOR THE PAD
                   12285: #
                   12286: #      (XL)                  POINTER TO STRING TO PAD
                   12287: #      (WB)                  PAD CHARACTER
                   12288: #      (WC)                  LENGTH TO PAD STRING TO
                   12289: #
                   12290:        movl    r8,r6           # copy length
                   12291:        jsb     alocs           # allocate scblk for new string
                   12292:        movl    r9,-(sp)        # save as result
                   12293:        movl    4*sclen(r10),r6 # load length of argument
                   12294:        subl2   r6,r8           # calculate number of pad characters
                   12295:        movab   cfp$f(r9),r9    # point to chars in result string
                   12296:                                # set counter for pad loop
                   12297: #
                   12298: #      COPY ARGUMENT STRING
                   12299: #
                   12300:        tstl    r6              # jump if argument is null
                   12301:        beqlu   srpd2
                   12302:        movab   cfp$f(r10),r10  # else point to argument chars
                   12303:        jsb     sbmvc           # move characters to result string
                   12304: #
                   12305: #      LOOP TO SUPPLY PAD CHARACTERS
                   12306: #
                   12307: srpd2: movb    r7,(r9)+        # store pad character, bump ptr
                   12308:        sobgtr  r8,srpd2        # loop till all pad chars stored
                   12309:        #csc    r9              # complete character storing
                   12310:        jmp     exits           # and exit for next word
                   12311: #
                   12312: #      HERE IF 2ND ARG IS NEGATIVE OR LARGE
                   12313: #
                   12314: srpd3: clrl    r8              # zero pad count
                   12315:        jmp     srpd1           # merge
                   12316:        #page   
                   12317: #
                   12318: #      RTAB
                   12319: #
                   12320: s$rtb:                         # entry point
                   12321:        movl    $p$rtb,r7       # set pcode for integer arg case
                   12322:        movl    $p$rtd,r6       # set pcode for expression arg case
                   12323:        jsb     patin           # call common routine to build node
                   12324:        .long   er_181          # rtab argument is not integer or expression
                   12325:        .long   er_182          # rtab argument is negative or too large
                   12326:        jmp     exixr           # return pattern node
                   12327:        #page   
                   12328: #
                   12329: #      SET
                   12330: #
                   12331: s$set:                         # entry point
                   12332:        movl    (sp)+,r$io2     # save third arg
                   12333:        movl    (sp)+,r$io1     # save second arg
                   12334:        jsb     iofcb           # call fcblk routine
                   12335:        .long   er_291          # set first argument is not a suitable name
                   12336:        .long   er_292          # set first argument is null
                   12337:        movl    r$io1,r7        # load second arg
                   12338:        movl    r$io2,r8        # load third arg
                   12339:        jsb     sysst           # call system set routine
                   12340:        .long   er_293          # inappropriate second argument to set
                   12341:        .long   er_294          # inappropriate third argument to set
                   12342:        .long   er_295          # set file does not exist
                   12343:        .long   er_296          # set file does not permit setting file pointer
                   12344:        .long   er_297          # set caused non-recoverable i/o error
                   12345:        jmp     exnul           # otherwisew return null
                   12346:        #page   
                   12347: #
                   12348: #      TAB
                   12349: #
                   12350: s$tab:                         # entry point
                   12351:        movl    $p$tab,r7       # set pcode for integer arg case
                   12352:        movl    $p$tbd,r6       # set pcode for expression arg case
                   12353:        jsb     patin           # call common routine to build node
                   12354:        .long   er_183          # tab argument is not integer or expression
                   12355:        .long   er_184          # tab argument is negative or too large
                   12356:        jmp     exixr           # return pattern node
                   12357:        #page   
                   12358: #
                   12359: #      RPOS
                   12360: #
                   12361: s$rps:                         # entry point
                   12362:        movl    $p$rps,r7       # set pcode for integer arg case
                   12363:        movl    $p$rpd,r6       # set pcode for expression arg case
                   12364:        jsb     patin           # call common routine to build node
                   12365:        .long   er_185          # rpos argument is not integer or expression
                   12366:        .long   er_186          # rpos argument is negative or too large
                   12367:        jmp     exixr           # return pattern node
                   12368:        #page   
                   12369: #
                   12370: #      RSORT
                   12371: #
                   12372: s$rsr:                         # entry point
                   12373:        movl    sp,r6           # mark as rsort
                   12374:        jsb     sorta           # call sort routine
                   12375:        jmp     exsid           # return, setting idval
                   12376:        #page   
                   12377: #
                   12378: #      SETEXIT
                   12379: #
                   12380: s$stx:                         # entry point
                   12381:        movl    (sp)+,r9        # load argument
                   12382:        movl    stxvr,r6        # load old vrblk pointer
                   12383:        clrl    r10             # load zero in case null arg
                   12384:        cmpl    r9,$nulls       # jump if null argument (reset call)
                   12385:        beqlu   sstx1
                   12386:        jsb     gtnvr           # else get specified vrblk
                   12387:        .long   sstx2           # jump if not natural variable
                   12388:        movl    4*vrlbl(r9),r10 # else load label
                   12389:        cmpl    r10,$stndl      # jump if label is not defined
                   12390:        beqlu   sstx2
                   12391:        cmpl    (r10),$b$trt    # jump if not trapped
                   12392:        bnequ   sstx1
                   12393:        movl    4*trlbl(r10),r10# else load ptr to real label code
                   12394: #
                   12395: #      HERE TO SET/RESET SETEXIT TRAP
                   12396: #
                   12397: sstx1: movl    r9,stxvr        # store new vrblk pointer (or null)
                   12398:        movl    r10,r$sxc       # store new code ptr (or zero)
                   12399:        cmpl    r6,$nulls       # return null if null result
                   12400:        bnequ   0f
                   12401:        jmp     exnul
                   12402: 0:             
                   12403:        movl    r6,r9           # else copy vrblk pointer
                   12404:        jmp     exvnm           # and return building nmblk
                   12405: #
                   12406: #      HERE IF BAD ARGUMENT
                   12407: #
                   12408: sstx2: jmp     er_187          # setexit argument is not label name or null
                   12409:        #page   
                   12410: #
                   12411: #      SORT
                   12412: #
                   12413: s$srt:                         # entry point
                   12414:        clrl    r6              # mark as sort
                   12415:        jsb     sorta           # call sort routine
                   12416:        jmp     exsid           # return, setting idval
                   12417:        #page   
                   12418: #
                   12419: #      SPAN
                   12420: #
                   12421: s$spn:                         # entry point
                   12422:        movl    $p$sps,r7       # set pcode for single char arg
                   12423:        movl    $p$spn,r10      # set pcode for multi-char arg
                   12424:        movl    $p$spd,r8       # set pcode for expression arg
                   12425:        jsb     patst           # call common routine to build node
                   12426:        .long   er_188          # span argument is not string or expression
                   12427:        jmp     exixr           # jump for next code word
                   12428:        #page   
                   12429: #
                   12430: #      SIZE
                   12431: #
                   12432: s$si$:                         # entry point
                   12433:        movl    (sp),r9         # load argument
                   12434:        cmpl    (r9),$b$bct     # branch if not buffer
                   12435:        bnequ   ssi$1
                   12436:        addl2   $4,sp           # else pop argument
                   12437:        movl    4*bclen(r9),r5  # load defined length
                   12438:        jmp     exint           # exit with integer
                   12439: #
                   12440: #      HERE IF NOT BUFFER
                   12441: #
                   12442: ssi$1: jsb     gtstg           # load string argument
                   12443:        .long   er_189          # size argument is not string
                   12444:        movl    r6,r5           # load length as integer
                   12445:        jmp     exint           # exit with integer result
                   12446:        #page   
                   12447: #
                   12448: #      STOPTR
                   12449: #
                   12450: s$stt:                         # entry point
                   12451:        clrl    r10             # indicate stoptr case
                   12452:        jsb     trace           # call trace procedure
                   12453:        .long   er_190          # stoptr first argument is not appropriate name
                   12454:        .long   er_191          # stoptr second argument is not trace type
                   12455:        jmp     exnul           # return null
                   12456:        #page   
                   12457: #
                   12458: #      SUBSTR
                   12459: #
                   12460: s$sub:                         # entry point
                   12461:        jsb     gtsmi           # load third argument
                   12462:        .long   er_192          # substr third argument is not integer
                   12463:        .long   exfal           # jump if negative or too large
                   12464:        movl    r9,sbssv        # save third argument
                   12465:        jsb     gtsmi           # load second argument
                   12466:        .long   er_193          # substr second argument is not integer
                   12467:        .long   exfal           # jump if out of range
                   12468:        movl    r9,r7           # save second argument
                   12469:        tstl    r7              # jump if second argument zero
                   12470:        bnequ   0f
                   12471:        jmp     exfal
                   12472: 0:             
                   12473:        decl    r7              # else decrement for ones origin
                   12474:        movl    (sp),r10        # get first arg ptr
                   12475:        cmpl    (r10),$b$bct    # branch if not buffer
                   12476:        bnequ   ssuba
                   12477:        movl    4*bcbuf(r10),r9 # get bfblk ptr
                   12478:        movl    4*bclen(r10),r6 # get length
                   12479:        jmp     ssubb           # merge
                   12480: #
                   12481: #      HERE IF NOT BUFFER TO GET STRING
                   12482: #
                   12483: ssuba: jsb     gtstg           # load first argument
                   12484:        .long   er_194          # substr first argument is not string
                   12485: #
                   12486: #      MERGE WITH BFBLK OR SCBLK PTR IN XR.  WA HAS LENGTH
                   12487: #
                   12488: ssubb: movl    sbssv,r8        # reload third argument
                   12489:        tstl    r8              # skip if third arg given
                   12490:        bnequ   ssub1
                   12491:        movl    r6,r8           # else get string length
                   12492:        cmpl    r7,r8           # fail if improper
                   12493:        blequ   0f
                   12494:        jmp     exfal
                   12495: 0:             
                   12496:        subl2   r7,r8           # reduce by offset to start
                   12497: #
                   12498: #      MERGE
                   12499: #
                   12500: ssub1: movl    r6,r10          # save string length
                   12501:        movl    r8,r6           # set length of substring
                   12502:        addl2   r7,r8           # add 2nd arg to 3rd arg
                   12503:        cmpl    r8,r10          # jump if improper substring
                   12504:        blequ   0f
                   12505:        jmp     exfal
                   12506: 0:             
                   12507:        movl    r9,r10          # copy pointer to first arg
                   12508:        jsb     sbstr           # build substring
                   12509:        jmp     exixr           # and jump for next code word
                   12510:        #page   
                   12511: #
                   12512: #      TABLE
                   12513: #
                   12514: s$tbl:                         # entry point
                   12515:        movl    (sp)+,r10       # get initial lookup value
                   12516:        addl2   $4,sp           # pop second argument
                   12517:        jsb     gtsmi           # load argument
                   12518:        .long   er_195          # table argument is not integer
                   12519:        .long   er_196          # table argument is out of range
                   12520:        tstl    r8              # jump if non-zero
                   12521:        bnequ   stbl1
                   12522:        movl    $tbnbk,r8       # else supply default value
                   12523: #
                   12524: #      MERGE HERE WITH NUMBER OF HEADERS IN WA
                   12525: #
                   12526: stbl1: movl    r8,r6           # copy number of headers
                   12527:        addl2   $tbsi$,r6       # adjust for standard fields
                   12528:        moval   0[r6],r6        # convert length to bytes
                   12529:        jsb     alloc           # allocate space for tbblk
                   12530:        movl    r9,r7           # copy pointer to tbblk
                   12531:        movl    $b$tbt,(r9)+    # store type word
                   12532:        clrl    (r9)+           # zero id for the moment
                   12533:        movl    r6,(r9)+        # store length (tblen)
                   12534:        movl    r10,(r9)+       # store initial lookup value
                   12535:                                # set loop counter (num headers)
                   12536: #
                   12537: #      LOOP TO INITIALIZE ALL BUCKET POINTERS
                   12538: #
                   12539: stbl2: movl    r7,(r9)+        # store tbblk ptr in bucket header
                   12540:        sobgtr  r8,stbl2        # loop till all stored
                   12541:        movl    r7,r9           # recall pointer to tbblk
                   12542:        jmp     exsid           # exit setting idval
                   12543:        #page   
                   12544: #
                   12545: #      TIME
                   12546: #
                   12547: s$tim:                         # entry point
                   12548:        jsb     systm           # get timer value
                   12549:        subl2   timsx,r5        # subtract starting time
                   12550:        jmp     exint           # exit with integer value
                   12551:        #page   
                   12552: #
                   12553: #      TRACE
                   12554: #
                   12555: s$tra:                         # entry point
                   12556:        cmpl    4*3(sp),$nulls  # jump if first argument is null
                   12557:        beqlu   str03
                   12558:        movl    (sp)+,r9        # load fourth argument
                   12559:        clrl    r10             # tentatively set zero pointer
                   12560:        cmpl    r9,$nulls       # jump if 4th argument is null
                   12561:        beqlu   str02
                   12562:        jsb     gtnvr           # else point to vrblk
                   12563:        .long   str01           # jump if not variable name
                   12564:        movl    4*vrfnc(r9),r10 # else load function pointer
                   12565:        cmpl    r10,$stndf      # jump if function is defined
                   12566:        bnequ   str02
                   12567: #
                   12568: #      HERE FOR BAD FOURTH ARGUMENT
                   12569: #
                   12570: str01: jmp     er_197          # trace fourth arg is not function name or null
                   12571: #
                   12572: #      HERE WITH FUNCTION POINTER IN XL
                   12573: #
                   12574: str02: movl    (sp)+,r9        # load third argument (tag)
                   12575:        clrl    r7              # set zero as trtyp value for now
                   12576:        jsb     trbld           # build trblk for trace call
                   12577:        movl    r9,r10          # move trblk pointer for trace
                   12578:        jsb     trace           # call trace procedure
                   12579:        .long   er_198          # trace first argument is not appropriate name
                   12580:        .long   er_199          # trace second argument is not trace type
                   12581:        jmp     exnul           # return null
                   12582: #
                   12583: #      HERE TO CALL SYSTEM TRACE TOGGLE ROUTINE
                   12584: #
                   12585: str03: jsb     systt           # call it
                   12586:        addl2   $4*num04,sp     # pop trace arguments
                   12587:        jmp     exnul           # return
                   12588:        #page   
                   12589: #
                   12590: #      TRIM
                   12591: #
                   12592: s$trm:                         # entry point
                   12593:        jsb     gtstg           # load argument as string
                   12594:        .long   er_200          # trim argument is not string
                   12595:        tstl    r6              # return null if argument is null
                   12596:        bnequ   0f
                   12597:        jmp     exnul
                   12598: 0:             
                   12599:        movl    r9,r10          # copy string pointer
                   12600:        movab   3+(4*schar)(r6),r6 # get block length
                   12601:        bicl2   $3,r6
                   12602:        jsb     alloc           # allocate copy same size
                   12603:        movl    r9,r7           # save pointer to copy
                   12604:        jsb     sbmvw           # copy old string block to new
                   12605:        movl    r7,r9           # restore ptr to new block
                   12606:        jsb     trimr           # trim blanks (wb is non-zero)
                   12607:        jmp     exixr           # exit with result in xr
                   12608:        #page   
                   12609: #
                   12610: #      UNLOAD
                   12611: #
                   12612: s$unl:                         # entry point
                   12613:        movl    (sp)+,r9        # load argument
                   12614:        jsb     gtnvr           # point to vrblk
                   12615:        .long   er_201          # unload argument is not natural variable name
                   12616:        movl    $stndf,r10      # get ptr to undefined function
                   12617:        jsb     dffnc           # undefine named function
                   12618:        jmp     exnul           # return null as result
                   12619:        #title  s p i t b o l -- utility procedures
                   12620: #
                   12621: #      THE FOLLOWING SECTION CONTAINS PROCEDURES WHICH ARE
                   12622: #      USED FOR VARIOUS PURPOSES THROUGHOUT THE SYSTEM.
                   12623: #
                   12624: #      EACH PROCEDURE IS PRECEDED BY A DESCRIPTION OF THE
                   12625: #      CALLING SEQUENCE. USUALLY THE ARGUMENTS ARE IN REGISTERS
                   12626: #      BUT ARGUMENTS CAN ALSO OCCUR ON THE STACK AND AS
                   12627: #      PARAMETERS ASSEMBLED AFTER THE JSR INSTRUCTION.
                   12628: #
                   12629: #      THE FOLLOWING CONSIDERATIONS APPLY TO THESE DESCRIPTIONS.
                   12630: #
                   12631: #      1)   THE STACK POINTER (XS) IS NOT CHANGED UNLESS THE
                   12632: #           CHANGE IS EXPLICITLY DOCUMENTED IN THE CALL.
                   12633: #
                   12634: #      2)   REGISTERS WHOSE ENTRY VALUES ARE NOT MENTIONED
                   12635: #           MAY CONTAIN ANY VALUE EXCEPT THAT XL,XR MAY ONLY
                   12636: #           CONTAIN PROPER (COLLECTABLE) POINTER VALUES.
                   12637: #           THIS CONDITION ON XR MEANS THAT THE CALLED ROUTINE
                   12638: #           MAY IF IT CHOOSES PRESERVE XR BY STACKING.
                   12639: #
                   12640: #      3)   REGISTERS NOT MENTIONED ON EXIT CONTAIN THE SAME
                   12641: #           VALUES AS THEY DID ON ENTRY EXCEPT THAT VALUES IN
                   12642: #           XR,XL MAY HAVE BEEN RELOCATED BY THE COLLECTOR.
                   12643: #
                   12644: #      4)   REGISTERS WHICH ARE DESTROYED ON EXIT MAY CONTAIN
                   12645: #           ANY VALUE EXCEPT THAT VALUES IN XL,XR ARE PROPER
                   12646: #           (COLLECTABLE) POINTERS.
                   12647: #
                   12648: #      5)   THE CODE POINTER REGISTER POINTS TO THE CURRENT
                   12649: #           CODE LOCATION ON ENTRY AND IS UNCHANGED ON EXIT.
                   12650: #
                   12651: #      IN THE ABOVE DESCRIPTION, A COLLECTABLE POINTER IS ONE
                   12652: #      WHICH EITHER POINTS OUTSIDE THE DYNAMIC REGION OR
                   12653: #      POINTS TO THE START OF A BLOCK IN THE DYNAMIC REGION.
                   12654: #
                   12655: #      IN THOSE CASES WHERE THE CALLING SEQUENCE CONTAINS
                   12656: #      PARAMETERS WHICH ARE USED AS ALTERNATE RETURN POINTS,
                   12657: #      THESE PARAMETERS MAY BE REPLACED BY ERROR CODES
                   12658: #      ASSEMBLED WITH THE ERR INSTRUCTION. THIS WILL RESULT
                   12659: #      IN THE POSTING OF THE ERROR IF THE RETURN IS TAKEN.
                   12660: #
                   12661: #      THE PROCEDURES ALL HAVE NAMES CONSISTING OF FIVE LETTERS
                   12662: #      AND ARE IN ALPHABETICAL ORDER BY THEIR NAMES.
                   12663:        #page   
                   12664: #
                   12665: #      ACESS - ACCESS VARIABLE VALUE WITH TRACE/INPUT CHECKS
                   12666: #
                   12667: #      ACESS LOADS THE VALUE OF A VARIABLE. TRACE AND INPUT
                   12668: #      ASSOCIATIONS ARE TESTED FOR AND EXECUTED AS REQUIRED.
                   12669: #      ACESS ALSO HANDLES THE SPECIAL CASES OF PSEUDO-VARIABLES.
                   12670: #
                   12671: #      (XL)                  VARIABLE NAME BASE
                   12672: #      (WA)                  VARIABLE NAME OFFSET
                   12673: #      JSR  ACESS            CALL TO ACCESS VALUE
                   12674: #      PPM  LOC              TRANSFER LOC IF ACCESS FAILURE
                   12675: #      (XR)                  VARIABLE VALUE
                   12676: #      (WA,WB,WC)            DESTROYED
                   12677: #      (XL,RA)               DESTROYED
                   12678: #
                   12679: #      FAILURE CAN OCCUR IF AN INPUT ASSOCIATION CAUSES AN END
                   12680: #      OF FILE CONDITION OR IF THE EVALUATION OF AN EXPRESSION
                   12681: #      ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS.
                   12682: #
                   12683: acess: #prc                    # entry point (recursive)
                   12684:        movl    r10,r9          # copy name base
                   12685:        addl2   r6,r9           # point to variable location
                   12686:        movl    (r9),r9         # load variable value
                   12687: #
                   12688: #      LOOP HERE TO CHECK FOR SUCCESSIVE TRBLKS
                   12689: #
                   12690: acs02: cmpl    (r9),$b$trt     # jump if not trapped
                   12691:        beqlu   0f
                   12692:        jmp     acs18
                   12693: 0:             
                   12694: #
                   12695: #      HERE IF TRAPPED
                   12696: #
                   12697:        cmpl    r9,$trbkv       # jump if keyword variable
                   12698:        bnequ   0f
                   12699:        jmp     acs12
                   12700: 0:             
                   12701:        cmpl    r9,$trbev       # jump if not expression variable
                   12702:        bnequ   acs05
                   12703: #
                   12704: #      HERE FOR EXPRESSION VARIABLE, EVALUATE VARIABLE
                   12705: #
                   12706:        movl    4*evexp(r10),r9 # load expression pointer
                   12707:        clrl    r7              # evaluate by value
                   12708:        jsb     evalx           # evaluate expression
                   12709:        .long   acs04           # jump if evaluation failure
                   12710:        jmp     acs02           # check value for more trblks
                   12711:        #page   
                   12712: #
                   12713: #      ACESS (CONTINUED)
                   12714: #
                   12715: #      HERE ON READING END OF FILE
                   12716: #
                   12717: acs03: addl2   $4*num03,sp     # pop trblk ptr, name base and offset
                   12718:        movl    r9,dnamp        # pop unused scblk
                   12719: #
                   12720: #      MERGE HERE WHEN EVALUATION OF EXPRESSION FAILS
                   12721: #
                   12722: acs04: movl    (sp)+,r11       # take alternate (failure) return
                   12723:        jmp     *(r11)+
                   12724: #
                   12725: #      HERE IF NOT KEYWORD OR EXPRESSION VARIABLE
                   12726: #
                   12727: acs05: movl    4*trtyp(r9),r7  # load trap type code
                   12728:        tstl    r7              # jump if not input association
                   12729:        beqlu   0f
                   12730:        jmp     acs10
                   12731: 0:             
                   12732:        tstl    kvinp           # ignore input assoc if input is off
                   12733:        bnequ   0f
                   12734:        jmp     acs09
                   12735: 0:             
                   12736: #
                   12737: #      HERE FOR INPUT ASSOCIATION
                   12738: #
                   12739:        movl    r10,-(sp)       # stack name base
                   12740:        movl    r6,-(sp)        # stack name offset
                   12741:        movl    r9,-(sp)        # stack trblk pointer
                   12742:        movl    4*trfpt(r9),r10 # get file ctrl blk ptr or zero
                   12743:        tstl    r10             # jump if not standard input file
                   12744:        bnequ   acs06
                   12745:        cmpl    4*trter(r9),$v$ter # jump if terminal
                   12746:        bnequ   0f
                   12747:        jmp     acs21
                   12748: 0:             
                   12749: #
                   12750: #      HERE TO READ FROM STANDARD INPUT FILE
                   12751: #
                   12752:        movl    cswin,r6        # length for read buffer
                   12753:        jsb     alocs           # build string of appropriate length
                   12754:        jsb     sysrd           # read next standard input image
                   12755:        .long   acs03           # jump to fail exit if end of file
                   12756:        jmp     acs07           # else merge with other file case
                   12757: #
                   12758: #      HERE FOR INPUT FROM OTHER THAN STANDARD INPUT FILE
                   12759: #
                   12760: acs06: movl    r10,r6          # fcblk ptr
                   12761:        jsb     sysil           # get input record max length (to wa)
                   12762:        jsb     alocs           # allocate string of correct size
                   12763:        movl    r10,r6          # fcblk ptr
                   12764:        jsb     sysin           # call system input routine
                   12765:        .long   acs03           # jump to fail exit if end of file
                   12766:        .long   acs22           # error
                   12767:        .long   acs23           # error
                   12768:        #page   
                   12769: #
                   12770: #      ACESS (CONTINUED)
                   12771: #
                   12772: #      MERGE HERE AFTER OBTAINING INPUT RECORD
                   12773: #
                   12774: acs07: movl    kvtrm,r7        # load trim indicator
                   12775:        jsb     trimr           # trim record as required
                   12776:        movl    r9,r7           # copy result pointer
                   12777:        movl    (sp),r9         # reload pointer to trblk
                   12778: #
                   12779: #      LOOP TO CHASE TO END OF TRBLK CHAIN AND STORE VALUE
                   12780: #
                   12781: acs08: movl    r9,r10          # save pointer to this trblk
                   12782:        movl    4*trnxt(r9),r9  # load forward pointer
                   12783:        cmpl    (r9),$b$trt     # loop if this is another trblk
                   12784:        beqlu   acs08
                   12785:        movl    r7,4*trnxt(r10) # else store result at end of chain
                   12786:        movl    (sp)+,r9        # restore initial trblk pointer
                   12787:        movl    (sp)+,r6        # restore name offset
                   12788:        movl    (sp)+,r10       # restore name base pointer
                   12789: #
                   12790: #      COME HERE TO MOVE TO NEXT TRBLK
                   12791: #
                   12792: acs09: movl    4*trnxt(r9),r9  # load forward ptr to next value
                   12793:        jmp     acs02           # back to check if trapped
                   12794: #
                   12795: #      HERE TO CHECK FOR ACCESS TRACE TRBLK
                   12796: #
                   12797: acs10: cmpl    r7,$trtac       # loop back if not access trace
                   12798:        beqlu   0f
                   12799:        jmp     acs09
                   12800: 0:             
                   12801:        tstl    kvtra           # ignore access trace if trace off
                   12802:        bnequ   0f
                   12803:        jmp     acs09
                   12804: 0:             
                   12805:        decl    kvtra           # else decrement trace count
                   12806:        tstl    4*trfnc(r9)     # jump if print trace
                   12807:        beqlu   acs11
                   12808:        #page   
                   12809: #
                   12810: #      ACESS (CONTINUED)
                   12811: #
                   12812: #      HERE FOR FULL FUNCTION TRACE
                   12813: #
                   12814:        jsb     trxeq           # call routine to execute trace
                   12815:        jmp     acs09           # jump for next trblk
                   12816: #
                   12817: #      HERE FOR CASE OF PRINT TRACE
                   12818: #
                   12819: acs11: jsb     prtsn           # print statement number
                   12820:        jsb     prtnv           # print name = value
                   12821:        jmp     acs09           # jump back for next trblk
                   12822: #
                   12823: #      HERE FOR KEYWORD VARIABLE
                   12824: #
                   12825: acs12: movl    4*kvnum(r10),r9 # load keyword number
                   12826:        cmpl    r9,$k$v$$       # jump if not one word value
                   12827:        bgequ   acs14
                   12828:        movl    l^kvabe(r9),r5  # else load value as integer
                   12829: #
                   12830: #      COMMON EXIT WITH KEYWORD VALUE AS INTEGER IN (IA)
                   12831: #
                   12832: acs13: jsb     icbld           # build icblk
                   12833:        jmp     acs18           # jump to exit
                   12834: #
                   12835: #      HERE IF NOT ONE WORD KEYWORD VALUE
                   12836: #
                   12837: acs14: cmpl    r9,$k$s$$       # jump if special case
                   12838:        bgequ   acs15
                   12839:        subl2   $k$v$$,r9       # else get offset
                   12840:        addl2   $ndabo,r9       # point to pattern value
                   12841:        jmp     acs18           # jump to exit
                   12842: #
                   12843: #      HERE IF SPECIAL KEYWORD CASE
                   12844: #
                   12845: acs15: movl    kvrtn,r10       # load rtntype in case
                   12846:        movl    kvstl,r5        # load stlimit in case
                   12847:        subl2   $k$s$$,r9       # get case number
                   12848:        casel   r9,$0,$5                # switch on keyword number
                   12849: 5:             
                   12850:        .word   acs16-5b        # jump if alphabet
                   12851:        .word   acs17-5b        # rtntype
                   12852:        .word   acs19-5b        # stcount
                   12853:        .word   acs20-5b        # errtext
                   12854:        .word   acs13-5b        # stlimit
                   12855:        #esw                    # end switch on keyword number
                   12856:        #page   
                   12857: #
                   12858: #      ACESS (CONTINUED)
                   12859: #
                   12860: #      ALPHABET
                   12861: #
                   12862: acs16: movl    kvalp,r10       # load pointer to alphabet string
                   12863: #
                   12864: #      RTNTYPE MERGES HERE
                   12865: #
                   12866: acs17: movl    r10,r9          # copy string ptr to proper reg
                   12867: #
                   12868: #      COMMON RETURN POINT
                   12869: #
                   12870: acs18: addl2   $4*1,(sp)       # return to acess caller
                   12871:        rsb     
                   12872: #
                   12873: #      HERE FOR STCOUNT (IA HAS STLIMIT)
                   12874: #
                   12875: acs19: subl2   kvstc,r5        # stcount = limit - left
                   12876:        jmp     acs13           # merge back with integer result
                   12877: #
                   12878: #      ERRTEXT
                   12879: #
                   12880: acs20: movl    r$etx,r9        # get errtext string
                   12881:        jmp     acs18           # merge with result
                   12882: #
                   12883: #      HERE TO READ A RECORD FROM TERMINAL
                   12884: #
                   12885: acs21: movl    $rilen,r6       # buffer length
                   12886:        jsb     alocs           # allocate buffer
                   12887:        jsb     sysri           # read record
                   12888:        .long   acs03           # endfile
                   12889:        jmp     acs07           # merge with record read
                   12890: #
                   12891: #      ERROR RETURNS
                   12892: #
                   12893: acs22: movl    r9,dnamp        # pop unused scblk
                   12894:        jmp     er_202          # input from file caused non-recoverable error
                   12895: #
                   12896: acs23: movl    r9,dnamp        # pop unused scblk
                   12897:        jmp     er_203          # input file record has incorrect format
                   12898:        #enp                    # end procedure acess
                   12899:        #page   
                   12900: #
                   12901: #      ACOMP -- COMPARE TWO ARITHMETIC VALUES
                   12902: #
                   12903: #      1(XS)                 FIRST ARGUMENT
                   12904: #      0(XS)                 SECOND ARGUMENT
                   12905: #      JSR  ACOMP            CALL TO COMPARE VALUES
                   12906: #      PPM  LOC              TRANSFER LOC IF ARG1 IS NON-NUMERIC
                   12907: #      PPM  LOC              TRANSFER LOC IF ARG2 IS NON-NUMERIC
                   12908: #      PPM  LOC              TRANSFER LOC FOR ARG1 LT ARG2
                   12909: #      PPM  LOC              TRANSFER LOC FOR ARG1 EQ ARG2
                   12910: #      PPM  LOC              TRANSFER LOC FOR ARG1 GT ARG2
                   12911: #      (NORMAL RETURN IS NEVER GIVEN)
                   12912: #      (WA,WB,WC,IA,RA)      DESTROYED
                   12913: #      (XL,XR)               DESTROYED
                   12914: #
                   12915:        .data   1
                   12916: acomp_s:       .long   0
                   12917:        .text   0
                   12918: acomp: movl    (sp)+,acomp_s   # entry point
                   12919:        jsb     arith           # load arithmetic operands
                   12920:        .long   acmp7           # jump if first arg non-numeric
                   12921:        .long   acmp8           # jump if second arg non-numeric
                   12922:        .long   acmp4           # jump if real arguments
                   12923: #
                   12924: #      HERE FOR INTEGER ARGUMENTS
                   12925: #
                   12926:        subl2   4*icval(r10),r5 # subtract to compare
                   12927:        bvs     acmp3
                   12928:        tstl    r5              # else jump if arg1 lt arg2
                   12929:        blss    acmp5
                   12930:        tstl    r5              # jump if arg1 eq arg2
                   12931:        beql    acmp2
                   12932: #
                   12933: #      HERE IF ARG1 GT ARG2
                   12934: #
                   12935: acmp1: addl3   $4*4,acomp_s,r11        # take gt exit
                   12936:        jmp     *(r11)+
                   12937: #
                   12938: #      HERE IF ARG1 EQ ARG2
                   12939: #
                   12940: acmp2: addl3   $4*3,acomp_s,r11        # take eq exit
                   12941:        jmp     *(r11)+
                   12942:        #page   
                   12943: #
                   12944: #      ACOMP (CONTINUED)
                   12945: #
                   12946: #      HERE FOR INTEGER OVERFLOW ON SUBTRACT
                   12947: #
                   12948: acmp3: movl    4*icval(r10),r5 # load second argument
                   12949:        tstl    r5              # gt if negative
                   12950:        blss    acmp1
                   12951:        jmp     acmp5           # else lt
                   12952: #
                   12953: #      HERE FOR REAL OPERANDS
                   12954: #
                   12955: acmp4: subf2   4*rcval(r10),r2 # subtract to compare
                   12956:        bvs     acmp6
                   12957:        tstf    r2              # else jump if arg1 gt
                   12958:        bgtr    acmp1
                   12959:        tstf    r2              # jump if arg1 eq arg2
                   12960:        beql    acmp2
                   12961: #
                   12962: #      HERE IF ARG1 LT ARG2
                   12963: #
                   12964: acmp5: addl3   $4*2,acomp_s,r11        # take lt exit
                   12965:        jmp     *(r11)+
                   12966: #
                   12967: #      HERE IF OVERFLOW ON REAL SUBTRACTION
                   12968: #
                   12969: acmp6: movf    4*rcval(r10),r2 # reload arg2
                   12970:        tstf    r2              # gt if negative
                   12971:        blss    acmp1
                   12972:        jmp     acmp5           # else lt
                   12973: #
                   12974: #      HERE IF ARG1 NON-NUMERIC
                   12975: #
                   12976: acmp7: movl    acomp_s,r11     # take error exit
                   12977:        jmp     *(r11)+
                   12978: #
                   12979: #      HERE IF ARG2 NON-NUMERIC
                   12980: #
                   12981: acmp8: addl3   $4*1,acomp_s,r11        # take error exit
                   12982:        jmp     *(r11)+
                   12983:        #enp                    # end procedure acomp
                   12984:        #page   
                   12985: #
                   12986: #      ALLOC                 ALLOCATE BLOCK OF DYNAMIC STORAGE
                   12987: #
                   12988: #      (WA)                  LENGTH REQUIRED IN BYTES
                   12989: #      JSR  ALLOC            CALL TO ALLOCATE BLOCK
                   12990: #      (XR)                  POINTER TO ALLOCATED BLOCK
                   12991: #
                   12992: #      A POSSIBLE ALTERNATIVE TO AOV .. AND FOLLOWING STMT IS -
                   12993: #      MOV  DNAME,XR .  SUB  WA,XR .  BLO XR,DNAMP,ALOC2 .
                   12994: #      MOV  DNAMP,XR .  ADD  WA,XR
                   12995: #
                   12996: alloc: #prc                    # entry point
                   12997: #
                   12998: #      COMMON EXIT POINT
                   12999: #
                   13000: aloc1: movl    dnamp,r9        # point to next available loc
                   13001:        addl2   r6,r9           # point past allocated block
                   13002:        bvc     0f
                   13003:        jmp     aloc2
                   13004: 0:             
                   13005:        cmpl    r9,dname        # jump if not enough room
                   13006:        bgtru   aloc2
                   13007:        movl    r9,dnamp        # store new pointer
                   13008:        subl2   r6,r9           # point back to start of allocated bk
                   13009:        rsb                     # return to caller
                   13010: #
                   13011: #      HERE IF INSUFFICIENT ROOM, TRY A GARBAGE COLLECTION
                   13012: #
                   13013: aloc2: movl    r7,allsv        # save wb
                   13014:        clrl    r7              # set no upward move for gbcol
                   13015:        jsb     gbcol           # garbage collect
                   13016: #
                   13017: #      SEE IF ROOM AFTER GBCOL OR SYSMM CALL
                   13018: #
                   13019: aloc3: movl    dnamp,r9        # point to first available loc
                   13020:        addl2   r6,r9           # point past new block
                   13021:        bvc     0f
                   13022:        jmp     alc3a
                   13023: 0:             
                   13024:        cmpl    r9,dname        # jump if there is room now
                   13025:        blequ   aloc4
                   13026: #
                   13027: #      FAILED AGAIN, SEE IF WE CAN GET MORE CORE
                   13028: #
                   13029: alc3a: jsb     sysmm           # try to get more memory
                   13030:        moval   0[r9],r9        # convert to baus (sgd05)
                   13031:        addl2   r9,dname        # bump ptr by amount obtained
                   13032:        tstl    r9              # jump if got more core
                   13033:        bnequ   aloc3
                   13034:        addl2   rsmem,dname     # get the reserve memory
                   13035:        clrl    rsmem           # only permissible once
                   13036:        incl    errft           # fatal error
                   13037:        jmp     er_204          # memory overflow
                   13038:        #page   
                   13039: #
                   13040: #      HERE AFTER SUCCESSFUL GARBAGE COLLECTION
                   13041: #
                   13042: aloc4: movl    r5,allia        # save ia
                   13043:        movl    dname,r7        # get dynamic end adrs
                   13044:        subl2   dnamp,r7        # compute free store
                   13045:        ashl    $-2,r7,r7       # convert bytes to words
                   13046:        movl    r7,r5           # put free store in ia
                   13047:        mull2   alfsf,r5        # multiply by free store factor
                   13048:        bvs     aloc5
                   13049:        movl    dname,r7        # dynamic end adrs
                   13050:        subl2   dnamb,r7        # compute total amount of dynamic
                   13051:        ashl    $-2,r7,r7       # convert to words
                   13052:        movl    r7,aldyn        # store it
                   13053:        subl2   aldyn,r5        # subtract from scaled up free store
                   13054:        tstl    r5              # jump if sufficient free store
                   13055:        bgtr    aloc5
                   13056:        jsb     sysmm           # try to get more store
                   13057:        moval   0[r9],r9        # convert to baus (sgd05)
                   13058:        addl2   r9,dname        # adjust dynamic end adrs
                   13059: #
                   13060: #      MERGE TO RESTORE IA AND WB
                   13061: #
                   13062: aloc5: movl    allia,r5        # recover ia
                   13063:        movl    allsv,r7        # restore wb
                   13064:        jmp     aloc1           # jump back to exit
                   13065:        #enp                    # end procedure alloc
                   13066:        #page   
                   13067: #
                   13068: #      ALOBF -- ALLOCATE BUFFER
                   13069: #
                   13070: #      THIS ROUTINES ALLOCATES A NEW BUFFER.  AS THE BFBLK
                   13071: #      AND BCBLK COME IN PAIRS, BOTH ARE ALLOCATED HERE,
                   13072: #      AND XR POINTS TO THE BCBLK ON RETURN.  THE BFBLK
                   13073: #      AND BCBLK ARE SET TO THE NULL BUFFER, AND THE IDVAL
                   13074: #      IS ZERO ON RETURN.
                   13075: #
                   13076: #      (WA)                  BUFFER SIZE IN CHARACTERS
                   13077: #      JSR  ALOBF            CALL TO CREATE BUFFER
                   13078: #      (XR)                  BCBLK PTR
                   13079: #      (WA,WB)               DESTROYED
                   13080: #
                   13081: alobf: #prc                    # entry point
                   13082:        movl    r6,r7           # hang onto allocation size
                   13083:        movab   3+(4*bfsi$)(r6),r6 # get total block size
                   13084:        bicl2   $3,r6
                   13085:        cmpl    r6,mxlen        # check for maxlen exceeded
                   13086:        bgequ   alb01
                   13087:        addl2   $4*bcsi$,r6     # add in allocation for bcblk
                   13088:        jsb     alloc           # allocate frame
                   13089:        movl    $b$bct,(r9)     # set type
                   13090:        clrl    4*idval(r9)     # no id yet
                   13091:        clrl    4*bclen(r9)     # no defined length
                   13092:        movl    r10,r6          # save xl
                   13093:        movl    r9,r10          # copy bcblk ptr
                   13094:        addl2   $4*bcsi$,r10    # bias past partially built bcblk
                   13095:        movl    $b$bft,(r10)    # set bfblk type word
                   13096:        movl    r7,4*bfalc(r10) # set allocated size
                   13097:        movl    r10,4*bcbuf(r9) # set pointer in bcblk
                   13098:        clrl    4*bfchr(r10)    # clear first word (null pad)
                   13099:        movl    r6,r10          # restore entry xl
                   13100:        rsb                     # return to caller
                   13101: #
                   13102: #      HERE FOR MXLEN EXCEEDED
                   13103: #
                   13104: alb01: jmp     er_274          # requested buffer allocation exceeds mxlen
                   13105:        #enp                    # end procedure alobf
                   13106:        #page   
                   13107: #
                   13108: #      ALOCS -- ALLOCATE STRING BLOCK
                   13109: #
                   13110: #      ALOCS IS USED TO BUILD A FRAME FOR A STRING BLOCK INTO
                   13111: #      WHICH THE ACTUAL CHARACTERS ARE PLACED BY THE CALLER.
                   13112: #      ALL STRINGS ARE CREATED WITH A CALL TO ALOCS (THE
                   13113: #      EXCEPTIONS OCCUR IN TRIMR AND S$RPL PROCEDURES).
                   13114: #
                   13115: #      (WA)                  LENGTH OF STRING TO BE ALLOCATED
                   13116: #      JSR  ALOCS            CALL TO ALLOCATE SCBLK
                   13117: #      (XR)                  POINTER TO RESULTING SCBLK
                   13118: #      (WA)                  DESTROYED
                   13119: #      (WC)                  CHARACTER COUNT (ENTRY VALUE OF WA)
                   13120: #
                   13121: #      THE RESULTING SCBLK HAS THE TYPE WORD AND THE LENGTH
                   13122: #      FILLED IN AND THE LAST WORD IS CLEARED TO ZERO CHARACTERS
                   13123: #      TO ENSURE CORRECT RIGHT PADDING OF THE FINAL WORD.
                   13124: #
                   13125: alocs: #prc                    # entry point
                   13126:        cmpl    r6,kvmxl        # jump if length exceeeds maxlength
                   13127:        bgtru   alcs2
                   13128:        movl    r6,r8           # else copy length
                   13129:        movab   3+(4*scsi$)(r6),r6 # compute length of scblk in bytes
                   13130:        bicl2   $3,r6
                   13131:        movl    dnamp,r9        # point to next available location
                   13132:        addl2   r6,r9           # point past block
                   13133:        bvc     0f
                   13134:        jmp     alcs0
                   13135: 0:             
                   13136:        cmpl    r9,dname        # jump if there is room
                   13137:        blequ   alcs1
                   13138: #
                   13139: #      INSUFFICIENT MEMORY
                   13140: #
                   13141: alcs0: clrl    r9              # else clear garbage xr value
                   13142:        jsb     alloc           # and use standard allocator
                   13143:        addl2   r6,r9           # point past end of block to merge
                   13144: #
                   13145: #      MERGE HERE WITH XR POINTING BEYOND NEW BLOCK
                   13146: #
                   13147: alcs1: movl    r9,dnamp        # set updated storage pointer
                   13148:        clrl    -(r9)           # store zero chars in last word
                   13149:        subl2   $4,r6           # decrement length
                   13150:        subl2   r6,r9           # point back to start of block
                   13151:        movl    $b$scl,(r9)     # set type word
                   13152:        movl    r8,4*sclen(r9)  # store length in chars
                   13153:        rsb                     # return to alocs caller
                   13154: #
                   13155: #      COME HERE IF STRING IS TOO LONG
                   13156: #
                   13157: alcs2: jmp     er_205          # string length exceeds value of maxlngth keyword
                   13158:        #enp                    # end procedure alocs
                   13159:        #page   
                   13160: #
                   13161: #      ALOST -- ALLOCATE SPACE IN STATIC REGION
                   13162: #
                   13163: #      (WA)                  LENGTH REQUIRED IN BYTES
                   13164: #      JSR  ALOST            CALL TO ALLOCATE SPACE
                   13165: #      (XR)                  POINTER TO ALLOCATED BLOCK
                   13166: #      (WB)                  DESTROYED
                   13167: #
                   13168: #      NOTE THAT THE CODING ENSURES THAT THE RESULTING VALUE
                   13169: #      OF STATE IS ALWAYS LESS THAN DNAMB. THIS FACT IS USED
                   13170: #      IN TESTING A VARIABLE NAME FOR BEING IN THE STATIC REGION
                   13171: #
                   13172: alost: #prc                    # entry point
                   13173: #
                   13174: #      MERGE BACK HERE AFTER ALLOCATING NEW CHUNK
                   13175: #
                   13176: alst1: movl    state,r9        # point to current end of area
                   13177:        addl2   r6,r9           # point beyond proposed block
                   13178:        bvc     0f
                   13179:        jmp     alst2
                   13180: 0:             
                   13181:        cmpl    r9,dnamb        # jump if overlap with dynamic area
                   13182:        bgequ   alst2
                   13183:        movl    r9,state        # else store new pointer
                   13184:        subl2   r6,r9           # point back to start of block
                   13185:        rsb                     # return to alost caller
                   13186: #
                   13187: #      HERE IF NO ROOM, PREPARE TO MOVE DYNAMIC STORAGE UP
                   13188: #
                   13189: alst2: movl    r6,alsta        # save wa
                   13190:        cmpl    r6,$4*e$sts     # skip if requested chunk is large
                   13191:        bgequ   alst3
                   13192:        movl    $4*e$sts,r6     # else set to get large enough chunk
                   13193: #
                   13194: #      HERE WITH AMOUNT TO MOVE UP IN WA
                   13195: #
                   13196: alst3: jsb     alloc           # allocate block to ensure room
                   13197:        movl    r9,dnamp        # and delete it
                   13198:        movl    r6,r7           # copy move up amount
                   13199:        jsb     gbcol           # call gbcol to move dynamic area up
                   13200:        movl    alsta,r6        # restore wa
                   13201:        jmp     alst1           # loop back to try again
                   13202:        #enp                    # end procedure alost
                   13203:        #page   
                   13204: #
                   13205: #      APNDB -- APPEND STRING TO BUFFER
                   13206: #
                   13207: #      THIS ROUTINE IS USED BY BUFFER HANDLING ROUTINES TO
                   13208: #      APPEND DATA TO AN EXISTING BFBLK.
                   13209: #
                   13210: #      (XR)                  EXISTING BCBLK TO BE APPENDED
                   13211: #      (XL)                  CONVERTABLE TO STRING
                   13212: #      JSR  APNDB            CALL TO APPEND TO BUFFER
                   13213: #      PPM  LOC              THREAD IF (XL) CANT BE CONVERTED
                   13214: #      PPM  LOC              IF NOT ENOUGH ROOM
                   13215: #      (WA,WB)               DESTROYED
                   13216: #
                   13217: #      IF MORE CHARACTERS ARE SPECIFIED THAN CAN BE INSERTED,
                   13218: #      THEN NO ACTION IS TAKEN AND THE SECOND RETURN IS TAKEN.
                   13219: #
                   13220: apndb: #prc                    # entry point
                   13221:        movl    4*bclen(r9),r6  # load offset to insert
                   13222:        clrl    r7              # replace section is null
                   13223:        jsb     insbf           # call to insert at end
                   13224:        .long   apn01           # convert error
                   13225:        .long   apn02           # no room
                   13226:        addl2   $4*2,(sp)       # return to caller
                   13227:        rsb     
                   13228: #
                   13229: #      HERE TO TAKE CONVERT FAILURE EXIT
                   13230: #
                   13231: apn01: movl    (sp)+,r11       # return to caller alternate
                   13232:        jmp     *(r11)+
                   13233: #
                   13234: #      HERE FOR NO FIT EXIT
                   13235: #
                   13236: apn02: addl3   $4*1,(sp)+,r11  # alternate exit to caller
                   13237:        jmp     *(r11)+
                   13238:        #enp                    # end procedure apndb
                   13239:        #page   
                   13240: #
                   13241: #      ARITH -- FETCH ARITHMETIC OPERANDS
                   13242: #
                   13243: #      ARITH IS USED BY FUNCTIONS AND OPERATORS WHICH EXPECT
                   13244: #      TWO NUMERIC ARGUMENTS (OPERANDS) WHICH MUST BOTH BE
                   13245: #      INTEGER OR BOTH BE REAL. ARITH FETCHES TWO ARGUMENTS FROM
                   13246: #      THE STACK AND PERFORMS ANY NECESSARY CONVERSIONS.
                   13247: #
                   13248: #      1(XS)                 FIRST ARGUMENT (LEFT OPERAND)
                   13249: #      0(XS)                 SECOND ARGUMENT (RIGHT OPERAND)
                   13250: #      JSR  ARITH            CALL TO FETCH NUMERIC ARGUMENTS
                   13251: #      PPM  LOC              TRANSFER LOC FOR OPND 1 NON-NUMERIC
                   13252: #      PPM  LOC              TRANSFER LOC FOR OPND 2 NON-NUMERIC
                   13253: #      PPM  LOC              TRANSFER LOC FOR REAL OPERANDS
                   13254: #
                   13255: #      FOR INTEGER ARGS, CONTROL RETURNS PAST THE PARAMETERS
                   13256: #
                   13257: #      (IA)                  LEFT OPERAND VALUE
                   13258: #      (XR)                  PTR TO ICBLK FOR LEFT OPERAND
                   13259: #      (XL)                  PTR TO ICBLK FOR RIGHT OPERAND
                   13260: #      (XS)                  POPPED TWICE
                   13261: #      (WA,WB,RA)            DESTROYED
                   13262: #
                   13263: #      FOR REAL ARGUMENTS, CONTROL RETURNS TO THE LOCATION
                   13264: #      SPECIFIED BY THE THIRD PARAMETER.
                   13265: #
                   13266: #      (RA)                  LEFT OPERAND VALUE
                   13267: #      (XR)                  PTR TO RCBLK FOR LEFT OPERAND
                   13268: #      (XL)                  PTR TO RCBLK FOR RIGHT OPERAND
                   13269: #      (WA,WB,WC)            DESTROYED
                   13270: #      (XS)                  POPPED TWICE
                   13271:        #page   
                   13272: #
                   13273: #      ARITH (CONTINUED)
                   13274: #
                   13275: #      ENTRY POINT
                   13276: #
                   13277:        .data   1
                   13278: arith_s:       .long   0
                   13279:        .text   0
                   13280: arith: movl    (sp)+,arith_s   # entry point
                   13281:        movl    (sp)+,r10       # load right operand
                   13282:        movl    (sp)+,r9        # load left operand
                   13283:        movl    (r10),r6        # get right operand type word
                   13284:        cmpl    r6,$b$icl       # jump if integer
                   13285:        beqlu   arth1
                   13286:        cmpl    r6,$b$rcl       # jump if real
                   13287:        beqlu   arth4
                   13288:        movl    r9,-(sp)        # else replace left arg on stack
                   13289:        movl    r10,r9          # copy left arg pointer
                   13290:        jsb     gtnum           # convert to numeric
                   13291:        .long   arth6           # jump if unconvertible
                   13292:        movl    r9,r10          # else copy converted result
                   13293:        movl    (r10),r6        # get right operand type word
                   13294:        movl    (sp)+,r9        # reload left argument
                   13295:        cmpl    r6,$b$rcl       # jump if right arg is real
                   13296:        beqlu   arth4
                   13297: #
                   13298: #      HERE IF RIGHT ARG IS AN INTEGER
                   13299: #
                   13300: arth1: cmpl    (r9),$b$icl     # jump if left arg not integer
                   13301:        bnequ   arth3
                   13302: #
                   13303: #      EXIT FOR INTEGER CASE
                   13304: #
                   13305: arth2: movl    4*icval(r9),r5  # load left operand value
                   13306:        addl3   $4*3,arith_s,r11        # return to arith caller
                   13307:        jmp     (r11)
                   13308: #
                   13309: #      HERE FOR RIGHT OPERAND INTEGER, LEFT OPERAND NOT
                   13310: #
                   13311: arth3: jsb     gtnum           # convert left arg to numeric
                   13312:        .long   arth7           # jump if not convertible
                   13313:        cmpl    r6,$b$icl       # jump back if integer-integer
                   13314:        beqlu   arth2
                   13315: #
                   13316: #      HERE WE MUST CONVERT REAL-INTEGER TO REAL-REAL
                   13317: #
                   13318:        movl    r9,-(sp)        # put left arg back on stack
                   13319:        movl    4*icval(r10),r5 # load right argument value
                   13320:        cvtlf   r5,r2           # convert to real
                   13321:        jsb     rcbld           # get real block for right arg, merge
                   13322:        movl    r9,r10          # copy right arg ptr
                   13323:        movl    (sp)+,r9        # load left argument
                   13324:        jmp     arth5           # merge for real-real case
                   13325:        #page   
                   13326: #
                   13327: #      ARITH (CONTINUED)
                   13328: #
                   13329: #      HERE IF RIGHT ARGUMENT IS REAL
                   13330: #
                   13331: arth4: cmpl    (r9),$b$rcl     # jump if left arg real
                   13332:        beqlu   arth5
                   13333:        jsb     gtrea           # else convert to real
                   13334:        .long   arth7           # error if unconvertible
                   13335: #
                   13336: #      HERE FOR REAL-REAL
                   13337: #
                   13338: arth5: movf    4*rcval(r9),r2  # load left operand value
                   13339:        addl3   $4*2,arith_s,r11        # take real-real exit
                   13340:        jmp     *(r11)+
                   13341: #
                   13342: #      HERE FOR ERROR CONVERTING RIGHT ARGUMENT
                   13343: #
                   13344: arth6: addl2   $4,sp           # pop unwanted left arg
                   13345:        addl3   $4*1,arith_s,r11        # take appropriate error exit
                   13346:        jmp     *(r11)+
                   13347: #
                   13348: #      HERE FOR ERROR CONVERTING LEFT OPERAND
                   13349: #
                   13350: arth7: movl    arith_s,r11     # take appropriate error return
                   13351:        jmp     *(r11)+
                   13352:        #enp                    # end procedure arith
                   13353:        #page   
                   13354: #
                   13355: #      ASIGN -- PERFORM ASSIGNMENT
                   13356: #
                   13357: #      ASIGN PERFORMS THE ASSIGNMENT OF A VALUE TO A VARIABLE
                   13358: #      WITH APPROPRIATE CHECKS FOR OUTPUT ASSOCIATIONS AND
                   13359: #      VALUE TRACE ASSOCIATIONS WHICH ARE EXECUTED AS REQUIRED.
                   13360: #      ASIGN ALSO HANDLES THE SPECIAL CASES OF ASSIGNMENT TO
                   13361: #      PATTERN AND EXPRESSION VARIABLES.
                   13362: #
                   13363: #      (WB)                  VALUE TO BE ASSIGNED
                   13364: #      (XL)                  BASE POINTER FOR VARIABLE
                   13365: #      (WA)                  OFFSET FOR VARIABLE
                   13366: #      JSR  ASIGN            CALL TO ASSIGN VALUE TO VARIABLE
                   13367: #      PPM  LOC              TRANSFER LOC FOR FAILURE
                   13368: #      (XR,XL,WA,WB,WC)      DESTROYED
                   13369: #      (RA)                  DESTROYED
                   13370: #
                   13371: #      FAILURE OCCURS IF THE EVALUATION OF AN EXPRESSION
                   13372: #      ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS.
                   13373: #
                   13374: asign: #prc                    # entry point (recursive)
                   13375: #
                   13376: #      MERGE BACK HERE TO ASSIGN RESULT TO EXPRESSION VARIABLE.
                   13377: #
                   13378: asg01: addl2   r6,r10          # point to variable value
                   13379:        movl    (r10),r9        # load variable value
                   13380:        cmpl    (r9),$b$trt     # jump if trapped
                   13381:        beqlu   asg02
                   13382:        movl    r7,(r10)        # else perform assignment
                   13383:        clrl    r10             # clear garbage value in xl
                   13384:        addl2   $4*1,(sp)       # and return to asign caller
                   13385:        rsb     
                   13386: #
                   13387: #      HERE IF VALUE IS TRAPPED
                   13388: #
                   13389: asg02: subl2   r6,r10          # restore name base
                   13390:        cmpl    r9,$trbkv       # jump if keyword variable
                   13391:        bnequ   0f
                   13392:        jmp     asg14
                   13393: 0:             
                   13394:        cmpl    r9,$trbev       # jump if not expression variable
                   13395:        bnequ   asg04
                   13396: #
                   13397: #      HERE FOR ASSIGNMENT TO EXPRESSION VARIABLE
                   13398: #
                   13399:        movl    4*evexp(r10),r9 # point to expression
                   13400:        movl    r7,-(sp)        # store value to assign on stack
                   13401:        movl    $num01,r7       # set for evaluation by name
                   13402:        jsb     evalx           # evaluate expression by name
                   13403:        .long   asg03           # jump if evaluation fails
                   13404:        movl    (sp)+,r7        # else reload value to assign
                   13405:        jmp     asg01           # loop back to perform assignment
                   13406:        #page   
                   13407: #
                   13408: #      ASIGN (CONTINUED)
                   13409: #
                   13410: #      HERE FOR FAILURE DURING EXPRESSION EVALUATION
                   13411: #
                   13412: asg03: addl2   $4,sp           # remove stacked value entry
                   13413:        movl    (sp)+,r11       # take failure exit
                   13414:        jmp     *(r11)+
                   13415: #
                   13416: #      HERE IF NOT KEYWORD OR EXPRESSION VARIABLE
                   13417: #
                   13418: asg04: movl    r9,-(sp)        # save ptr to first trblk
                   13419: #
                   13420: #      LOOP TO CHASE DOWN TRBLK CHAIN AND ASSIGN VALUE AT END
                   13421: #
                   13422: asg05: movl    r9,r8           # save ptr to this trblk
                   13423:        movl    4*trnxt(r9),r9  # point to next trblk
                   13424:        cmpl    (r9),$b$trt     # loop back if another trblk
                   13425:        beqlu   asg05
                   13426:        movl    r8,r9           # else point back to last trblk
                   13427:        movl    r7,4*trval(r9)  # store value at end of chain
                   13428:        movl    (sp)+,r9        # restore ptr to first trblk
                   13429: #
                   13430: #      LOOP TO PROCESS TRBLK ENTRIES ON CHAIN
                   13431: #
                   13432: asg06: movl    4*trtyp(r9),r7  # load type code of trblk
                   13433:        cmpl    r7,$trtvl       # jump if value trace
                   13434:        beqlu   asg08
                   13435:        cmpl    r7,$trtou       # jump if output association
                   13436:        beqlu   asg10
                   13437: #
                   13438: #      HERE TO MOVE TO NEXT TRBLK ON CHAIN
                   13439: #
                   13440: asg07: movl    4*trnxt(r9),r9  # point to next trblk on chain
                   13441:        cmpl    (r9),$b$trt     # loop back if another trblk
                   13442:        beqlu   asg06
                   13443:        addl2   $4*1,(sp)       # else end of chain, return to caller
                   13444:        rsb     
                   13445: #
                   13446: #      HERE TO PROCESS VALUE TRACE
                   13447: #
                   13448: asg08: tstl    kvtra           # ignore value trace if trace off
                   13449:        beqlu   asg07
                   13450:        decl    kvtra           # else decrement trace count
                   13451:        tstl    4*trfnc(r9)     # jump if print trace
                   13452:        beqlu   asg09
                   13453:        jsb     trxeq           # else execute function trace
                   13454:        jmp     asg07           # and loop back
                   13455:        #page   
                   13456: #
                   13457: #      ASIGN (CONTINUED)
                   13458: #
                   13459: #      HERE FOR PRINT TRACE
                   13460: #
                   13461: asg09: jsb     prtsn           # print statement number
                   13462:        jsb     prtnv           # print name = value
                   13463:        jmp     asg07           # loop back for next trblk
                   13464: #
                   13465: #      HERE FOR OUTPUT ASSOCIATION
                   13466: #
                   13467: asg10: tstl    kvoup           # ignore output assoc if output off
                   13468:        beqlu   asg07
                   13469:        movl    r9,r10          # else copy trblk pointer
                   13470:        movl    4*trval(r8),-(sp)# stack value to output (sgd01)
                   13471:        jsb     gtstg           # convert to string
                   13472:        .long   asg12           # get datatype name if unconvertible
                   13473: #
                   13474: #      MERGE WITH STRING FOR OUTPUT
                   13475: #
                   13476: asg11: movl    4*trfpt(r10),r6 # fcblk ptr
                   13477:        tstl    r6              # jump if standard output file
                   13478:        beqlu   asg13
                   13479: #
                   13480: #      HERE FOR OUTPUT TO NON-STANDARD OUTPUT FILE
                   13481: #
                   13482:        jsb     sysou           # call system output routine
                   13483:        .long   er_206          # output caused file overflow
                   13484:        .long   er_207          # output caused non-recoverable error
                   13485:        addl2   $4*1,(sp)       # else all done, return to caller
                   13486:        rsb     
                   13487: #
                   13488: #      IF NOT PRINTABLE, GET DATATYPE NAME INSTEAD
                   13489: #
                   13490: asg12: jsb     dtype           # call datatype routine
                   13491:        jmp     asg11           # merge
                   13492: #
                   13493: #      HERE TO PRINT A STRING ON THE PRINTER
                   13494: #
                   13495: asg13: jsb     prtst           # print string value
                   13496:        cmpl    4*trter(r10),$v$ter # jump if terminal output
                   13497:        bnequ   0f
                   13498:        jmp     asg20
                   13499: 0:             
                   13500:        jsb     prtnl           # end of line
                   13501:        addl2   $4*1,(sp)       # return to caller
                   13502:        rsb     
                   13503:        #page   
                   13504: #
                   13505: #      ASIGN (CONTINUED)
                   13506: #
                   13507: #      HERE FOR KEYWORD ASSIGNMENT
                   13508: #
                   13509: asg14: movl    4*kvnum(r10),r10# load keyword number
                   13510:        cmpl    r10,$k$etx      # jump if errtext
                   13511:        bnequ   0f
                   13512:        jmp     asg19
                   13513: 0:             
                   13514:        movl    r7,r9           # copy value to be assigned
                   13515:        jsb     gtint           # convert to integer
                   13516:        .long   er_208          # keyword value assigned is not integer
                   13517:        movl    4*icval(r9),r5  # else load value
                   13518:        cmpl    r10,$k$stl      # jump if special case of stlimit
                   13519:        beqlu   asg16
                   13520:        movl    r5,r6           # else get addr integer, test ovflow
                   13521:        bgeq    0f
                   13522:        jmp     asg18
                   13523: 0:             
                   13524:        cmpl    r6,mxlen        # fail if too large
                   13525:        bgequ   asg18
                   13526:        cmpl    r10,$k$ert      # jump if special case of errtype
                   13527:        beqlu   asg17
                   13528:        cmpl    r10,$k$pfl      # jump if special case of profile
                   13529:        beqlu   asg21
                   13530:        cmpl    r10,$k$p$$      # jump unless protected
                   13531:        blssu   asg15
                   13532:        jmp     er_209          # keyword in assignment is protected
                   13533: #
                   13534: #      HERE TO DO ASSIGNMENT IF NOT PROTECTED
                   13535: #
                   13536: asg15: movl    r6,l^kvabe(r10) # store new value
                   13537:        addl2   $4*1,(sp)       # return to asign caller
                   13538:        rsb     
                   13539: #
                   13540: #      HERE FOR SPECIAL CASE OF STLIMIT
                   13541: #
                   13542: #      SINCE STCOUNT IS MAINTAINED AS (STLIMIT-STCOUNT)
                   13543: #      IT IS ALSO NECESSARY TO MODIFY STCOUNT APPROPRIATELY.
                   13544: #
                   13545: asg16: subl2   kvstl,r5        # subtract old limit
                   13546:        addl2   kvstc,r5        # add old counter
                   13547:        movl    r5,kvstc        # store new counter value
                   13548:        movl    4*icval(r9),r5  # reload new limit value
                   13549:        movl    r5,kvstl        # store new limit value
                   13550:        addl2   $4*1,(sp)       # return to asign caller
                   13551:        rsb     
                   13552: #
                   13553: #      HERE FOR SPECIAL CASE OF ERRTYPE
                   13554: #
                   13555: asg17: cmpl    r6,$nini9       # ok to signal if in range
                   13556:        bgtru   0f
                   13557:        jmp     error
                   13558: 0:             
                   13559: #
                   13560: #      HERE IF VALUE ASSIGNED IS OUT OF RANGE
                   13561: #
                   13562: asg18: jmp     er_210          # keyword value assigned is negative or too large
                   13563: #
                   13564: #      HERE FOR SPECIAL CASE OF ERRTEXT
                   13565: #
                   13566: asg19: movl    r7,-(sp)        # stack value
                   13567:        jsb     gtstg           # convert to string
                   13568:        .long   er_211          # value assigned to keyword errtext not a string
                   13569:        movl    r9,r$etx        # make assignment
                   13570:        addl2   $4*1,(sp)       # return to caller
                   13571:        rsb     
                   13572: #
                   13573: #      PRINT STRING TO TERMINAL
                   13574: #
                   13575: asg20: jsb     prttr           # print
                   13576:        addl2   $4*1,(sp)       # return
                   13577:        rsb     
                   13578: #
                   13579: #      HERE FOR KEYWORD PROFILE
                   13580: #
                   13581: asg21: cmpl    r6,$num02       # moan if not 0,1, or 2
                   13582:        bgtru   asg18
                   13583:        tstl    r6              # just assign if zero
                   13584:        beqlu   asg15
                   13585:        tstl    pfdmp           # branch if first assignment
                   13586:        beqlu   asg22
                   13587:        cmpl    r6,pfdmp        # also if same value as before
                   13588:        beqlu   asg23
                   13589:        jmp     er_268          # inconsistent value assigned to keyword profile
                   13590: #
                   13591: asg22: movl    r6,pfdmp        # note value on first assignment
                   13592: asg23: jsb     systm           # get the time
                   13593:        movl    r5,pfstm        # fudge some kind of start time
                   13594:        jmp     asg15           # and go assign
                   13595:        #enp                    # end procedure asign
                   13596:        #page   
                   13597: #
                   13598: #      ASINP -- ASSIGN DURING PATTERN MATCH
                   13599: #
                   13600: #      ASINP IS LIKE ASIGN AND HAS A SIMILAR CALLING SEQUENCE
                   13601: #      AND EFFECT. THE DIFFERENCE IS THAT THE GLOBAL PATTERN
                   13602: #      VARIABLES ARE SAVED AND RESTORED IF REQUIRED.
                   13603: #
                   13604: #      (XL)                  BASE POINTER FOR VARIABLE
                   13605: #      (WA)                  OFFSET FOR VARIABLE
                   13606: #      (WB)                  VALUE TO BE ASSIGNED
                   13607: #      JSR  ASINP            CALL TO ASSIGN VALUE TO VARIABLE
                   13608: #      PPM  LOC              TRANSFER LOC IF FAILURE
                   13609: #      (XR,XL)               DESTROYED
                   13610: #      (WA,WB,WC,RA)         DESTROYED
                   13611: #
                   13612: asinp: #prc                    # entry point, recursive
                   13613:        addl2   r6,r10          # point to variable
                   13614:        movl    (r10),r9        # load current contents
                   13615:        cmpl    (r9),$b$trt     # jump if trapped
                   13616:        beqlu   asnp1
                   13617:        movl    r7,(r10)        # else perform assignment
                   13618:        clrl    r10             # clear garbage value in xl
                   13619:        addl2   $4*1,(sp)       # return to asinp caller
                   13620:        rsb     
                   13621: #
                   13622: #      HERE IF VARIABLE IS TRAPPED
                   13623: #
                   13624: asnp1: subl2   r6,r10          # restore base pointer
                   13625:        movl    pmssl,-(sp)     # stack subject string length
                   13626:        movl    pmhbs,-(sp)     # stack history stack base ptr
                   13627:        movl    r$pms,-(sp)     # stack subject string pointer
                   13628:        movl    pmdfl,-(sp)     # stack dot flag
                   13629:        jsb     asign           # call full-blown assignment routine
                   13630:        .long   asnp2           # jump if failure
                   13631:        movl    (sp)+,pmdfl     # restore dot flag
                   13632:        movl    (sp)+,r$pms     # restore subject string pointer
                   13633:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   13634:        movl    (sp)+,pmssl     # restore subject string length
                   13635:        addl2   $4*1,(sp)       # return to asinp caller
                   13636:        rsb     
                   13637: #
                   13638: #      HERE IF FAILURE IN ASIGN CALL
                   13639: #
                   13640: asnp2: movl    (sp)+,pmdfl     # restore dot flag
                   13641:        movl    (sp)+,r$pms     # restore subject string pointer
                   13642:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   13643:        movl    (sp)+,pmssl     # restore subject string length
                   13644:        movl    (sp)+,r11       # take failure exit
                   13645:        jmp     *(r11)+
                   13646:        #enp                    # end procedure asinp
                   13647:        #page   
                   13648: #
                   13649: #      BLKLN -- DETERMINE LENGTH OF BLOCK
                   13650: #
                   13651: #      BLKLN DETERMINES THE LENGTH OF A BLOCK IN DYNAMIC STORE.
                   13652: #
                   13653: #      (WA)                  FIRST WORD OF BLOCK
                   13654: #      (XR)                  POINTER TO BLOCK
                   13655: #      JSR  BLKLN            CALL TO GET BLOCK LENGTH
                   13656: #      (WA)                  LENGTH OF BLOCK IN BYTES
                   13657: #      (XL)                  DESTROYED
                   13658: #
                   13659: #      BLKLN IS USED BY THE GARBAGE COLLECTOR AND IS NOT
                   13660: #      PERMITTED TO CALL GBCOL DIRECTLY OR INDIRECTLY.
                   13661: #
                   13662: #      THE FIRST WORD STORED IN THE BLOCK (I.E. AT XR) MAY
                   13663: #      BE ANYTHING, BUT THE CONTENTS OF WA MUST BE CORRECT.
                   13664: #
                   13665: blkln: #prc                    # entry point
                   13666:        movl    r6,r10          # copy first word
                   13667:        movzwl  -2(r10),r10     # get entry id (bl$xx)
                   13668:        casel   r10,$0,$bl$$$   # switch on block type
                   13669: 5:             
                   13670:        .word   bln01-5b        # arblk
                   13671:        .word   bln04-5b        # bcblk
                   13672:        .word   bln01-5b        # cdblk
                   13673:        .word   bln01-5b        # exblk
                   13674:        .word   bln07-5b        # icblk
                   13675:        .word   bln03-5b        # nmblk
                   13676:        .word   bln02-5b        # p0blk
                   13677:        .word   bln03-5b        # p1blk
                   13678:        .word   bln04-5b        # p2blk
                   13679:        .word   bln09-5b        # rcblk
                   13680:        .word   bln10-5b        # scblk
                   13681:        .word   bln02-5b        # seblk
                   13682:        .word   bln01-5b        # tbblk
                   13683:        .word   bln01-5b        # vcblk
                   13684:        .word   bln00-5b
                   13685:        .word   bln00-5b
                   13686:        .word   bln08-5b        # pdblk
                   13687:        .word   bln05-5b        # trblk
                   13688:        .word   bln11-5b        # bfblk
                   13689:        .word   bln00-5b
                   13690:        .word   bln00-5b
                   13691:        .word   bln06-5b        # ctblk
                   13692:        .word   bln01-5b        # dfblk
                   13693:        .word   bln01-5b        # efblk
                   13694:        .word   bln03-5b        # evblk
                   13695:        .word   bln05-5b        # ffblk
                   13696:        .word   bln03-5b        # kvblk
                   13697:        .word   bln01-5b        # pfblk
                   13698:        .word   bln04-5b        # teblk
                   13699:        #esw                    # end of jump table on block type
                   13700:        #page   
                   13701: #
                   13702: #      BLKLN (CONTINUED)
                   13703: #
                   13704: #      HERE FOR BLOCKS WITH LENGTH IN SECOND WORD
                   13705: #
                   13706: bln00: movl    4*1(r9),r6      # load length
                   13707:        rsb                     # return to blkln caller
                   13708: #
                   13709: #      HERE FOR LENGTH IN THIRD WORD (AR,CD,DF,EF,EX,PF,TB,VC)
                   13710: #
                   13711: bln01: movl    4*2(r9),r6      # load length from third word
                   13712:        rsb                     # return to blkln caller
                   13713: #
                   13714: #      HERE FOR TWO WORD BLOCKS (P0,SE)
                   13715: #
                   13716: bln02: movl    $4*num02,r6     # load length (two words)
                   13717:        rsb                     # return to blkln caller
                   13718: #
                   13719: #      HERE FOR THREE WORD BLOCKS (NM,P1,EV,KV)
                   13720: #
                   13721: bln03: movl    $4*num03,r6     # load length (three words)
                   13722:        rsb                     # return to blkln caller
                   13723: #
                   13724: #      HERE FOR FOUR WORD BLOCKS (P2,TE,BC)
                   13725: #
                   13726: bln04: movl    $4*num04,r6     # load length (four words)
                   13727:        rsb                     # return to blkln caller
                   13728: #
                   13729: #      HERE FOR FIVE WORD BLOCKS (FF,TR)
                   13730: #
                   13731: bln05: movl    $4*num05,r6     # load length
                   13732:        rsb                     # return to blkln caller
                   13733:        #page   
                   13734: #
                   13735: #      BLKLN (CONTINUED)
                   13736: #
                   13737: #      HERE FOR CTBLK
                   13738: #
                   13739: bln06: movl    $4*ctsi$,r6     # set size of ctblk
                   13740:        rsb                     # return to blkln caller
                   13741: #
                   13742: #      HERE FOR ICBLK
                   13743: #
                   13744: bln07: movl    $4*icsi$,r6     # set size of icblk
                   13745:        rsb                     # return to blkln caller
                   13746: #
                   13747: #      HERE FOR PDBLK
                   13748: #
                   13749: bln08: movl    4*pddfp(r9),r10 # point to dfblk
                   13750:        movl    4*dfpdl(r10),r6 # load pdblk length from dfblk
                   13751:        rsb                     # return to blkln caller
                   13752: #
                   13753: #      HERE FOR RCBLK
                   13754: #
                   13755: bln09: movl    $4*rcsi$,r6     # set size of rcblk
                   13756:        rsb                     # return to blkln caller
                   13757: #
                   13758: #      HERE FOR SCBLK
                   13759: #
                   13760: bln10: movl    4*sclen(r9),r6  # load length in characters
                   13761:        movab   3+(4*scsi$)(r6),r6 # calculate length in bytes
                   13762:        bicl2   $3,r6
                   13763:        rsb                     # return to blkln caller
                   13764: #
                   13765: #      HERE FOR BFBLK
                   13766: #
                   13767: bln11: movl    4*bfalc(r9),r6  # get allocation in bytes
                   13768:        movab   3+(4*bfsi$)(r6),r6 # calculate length in bytes
                   13769:        bicl2   $3,r6
                   13770:        rsb                     # return to blkln caller
                   13771:        #enp                    # end procedure blkln
                   13772:        #page   
                   13773: #
                   13774: #      COPYB -- COPY A BLOCK
                   13775: #
                   13776: #      (XS)                  BLOCK TO BE COPIED
                   13777: #      JSR  COPYB            CALL TO COPY BLOCK
                   13778: #      PPM  LOC              RETURN IF BLOCK HAS NO IDVAL FIELD
                   13779: #                            NORMAL RETURN IF IDVAL FIELD
                   13780: #      (XR)                  COPY OF BLOCK
                   13781: #      (XS)                  POPPED
                   13782: #      (XL,WA,WB,WC)         DESTROYED
                   13783: #
                   13784:        .data   1
                   13785: copyb_s:       .long   0
                   13786:        .text   0
                   13787: copyb: movl    (sp)+,copyb_s   # entry point
                   13788:        movl    (sp),r9         # load argument
                   13789:        cmpl    r9,$nulls       # return argument if it is null
                   13790:        bnequ   0f
                   13791:        jmp     cop10
                   13792: 0:             
                   13793:        movl    (r9),r6         # else load type word
                   13794:        movl    r6,r7           # copy type word
                   13795:        jsb     blkln           # get length of argument block
                   13796:        movl    r9,r10          # copy pointer
                   13797:        jsb     alloc           # allocate block of same size
                   13798:        movl    r9,(sp)         # store pointer to copy
                   13799:        jsb     sbmvw           # copy contents of old block to new
                   13800:        movl    (sp),r9         # reload pointer to start of copy
                   13801:        cmpl    r7,$b$tbt       # jump if table
                   13802:        beqlu   cop05
                   13803:        cmpl    r7,$b$vct       # jump if vector
                   13804:        beqlu   cop01
                   13805:        cmpl    r7,$b$pdt       # jump if program defined
                   13806:        beqlu   cop01
                   13807:        cmpl    r7,$b$bct       # jump if buffer
                   13808:        bnequ   0f
                   13809:        jmp     cop11
                   13810: 0:             
                   13811:        cmpl    r7,$b$art       # return copy if not array
                   13812:        beqlu   0f
                   13813:        jmp     cop10
                   13814: 0:             
                   13815: #
                   13816: #      HERE FOR ARRAY (ARBLK)
                   13817: #
                   13818:        addl2   4*arofs(r9),r9  # point to prototype field
                   13819:        jmp     cop02           # jump to merge
                   13820: #
                   13821: #      HERE FOR VECTOR, PROGRAM DEFINED
                   13822: #
                   13823: cop01: addl2   $4*pdfld,r9     # point to pdfld = vcvls
                   13824: #
                   13825: #      MERGE HERE FOR ARBLK, VCBLK, PDBLK TO DELETE TRAP
                   13826: #      BLOCKS FROM ALL VALUE FIELDS (THE COPY IS UNTRAPPED)
                   13827: #
                   13828: cop02: movl    (r9),r10        # load next pointer
                   13829: #
                   13830: #      LOOP TO GET VALUE AT END OF TRBLK CHAIN
                   13831: #
                   13832: cop03: cmpl    (r10),$b$trt    # jump if not trapped
                   13833:        bnequ   cop04
                   13834:        movl    4*trval(r10),r10# else point to next value
                   13835:        jmp     cop03           # and loop back
                   13836:        #page   
                   13837: #
                   13838: #      COPYB (CONTINUED)
                   13839: #
                   13840: #      HERE WITH UNTRAPPED VALUE IN XL
                   13841: #
                   13842: cop04: movl    r10,(r9)+       # store real value, bump pointer
                   13843:        cmpl    r9,dnamp        # loop back if more to go
                   13844:        bnequ   cop02
                   13845:        jmp     cop09           # else jump to exit
                   13846: #
                   13847: #      HERE TO COPY A TABLE
                   13848: #
                   13849: cop05: clrl    4*idval(r9)     # zero id to stop dump blowing up
                   13850:        movl    $4*tesi$,r6     # set size of teblk
                   13851:        movl    $4*tbbuk,r8     # set initial offset
                   13852: #
                   13853: #      LOOP THROUGH BUCKETS IN TABLE
                   13854: #
                   13855: cop06: movl    (sp),r9         # load table pointer
                   13856:        cmpl    r8,4*tblen(r9)  # jump to exit if all done
                   13857:        beqlu   cop09
                   13858:        addl2   r8,r9           # else point to next bucket header
                   13859:        addl2   $4,r8           # bump offset
                   13860:        subl2   $4*tenxt,r9     # subtract link offset to merge
                   13861: #
                   13862: #      LOOP THROUGH TEBLKS ON ONE CHAIN
                   13863: #
                   13864: cop07: movl    4*tenxt(r9),r10 # load pointer to next teblk
                   13865:        movl    (sp),4*tenxt(r9)# set end of chain pointer in case
                   13866:        cmpl    (r10),$b$tbt    # back for next bucket if chain end
                   13867:        beqlu   cop06
                   13868:        movl    r9,-(sp)        # else stack ptr to previous block
                   13869:        movl    $4*tesi$,r6     # set size of teblk
                   13870:        jsb     alloc           # allocate new teblk
                   13871:        movl    r9,r7           # save ptr to new teblk
                   13872:        jsb     sbmvw           # copy old teblk to new teblk
                   13873:        movl    r7,r9           # restore pointer to new teblk
                   13874:        movl    (sp)+,r10       # restore pointer to previous block
                   13875:        movl    r9,4*tenxt(r10) # link new block to previous
                   13876:        movl    r9,r10          # copy pointer to new block
                   13877: #
                   13878: #      LOOP TO SET REAL VALUE AFTER REMOVING TRAP CHAIN
                   13879: #
                   13880: cop08: movl    4*teval(r10),r10# load value
                   13881:        cmpl    (r10),$b$trt    # loop back if trapped
                   13882:        beqlu   cop08
                   13883:        movl    r10,4*teval(r9) # store untrapped value in teblk
                   13884:        jmp     cop07           # back for next teblk
                   13885: #
                   13886: #      COMMON EXIT POINT
                   13887: #
                   13888: cop09: movl    (sp)+,r9        # load pointer to block
                   13889:        addl3   $4*1,copyb_s,r11        # return
                   13890:        jmp     (r11)
                   13891: #
                   13892: #      ALTERNATIVE RETURN
                   13893: #
                   13894: cop10: movl    copyb_s,r11     # return
                   13895:        jmp     *(r11)+
                   13896:        #page   
                   13897: #
                   13898: #      HERE TO COPY BUFFER
                   13899: #
                   13900: cop11: movl    4*bcbuf(r9),r10 # get bfblk ptr
                   13901:        movl    4*bfalc(r10),r6 # get allocation
                   13902:        movab   3+(4*bfsi$)(r6),r6 # set total size
                   13903:        bicl2   $3,r6
                   13904:        movl    r9,r10          # save bcblk ptr
                   13905:        jsb     alloc           # allocate bfblk
                   13906:        movl    4*bcbuf(r10),r7 # get old bfblk
                   13907:        movl    r9,4*bcbuf(r10) # set pointer to new bfblk
                   13908:        movl    r7,r10          # point to old bfblk
                   13909:        jsb     sbmvw           # copy bfblk too
                   13910:        clrl    r10             # clear rubbish ptr
                   13911:        jmp     cop09           # branch to exit
                   13912:        #enp                    # end procedure copyb
                   13913: #
                   13914: #      CDGCG -- GENERATE CODE FOR COMPLEX GOTO
                   13915: #
                   13916: #      USED BY CMPIL TO PROCESS COMPLEX GOTO TREE
                   13917: #
                   13918: #      (WB)                  MUST BE COLLECTABLE
                   13919: #      (XR)                  EXPRESSION POINTER
                   13920: #      JSR  CDGCG            CALL TO GENERATE COMPLEX GOTO
                   13921: #      (XL,XR,WA)            DESTROYED
                   13922: #
                   13923: cdgcg: #prc                    # entry point
                   13924:        movl    4*cmopn(r9),r10 # get unary goto operator
                   13925:        movl    4*cmrop(r9),r9  # point to goto operand
                   13926:        cmpl    r10,$opdvd      # jump if direct goto
                   13927:        beqlu   cdgc2
                   13928:        jsb     cdgnm           # generate opnd by name if not direct
                   13929: #
                   13930: #      RETURN POINT
                   13931: #
                   13932: cdgc1: movl    r10,r6          # goto operator
                   13933:        jsb     cdwrd           # generate it
                   13934:        rsb                     # return to caller
                   13935: #
                   13936: #      DIRECT GOTO
                   13937: #
                   13938: cdgc2: jsb     cdgvl           # generate operand by value
                   13939:        jmp     cdgc1           # merge to return
                   13940:        #enp                    # end procedure cdgcg
                   13941:        #page   
                   13942: #
                   13943: #      CDGEX -- BUILD EXPRESSION BLOCK
                   13944: #
                   13945: #      CDGEX IS PASSED A POINTER TO AN EXPRESSION TREE (SEE
                   13946: #      EXPAN) AND RETURNS AN EXPRESSION (SEBLK OR EXBLK).
                   13947: #
                   13948: #      (WC)                  SOME COLLECTABLE VALUE
                   13949: #      (WB)                  INTEGER IN RANGE 0 LE X LE MXLEN
                   13950: #      (XL)                  PTR TO EXPRESSION TREE
                   13951: #      JSR  CDGEX            CALL TO BUILD EXPRESSION
                   13952: #      (XR)                  PTR TO SEBLK OR EXBLK
                   13953: #      (XL,WA,WB)            DESTROYED
                   13954: #
                   13955: cdgex: #prc                    # entry point, recursive
                   13956:        cmpl    (r10),$b$vr$    # jump if not variable
                   13957:        blequ   cdgx1
                   13958: #
                   13959: #      HERE FOR NATURAL VARIABLE, BUILD SEBLK
                   13960: #
                   13961:        movl    $4*sesi$,r6     # set size of seblk
                   13962:        jsb     alloc           # allocate space for seblk
                   13963:        movl    $b$sel,(r9)     # set type word
                   13964:        movl    r10,4*sevar(r9) # store vrblk pointer
                   13965:        rsb                     # return to cdgex caller
                   13966: #
                   13967: #      HERE IF NOT VARIABLE, BUILD EXBLK
                   13968: #
                   13969: cdgx1: movl    r10,r9          # copy tree pointer
                   13970:        movl    r8,-(sp)        # save wc
                   13971:        movl    cwcof,r10       # save current offset
                   13972:        movl    (r9),r6         # get type word
                   13973:        cmpl    r6,$b$cmt       # call by value if not cmblk
                   13974:        bnequ   cdgx2
                   13975:        cmpl    4*cmtyp(r9),$c$$nm # jump if cmblk only by value
                   13976:        bgequ   cdgx2
                   13977:        #page   
                   13978: #
                   13979: #      CDGEX (CONTINUED)
                   13980: #
                   13981: #      HERE IF EXPRESSION CAN BE EVALUATED BY NAME
                   13982: #
                   13983:        jsb     cdgnm           # generate code by name
                   13984:        movl    $ornm$,r6       # load return by name word
                   13985:        jmp     cdgx3           # merge with value case
                   13986: #
                   13987: #      HERE IF EXPRESSION CAN ONLY BE EVALUATED BY VALUE
                   13988: #
                   13989: cdgx2: jsb     cdgvl           # generate code by value
                   13990:        movl    $orvl$,r6       # load return by value word
                   13991: #
                   13992: #      MERGE HERE TO CONSTRUCT EXBLK
                   13993: #
                   13994: cdgx3: jsb     cdwrd           # generate return word
                   13995:        jsb     exbld           # build exblk
                   13996:        movl    (sp)+,r8        # restore wc
                   13997:        rsb                     # return to cdgex caller
                   13998:        #enp                    # end procedure cdgex
                   13999:        #page   
                   14000: #
                   14001: #      CDGNM -- GENERATE CODE BY NAME
                   14002: #
                   14003: #      CDGNM IS CALLED DURING THE COMPILATION PROCESS TO
                   14004: #      GENERATE CODE BY NAME FOR AN EXPRESSION. SEE CDBLK
                   14005: #      DESCRIPTION FOR DETAILS OF CODE GENERATED. THE INPUT
                   14006: #      TO CDGNM IS AN EXPRESSION TREE AS GENERATED BY EXPAN.
                   14007: #
                   14008: #      CDGNM IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING
                   14009: #      RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS.
                   14010: #
                   14011: #      (WB)                  INTEGER IN RANGE 0 LE N LE DNAMB
                   14012: #      (XR)                  PTR TO TREE GENERATED BY EXPAN
                   14013: #      (WC)                  CONSTANT FLAG (SEE BELOW)
                   14014: #      JSR  CDGNM            CALL TO GENERATE CODE BY NAME
                   14015: #      (XR,WA)               DESTROYED
                   14016: #      (WC)                  SET NON-ZERO IF NON-CONSTANT
                   14017: #
                   14018: #      WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE
                   14019: #      EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE
                   14020: #      EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED.
                   14021: #
                   14022: #      THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD).
                   14023: #
                   14024: cdgnm: #prc                    # entry point, recursive
                   14025:        movl    r10,-(sp)       # save entry xl
                   14026:        movl    r7,-(sp)        # save entry wb
                   14027:        jsb     sbchk           # check for stack overflow
                   14028:        movl    (r9),r6         # load type word
                   14029:        cmpl    r6,$b$cmt       # jump if cmblk
                   14030:        beqlu   cgn04
                   14031:        cmpl    r6,$b$vr$       # jump if simple variable
                   14032:        blssu   0f
                   14033:        jmp     cgn02
                   14034: 0:             
                   14035: #
                   14036: #      MERGE HERE FOR OPERAND YIELDING VALUE (E.G. CONSTANT)
                   14037: #
                   14038: cgn01: jmp     er_212          # syntax error. value used where name is required
                   14039: #
                   14040: #      HERE FOR NATURAL VARIABLE REFERENCE
                   14041: #
                   14042: cgn02: movl    $olvn$,r6       # load variable load call
                   14043:        jsb     cdwrd           # generate it
                   14044:        movl    r9,r6           # copy vrblk pointer
                   14045:        jsb     cdwrd           # generate vrblk pointer
                   14046:        #page   
                   14047: #
                   14048: #      CDGNM (CONTINUED)
                   14049: #
                   14050: #      HERE TO EXIT WITH WC SET CORRECTLY
                   14051: #
                   14052: cgn03: movl    (sp)+,r7        # restore entry wb
                   14053:        movl    (sp)+,r10       # restore entry xl
                   14054:        rsb                     # return to cdgnm caller
                   14055: #
                   14056: #      HERE FOR CMBLK
                   14057: #
                   14058: cgn04: movl    r9,r10          # copy cmblk pointer
                   14059:        movl    4*cmtyp(r9),r9  # load cmblk type
                   14060:        cmpl    r9,$c$$nm       # error if not name operand
                   14061:        bgequ   cgn01
                   14062:        casel   r9,$0,$c$$nm    # else switch on type
                   14063: 5:             
                   14064:        .word   cgn05-5b        # array reference
                   14065:        .word   cgn08-5b        # function call
                   14066:        .word   cgn09-5b        # deferred expression
                   14067:        .word   cgn10-5b        # indirect reference
                   14068:        .word   cgn11-5b        # keyword reference
                   14069:        .word   cgn08-5b        # undefined binary op
                   14070:        .word   cgn08-5b        # undefined unary op
                   14071:        #esw                    # end switch on cmblk type
                   14072: #
                   14073: #      HERE TO GENERATE CODE FOR ARRAY REFERENCE
                   14074: #
                   14075: cgn05: movl    $4*cmopn,r7     # point to array operand
                   14076: #
                   14077: #      LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS
                   14078: #
                   14079: cgn06: jsb     cmgen           # generate code for next operand
                   14080:        movl    4*cmlen(r10),r8 # load length of cmblk
                   14081:        cmpl    r7,r8           # loop till all generated
                   14082:        blssu   cgn06
                   14083: #
                   14084: #      GENERATE APPROPRIATE ARRAY CALL
                   14085: #
                   14086:        movl    $oaon$,r6       # load one-subscript case call
                   14087:        cmpl    r8,$4*cmar1     # jump to exit if one subscript case
                   14088:        beqlu   cgn07
                   14089:        movl    $oamn$,r6       # else load multi-subscript case call
                   14090:        jsb     cdwrd           # generate call
                   14091:        movl    r8,r6           # copy cmblk length
                   14092:        ashl    $-2,r6,r6       # convert to words
                   14093:        subl2   $cmvls,r6       # calculate number of subscripts
                   14094:        #page   
                   14095: #
                   14096: #      CDGNM (CONTINUED)
                   14097: #
                   14098: #      HERE TO EXIT GENERATING WORD (NON-CONSTANT)
                   14099: #
                   14100: cgn07: movl    sp,r8           # set result non-constant
                   14101:        jsb     cdwrd           # generate word
                   14102:        jmp     cgn03           # back to exit
                   14103: #
                   14104: #      HERE TO GENERATE CODE FOR FUNCTIONS AND UNDEFINED OPRS
                   14105: #
                   14106: cgn08: movl    r10,r9          # copy cmblk pointer
                   14107:        jsb     cdgvl           # gen code by value for call
                   14108:        movl    $ofne$,r6       # get extra call for by name
                   14109:        jmp     cgn07           # back to generate and exit
                   14110: #
                   14111: #      HERE TO GENERATE CODE FOR DEFERED EXPRESSION
                   14112: #
                   14113: cgn09: movl    4*cmrop(r10),r9 # check if variable
                   14114:        cmpl    (r9),$b$vr$     # treat *variable as simple var
                   14115:        blssu   0f
                   14116:        jmp     cgn02
                   14117: 0:             
                   14118:        movl    r9,r10          # copy ptr to expression tree
                   14119:        jsb     cdgex           # else build exblk
                   14120:        movl    $olex$,r6       # set call to load expr by name
                   14121:        jsb     cdwrd           # generate it
                   14122:        movl    r9,r6           # copy exblk pointer
                   14123:        jsb     cdwrd           # generate exblk pointer
                   14124:        jmp     cgn03           # back to exit
                   14125: #
                   14126: #      HERE TO GENERATE CODE FOR INDIRECT REFERENCE
                   14127: #
                   14128: cgn10: movl    4*cmrop(r10),r9 # get operand
                   14129:        jsb     cdgvl           # generate code by value for it
                   14130:        movl    $oinn$,r6       # load call for indirect by name
                   14131:        jmp     cgn12           # merge
                   14132: #
                   14133: #      HERE TO GENERATE CODE FOR KEYWORD REFERENCE
                   14134: #
                   14135: cgn11: movl    4*cmrop(r10),r9 # get operand
                   14136:        jsb     cdgnm           # generate code by name for it
                   14137:        movl    $okwn$,r6       # load call for keyword by name
                   14138: #
                   14139: #      KEYWORD, INDIRECT MERGE HERE
                   14140: #
                   14141: cgn12: jsb     cdwrd           # generate code for operator
                   14142:        jmp     cgn03           # exit
                   14143:        #enp                    # end procedure cdgnm
                   14144:        #page   
                   14145: #
                   14146: #      CDGVL -- GENERATE CODE BY VALUE
                   14147: #
                   14148: #      CDGVL IS CALLED DURING THE COMPILATION PROCESS TO
                   14149: #      GENERATE CODE BY VALUE FOR AN EXPRESSION. SEE CDBLK
                   14150: #      DESCRIPTION FOR DETAILS OF THE CODE GENERATED. THE INPUT
                   14151: #      TO CDGVL IS AN EXPRESSION TREE AS GENERATED BY EXPAN.
                   14152: #
                   14153: #      CDGVL IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING
                   14154: #      RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS.
                   14155: #
                   14156: #      (WB)                  INTEGER IN RANGE 0 LE N LE DNAMB
                   14157: #      (XR)                  PTR TO TREE GENERATED BY EXPAN
                   14158: #      (WC)                  CONSTANT FLAG (SEE BELOW)
                   14159: #      JSR  CDGVL            CALL TO GENERATE CODE BY VALUE
                   14160: #      (XR,WA)               DESTROYED
                   14161: #      (WC)                  SET NON-ZERO IF NON-CONSTANT
                   14162: #
                   14163: #      WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE
                   14164: #      EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE
                   14165: #      EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED.
                   14166: #
                   14167: #      IF WC IS NON-ZERO ON ENTRY, THEN PREEVALUATION IS NOT
                   14168: #      ALLOWED REGARDLESS OF THE NATURE OF THE OPERAND.
                   14169: #
                   14170: #      THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD).
                   14171: #
                   14172: cdgvl: #prc                    # entry point, recursive
                   14173:        movl    (r9),r6         # load type word
                   14174:        cmpl    r6,$b$cmt       # jump if cmblk
                   14175:        beqlu   cgv01
                   14176:        cmpl    r6,$b$vra       # jump if icblk, rcblk, scblk
                   14177:        blssu   cgv00
                   14178:        tstl    4*vrlen(r9)     # jump if not system variable
                   14179:        bnequ   cgvl0
                   14180:        movl    r9,-(sp)        # stack xr
                   14181:        movl    4*vrsvp(r9),r9  # point to svblk
                   14182:        movl    4*svbit(r9),r6  # get svblk property bits
                   14183:        movl    (sp)+,r9        # recover xr
                   14184:        mcoml   btckw,r11       # check if constant keyword
                   14185:        bicl2   r11,r6
                   14186:        tstl    r6              # jump if constant keyword
                   14187:        bnequ   cgv00
                   14188: #
                   14189: #      HERE FOR VARIABLE VALUE REFERENCE
                   14190: #
                   14191: cgvl0: movl    sp,r8           # indicate non-constant value
                   14192: #
                   14193: #      MERGE HERE FOR SIMPLE CONSTANT (ICBLK,RCBLK,SCBLK)
                   14194: #      AND FOR VARIABLES CORRESPONDING TO CONSTANT KEYWORDS.
                   14195: #
                   14196: cgv00: movl    r9,r6           # copy ptr to var or constant
                   14197:        jsb     cdwrd           # generate as code word
                   14198:        rsb                     # return to caller
                   14199:        #page   
                   14200: #
                   14201: #      CDGVL (CONTINUED)
                   14202: #
                   14203: #      HERE FOR TREE NODE (CMBLK)
                   14204: #
                   14205: cgv01: movl    r7,-(sp)        # save entry wb
                   14206:        movl    r10,-(sp)       # save entry xl
                   14207:        movl    r8,-(sp)        # save entry constant flag
                   14208:        movl    cwcof,-(sp)     # save initial code offset
                   14209:        jsb     sbchk           # check for stack overflow
                   14210: #
                   14211: #      PREPARE TO GENERATE CODE FOR CMBLK. WC IS SET TO THE
                   14212: #      VALUE OF CSWNO (ZERO IF -OPTIMISE, 1 IF -NOOPT) TO
                   14213: #      START WITH AND IS RESET NON-ZERO FOR ANY NON-CONSTANT
                   14214: #      CODE GENERATED. IF IT IS STILL ZERO AFTER GENERATING ALL
                   14215: #      THE CMBLK CODE, THEN ITS VALUE IS COMPUTED AS THE RESULT.
                   14216: #
                   14217:        movl    r9,r10          # copy cmblk pointer
                   14218:        movl    4*cmtyp(r9),r9  # load cmblk type
                   14219:        movl    cswno,r8        # reset constant flag
                   14220:        cmpl    r9,$c$pr$       # jump if not predicate value
                   14221:        blequ   cgv02
                   14222:        movl    sp,r8           # else force non-constant case
                   14223: #
                   14224: #      HERE WITH WC SET APPROPRIATELY
                   14225: #
                   14226: cgv02: casel   r9,$0,$c$$nv    # switch to appropriate generator
                   14227: 5:             
                   14228:        .word   cgv03-5b        # array reference
                   14229:        .word   cgv05-5b        # function call
                   14230:        .word   cgv14-5b        # deferred expression
                   14231:        .word   cgv31-5b        # indirect reference
                   14232:        .word   cgv27-5b        # keyword reference
                   14233:        .word   cgv29-5b        # undefined binop
                   14234:        .word   cgv30-5b        # undefined unop
                   14235:        .word   cgv18-5b        # binops with val opds
                   14236:        .word   cgv19-5b        # unops with valu opnd
                   14237:        .word   cgv18-5b        # alternation
                   14238:        .word   cgv24-5b        # concatenation
                   14239:        .word   cgv24-5b        # concatenation (not pattern match)
                   14240:        .word   cgv27-5b        # unops with name opnd
                   14241:        .word   cgv26-5b        # binary $ and .
                   14242:        .word   cgv21-5b        # assignment
                   14243:        .word   cgv31-5b        # interrogation
                   14244:        .word   cgv28-5b        # negation
                   14245:        .word   cgv15-5b        # selection
                   14246:        .word   cgv18-5b        # pattern match
                   14247:        #esw                    # end switch on cmblk type
                   14248:        #page   
                   14249: #
                   14250: #      CDGVL (CONTINUED)
                   14251: #
                   14252: #      HERE TO GENERATE CODE FOR ARRAY REFERENCE
                   14253: #
                   14254: cgv03: movl    $4*cmopn,r7     # set offset to array operand
                   14255: #
                   14256: #      LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS
                   14257: #
                   14258: cgv04: jsb     cmgen           # gen value code for next operand
                   14259:        movl    4*cmlen(r10),r8 # load cmblk length
                   14260:        cmpl    r7,r8           # loop back if more to go
                   14261:        blssu   cgv04
                   14262: #
                   14263: #      GENERATE CALL TO APPROPRIATE ARRAY REFERENCE ROUTINE
                   14264: #
                   14265:        movl    $oaov$,r6       # set one subscript call in case
                   14266:        cmpl    r8,$4*cmar1     # jump to exit if 1-sub case
                   14267:        bnequ   0f
                   14268:        jmp     cgv32
                   14269: 0:             
                   14270:        movl    $oamv$,r6       # else set call for multi-subscripts
                   14271:        jsb     cdwrd           # generate call
                   14272:        movl    r8,r6           # copy length of cmblk
                   14273:        subl2   $4*cmvls,r6     # subtract standard length
                   14274:        ashl    $-2,r6,r6       # get number of words
                   14275:        jmp     cgv32           # jump to generate subscript count
                   14276: #
                   14277: #      HERE TO GENERATE CODE FOR FUNCTION CALL
                   14278: #
                   14279: cgv05: movl    $4*cmvls,r7     # set offset to first argument
                   14280: #
                   14281: #      LOOP TO GENERATE CODE FOR ARGUMENTS
                   14282: #
                   14283: cgv06: cmpl    r7,4*cmlen(r10) # jump if all generated
                   14284:        beqlu   cgv07
                   14285:        jsb     cmgen           # else gen value code for next arg
                   14286:        jmp     cgv06           # back to generate next argument
                   14287: #
                   14288: #      HERE TO GENERATE ACTUAL FUNCTION CALL
                   14289: #
                   14290: cgv07: subl2   $4*cmvls,r7     # get number of arg ptrs (bytes)
                   14291:        ashl    $-2,r7,r7       # convert bytes to words
                   14292:        movl    4*cmopn(r10),r9 # load function vrblk pointer
                   14293:        tstl    4*vrlen(r9)     # jump if not system function
                   14294:        bnequ   cgv12
                   14295:        movl    4*vrsvp(r9),r10 # load svblk ptr if system var
                   14296:        movl    4*svbit(r10),r6 # load bit mask
                   14297:        mcoml   btffc,r11       # test for fast function call allowed
                   14298:        bicl2   r11,r6
                   14299:        tstl    r6              # jump if not
                   14300:        beqlu   cgv12
                   14301:        #page   
                   14302: #
                   14303: #      CDGVL (CONTINUED)
                   14304: #
                   14305: #      HERE IF FAST FUNCTION CALL IS ALLOWED
                   14306: #
                   14307:        movl    4*svbit(r10),r6 # reload bit indicators
                   14308:        mcoml   btpre,r11       # test for preevaluation ok
                   14309:        bicl2   r11,r6
                   14310:        tstl    r6              # jump if preevaluation permitted
                   14311:        bnequ   cgv08
                   14312:        movl    sp,r8           # else set result non-constant
                   14313: #
                   14314: #      TEST FOR CORRECT NUMBER OF ARGS FOR FAST CALL
                   14315: #
                   14316: cgv08: movl    4*vrfnc(r9),r10 # load ptr to svfnc field
                   14317:        movl    4*fargs(r10),r6 # load svnar field value
                   14318:        cmpl    r6,r7           # jump if argument count is correct
                   14319:        beqlu   cgv11
                   14320:        cmpl    r6,r7           # jump if too few arguments given
                   14321:        bgequ   cgv09
                   14322: #
                   14323: #      HERE IF TOO MANY ARGUMENTS, PREPARE TO GENERATE O$POPS
                   14324: #
                   14325:        subl2   r6,r7           # get number of extra args
                   14326:                                # set as count to control loop
                   14327:        movl    $opop$,r6       # set pop call
                   14328:        jmp     cgv10           # jump to common loop
                   14329: #
                   14330: #      HERE IF TOO FEW ARGUMENTS, PREPARE TO GENERATE NULLS
                   14331: #
                   14332: cgv09: subl2   r7,r6           # get number of missing arguments
                   14333:        movl    r6,r7           # load as count to control loop
                   14334:        movl    $nulls,r6       # load ptr to null constant
                   14335: #
                   14336: #      LOOP TO GENERATE CALLS TO FIX ARGUMENT COUNT
                   14337: #
                   14338: cgv10: jsb     cdwrd           # generate one call
                   14339:        sobgtr  r7,cgv10        # loop till all generated
                   14340: #
                   14341: #      HERE AFTER ADJUSTING ARG COUNT AS REQUIRED
                   14342: #
                   14343: cgv11: movl    r10,r6          # copy pointer to svfnc field
                   14344:        jmp     cgv36           # jump to generate call
                   14345:        #page   
                   14346: #
                   14347: #      CDGVL (CONTINUED)
                   14348: #
                   14349: #      COME HERE IF FAST CALL IS NOT PERMITTED
                   14350: #
                   14351: cgv12: movl    $ofns$,r6       # set one arg call in case
                   14352:        cmpl    r7,$num01       # jump if one arg case
                   14353:        beqlu   cgv13
                   14354:        movl    $ofnc$,r6       # else load call for more than 1 arg
                   14355:        jsb     cdwrd           # generate it
                   14356:        movl    r7,r6           # copy argument count
                   14357: #
                   14358: #      ONE ARG CASE MERGES HERE
                   14359: #
                   14360: cgv13: jsb     cdwrd           # generate =o$fns or arg count
                   14361:        movl    r9,r6           # copy vrblk pointer
                   14362:        jmp     cgv32           # jump to generate vrblk ptr
                   14363: #
                   14364: #      HERE FOR DEFERRED EXPRESSION
                   14365: #
                   14366: cgv14: movl    4*cmrop(r10),r10# point to expression tree
                   14367:        jsb     cdgex           # build exblk or seblk
                   14368:        movl    r9,r6           # copy block ptr
                   14369:        jsb     cdwrd           # generate ptr to exblk or seblk
                   14370:        jmp     cgv34           # jump to exit, constant test
                   14371: #
                   14372: #      HERE TO GENERATE CODE FOR SELECTION
                   14373: #
                   14374: cgv15: clrl    -(sp)           # zero ptr to chain of forward jumps
                   14375:        clrl    -(sp)           # zero ptr to prev o$slc forward ptr
                   14376:        movl    $4*cmvls,r7     # point to first alternative
                   14377:        movl    $osla$,r6       # set initial code word
                   14378: #
                   14379: #      0(XS)                 IS THE OFFSET TO THE PREVIOUS WORD
                   14380: #                            WHICH REQUIRES FILLING IN WITH AN
                   14381: #                            OFFSET TO THE FOLLOWING O$SLC,O$SLD
                   14382: #
                   14383: #      1(XS)                 IS THE HEAD OF A CHAIN OF OFFSET
                   14384: #                            POINTERS INDICATING THOSE LOCATIONS
                   14385: #                            TO BE FILLED WITH OFFSETS PAST
                   14386: #                            THE END OF ALL THE ALTERNATIVES
                   14387: #
                   14388: cgv16: jsb     cdwrd           # generate o$slc (o$sla first time)
                   14389:        movl    cwcof,(sp)      # set current loc as ptr to fill in
                   14390:        jsb     cdwrd           # generate garbage word there for now
                   14391:        jsb     cmgen           # gen value code for alternative
                   14392:        movl    $oslb$,r6       # load o$slb pointer
                   14393:        jsb     cdwrd           # generate o$slb call
                   14394:        movl    4*1(sp),r6      # load old chain ptr
                   14395:        movl    cwcof,4*1(sp)   # set current loc as new chain head
                   14396:        jsb     cdwrd           # generate forward chain link
                   14397:        #page   
                   14398: #
                   14399: #      CDGVL (CONTINUED)
                   14400: #
                   14401: #      NOW TO FILL IN THE SKIP OFFSET TO O$SLC,O$SLD
                   14402: #
                   14403:        movl    (sp),r9         # load offset to word to plug
                   14404:        addl2   r$ccb,r9        # point to actual location to plug
                   14405:        movl    cwcof,(r9)      # plug proper offset in
                   14406:        movl    $oslc$,r6       # load o$slc ptr for next alternative
                   14407:        movl    r7,r9           # copy offset (destroy garbage xr)
                   14408:        addl2   $4,r9           # bump extra time for test
                   14409:        cmpl    r9,4*cmlen(r10) # loop back if not last alternative
                   14410:        blssu   cgv16
                   14411: #
                   14412: #      HERE TO GENERATE CODE FOR LAST ALTERNATIVE
                   14413: #
                   14414:        movl    $osld$,r6       # get header call
                   14415:        jsb     cdwrd           # generate o$sld call
                   14416:        jsb     cmgen           # generate code for last alternative
                   14417:        addl2   $4,sp           # pop offset ptr
                   14418:        movl    (sp)+,r9        # load chain ptr
                   14419: #
                   14420: #      LOOP TO PLUG OFFSETS PAST STRUCTURE
                   14421: #
                   14422: cgv17: addl2   r$ccb,r9        # make next ptr absolute
                   14423:        movl    (r9),r6         # load forward ptr
                   14424:        movl    cwcof,(r9)      # plug required offset
                   14425:        movl    r6,r9           # copy forward ptr
                   14426:        tstl    r6              # loop back if more to go
                   14427:        bnequ   cgv17
                   14428:        jmp     cgv33           # else jump to exit (not constant)
                   14429: #
                   14430: #      HERE FOR BINARY OPS WITH VALUE OPERANDS
                   14431: #
                   14432: cgv18: movl    4*cmlop(r10),r9 # load left operand pointer
                   14433:        jsb     cdgvl           # gen value code for left operand
                   14434: #
                   14435: #      HERE FOR UNARY OPS WITH VALUE OPERAND (BINOPS MERGE)
                   14436: #
                   14437: cgv19: movl    4*cmrop(r10),r9 # load right (only) operand ptr
                   14438:        jsb     cdgvl           # gen code by value
                   14439:        #page   
                   14440: #
                   14441: #      CDGVL (CONTINUED)
                   14442: #
                   14443: #      MERGE HERE TO GENERATE OPERATOR CALL FROM CMOPN FIELD
                   14444: #
                   14445: cgv20: movl    4*cmopn(r10),r6 # load operator call pointer
                   14446:        jmp     cgv36           # jump to generate it with cons test
                   14447: #
                   14448: #      HERE FOR ASSIGNMENT
                   14449: #
                   14450: cgv21: movl    4*cmlop(r10),r9 # load left operand pointer
                   14451:        cmpl    (r9),$b$vr$     # jump if not variable
                   14452:        blequ   cgv22
                   14453: #
                   14454: #      HERE FOR ASSIGNMENT TO SIMPLE VARIABLE
                   14455: #
                   14456:        movl    4*cmrop(r10),r9 # load right operand ptr
                   14457:        jsb     cdgvl           # generate code by value
                   14458:        movl    4*cmlop(r10),r6 # reload left operand vrblk ptr
                   14459:        addl2   $4*vrsto,r6     # point to vrsto field
                   14460:        jmp     cgv32           # jump to generate store ptr
                   14461: #
                   14462: #      HERE IF NOT SIMPLE VARIABLE ASSIGNMENT
                   14463: #
                   14464: cgv22: jsb     expap           # test for pattern match on left side
                   14465:        .long   cgv23           # jump if not pattern match
                   14466: #
                   14467: #      HERE FOR PATTERN REPLACEMENT
                   14468: #
                   14469:        movl    4*cmrop(r9),4*cmlop(r10) # save pattern ptr in safe place
                   14470:        movl    4*cmlop(r9),r9  # load subject ptr
                   14471:        jsb     cdgnm           # gen code by name for subject
                   14472:        movl    4*cmlop(r10),r9 # load pattern ptr
                   14473:        jsb     cdgvl           # gen code by value for pattern
                   14474:        movl    $opmn$,r6       # load match by name call
                   14475:        jsb     cdwrd           # generate it
                   14476:        movl    4*cmrop(r10),r9 # load replacement value ptr
                   14477:        jsb     cdgvl           # gen code by value
                   14478:        movl    $orpl$,r6       # load replace call
                   14479:        jmp     cgv32           # jump to gen and exit (not constant)
                   14480: #
                   14481: #      HERE FOR ASSIGNMENT TO COMPLEX VARIABLE
                   14482: #
                   14483: cgv23: movl    sp,r8           # inhibit pre-evaluation
                   14484:        jsb     cdgnm           # gen code by name for left side
                   14485:        jmp     cgv31           # merge with unop circuit
                   14486:        #page   
                   14487: #
                   14488: #      CDGVL (CONTINUED)
                   14489: #
                   14490: #      HERE FOR CONCATENATION
                   14491: #
                   14492: cgv24: movl    4*cmlop(r10),r9 # load left operand ptr
                   14493:        cmpl    (r9),$b$cmt     # ordinary binop if not cmblk
                   14494:        beqlu   0f
                   14495:        jmp     cgv18
                   14496: 0:             
                   14497:        movl    4*cmtyp(r9),r7  # load cmblk type code
                   14498:        cmpl    r7,$c$int       # special case if interrogation
                   14499:        beqlu   cgv25
                   14500:        cmpl    r7,$c$neg       # or negation
                   14501:        beqlu   cgv25
                   14502:        cmpl    r7,$c$fnc       # else ordinary binop if not function
                   14503:        beqlu   0f
                   14504:        jmp     cgv18
                   14505: 0:             
                   14506:        movl    4*cmopn(r9),r9  # else load function vrblk ptr
                   14507:        tstl    4*vrlen(r9)     # ordinary binop if not system var
                   14508:        beqlu   0f
                   14509:        jmp     cgv18
                   14510: 0:             
                   14511:        movl    4*vrsvp(r9),r9  # else point to svblk
                   14512:        movl    4*svbit(r9),r6  # load bit indicators
                   14513:        mcoml   btprd,r11       # test for predicate function
                   14514:        bicl2   r11,r6
                   14515:        tstl    r6              # ordinary binop if not
                   14516:        bnequ   0f
                   14517:        jmp     cgv18
                   14518: 0:             
                   14519: #
                   14520: #      HERE IF LEFT ARG OF CONCATENATION IS PREDICATE FUNCTION
                   14521: #
                   14522: cgv25: movl    4*cmlop(r10),r9 # reload left arg
                   14523:        jsb     cdgvl           # gen code by value
                   14524:        movl    $opop$,r6       # load pop call
                   14525:        jsb     cdwrd           # generate it
                   14526:        movl    4*cmrop(r10),r9 # load right operand
                   14527:        jsb     cdgvl           # gen code by value as result code
                   14528:        jmp     cgv33           # exit (not constant)
                   14529: #
                   14530: #      HERE TO GENERATE CODE FOR PATTERN, IMMEDIATE ASSIGNMENT
                   14531: #
                   14532: cgv26: movl    4*cmlop(r10),r9 # load left operand
                   14533:        jsb     cdgvl           # gen code by value, merge
                   14534: #
                   14535: #      HERE FOR UNOPS WITH ARG BY NAME (BINARY $ . MERGE)
                   14536: #
                   14537: cgv27: movl    4*cmrop(r10),r9 # load right operand ptr
                   14538:        jsb     cdgnm           # gen code by name for right arg
                   14539:        movl    4*cmopn(r10),r9 # get operator code word
                   14540:        cmpl    (r9),$o$kwv     # gen call unless keyword value
                   14541:        beqlu   0f
                   14542:        jmp     cgv20
                   14543: 0:             
                   14544:        #page   
                   14545: #
                   14546: #      CDGVL (CONTINUED)
                   14547: #
                   14548: #      HERE FOR KEYWORD BY VALUE. THIS IS CONSTANT ONLY IF
                   14549: #      THE OPERAND IS ONE OF THE SPECIAL SYSTEM VARIABLES WITH
                   14550: #      THE SVCKW BIT SET TO INDICATE A CONSTANT KEYWORD VALUE.
                   14551: #      NOTE THAT THE ONLY CONSTANT OPERAND BY NAME IS A VARIABLE
                   14552: #
                   14553:        tstl    r8              # gen call if non-constant (not var)
                   14554:        beqlu   0f
                   14555:        jmp     cgv20
                   14556: 0:             
                   14557:        movl    sp,r8           # else set non-constant in case
                   14558:        movl    4*cmrop(r10),r9 # load ptr to operand vrblk
                   14559:        tstl    4*vrlen(r9)     # gen (non-constant) if not sys var
                   14560:        beqlu   0f
                   14561:        jmp     cgv20
                   14562: 0:             
                   14563:        movl    4*vrsvp(r9),r9  # else load ptr to svblk
                   14564:        movl    4*svbit(r9),r6  # load bit mask
                   14565:        mcoml   btckw,r11       # test for constant keyword
                   14566:        bicl2   r11,r6
                   14567:        tstl    r6              # go gen if not constant
                   14568:        bnequ   0f
                   14569:        jmp     cgv20
                   14570: 0:             
                   14571:        clrl    r8              # else set result constant
                   14572:        jmp     cgv20           # and jump back to generate call
                   14573: #
                   14574: #      HERE TO GENERATE CODE FOR NEGATION
                   14575: #
                   14576: cgv28: movl    $onta$,r6       # get initial word
                   14577:        jsb     cdwrd           # generate it
                   14578:        movl    cwcof,r7        # save next offset
                   14579:        jsb     cdwrd           # generate gunk word for now
                   14580:        movl    4*cmrop(r10),r9 # load right operand ptr
                   14581:        jsb     cdgvl           # gen code by value
                   14582:        movl    $ontb$,r6       # load end of evaluation call
                   14583:        jsb     cdwrd           # generate it
                   14584:        movl    r7,r9           # copy offset to word to plug
                   14585:        addl2   r$ccb,r9        # point to actual word to plug
                   14586:        movl    cwcof,(r9)      # plug word with current offset
                   14587:        movl    $ontc$,r6       # load final call
                   14588:        jmp     cgv32           # jump to generate it (not constant)
                   14589: #
                   14590: #      HERE TO GENERATE CODE FOR UNDEFINED BINARY OPERATOR
                   14591: #
                   14592: cgv29: movl    4*cmlop(r10),r9 # load left operand ptr
                   14593:        jsb     cdgvl           # generate code by value
                   14594:        #page   
                   14595: #
                   14596: #      CDGVL (CONTINUED)
                   14597: #
                   14598: #      HERE TO GENERATE CODE FOR UNDEFINED UNARY OPERATOR
                   14599: #
                   14600: cgv30: movl    $c$uo$,r7       # set unop code + 1
                   14601:        subl2   4*cmtyp(r10),r7 # set number of args (1 or 2)
                   14602: #
                   14603: #      MERGE HERE FOR UNDEFINED OPERATORS
                   14604: #
                   14605:        movl    4*cmrop(r10),r9 # load right (only) operand pointer
                   14606:        jsb     cdgvl           # gen value code for right operand
                   14607:        movl    4*cmopn(r10),r9 # load pointer to operator dv
                   14608:        movl    4*dvopn(r9),r9  # load pointer offset
                   14609:        moval   0[r9],r9        # convert word offset to bytes
                   14610:        addl2   $r$uba,r9       # point to proper function ptr
                   14611:        subl2   $4*vrfnc,r9     # set standard function offset
                   14612:        jmp     cgv12           # merge with function call circuit
                   14613: #
                   14614: #      HERE TO GENERATE CODE FOR INTERROGATION, INDIRECTION
                   14615: #
                   14616: cgv31: movl    sp,r8           # set non constant
                   14617:        jmp     cgv19           # merge
                   14618: #
                   14619: #      HERE TO EXIT GENERATING A WORD, RESULT NOT CONSTANT
                   14620: #
                   14621: cgv32: jsb     cdwrd           # generate word, merge
                   14622: #
                   14623: #      HERE TO EXIT WITH NO WORD GENERATED, NOT CONSTANT
                   14624: #
                   14625: cgv33: movl    sp,r8           # indicate result is not constant
                   14626: #
                   14627: #      COMMON EXIT POINT
                   14628: #
                   14629: cgv34: addl2   $4,sp           # pop initial code offset
                   14630:        movl    (sp)+,r6        # restore old constant flag
                   14631:        movl    (sp)+,r10       # restore entry xl
                   14632:        movl    (sp)+,r7        # restore entry wb
                   14633:        tstl    r8              # jump if not constant
                   14634:        bnequ   cgv35
                   14635:        movl    r6,r8           # else restore entry constant flag
                   14636: #
                   14637: #      HERE TO RETURN AFTER DEALING WITH WC SETTING
                   14638: #
                   14639: cgv35: rsb                     # return to cdgvl caller
                   14640: #
                   14641: #      EXIT HERE TO GENERATE WORD AND TEST FOR CONSTANT
                   14642: #
                   14643: cgv36: jsb     cdwrd           # generate word
                   14644:        tstl    r8              # jump to exit if not constant
                   14645:        bnequ   cgv34
                   14646:        #page   
                   14647: #
                   14648: #      CDGVL (CONTINUED)
                   14649: #
                   14650: #      HERE TO PREEVALUATE CONSTANT SUB-EXPRESSION
                   14651: #
                   14652:        movl    $orvl$,r6       # load call to return value
                   14653:        jsb     cdwrd           # generate it
                   14654:        movl    (sp),r10        # load initial code offset
                   14655:        jsb     exbld           # build exblk for expression
                   14656:        clrl    r7              # set to evaluate by value
                   14657:        jsb     evalx           # evaluate expression
                   14658:        .long   invalid$        # should not fail
                   14659:        movl    (r9),r6         # load type word of result
                   14660:        cmpl    r6,$p$aaa       # jump if not pattern
                   14661:        blequ   cgv37
                   14662:        movl    $olpt$,r6       # else load special pattern load call
                   14663:        jsb     cdwrd           # generate it
                   14664: #
                   14665: #      MERGE HERE TO GENERATE POINTER TO RESULTING CONSTANT
                   14666: #
                   14667: cgv37: movl    r9,r6           # copy constant pointer
                   14668:        jsb     cdwrd           # generate ptr
                   14669:        clrl    r8              # set result constant
                   14670:        jmp     cgv34           # jump back to exit
                   14671:        #enp                    # end procedure cdgvl
                   14672:        #page   
                   14673: #
                   14674: #      CDWRD -- GENERATE ONE WORD OF CODE
                   14675: #
                   14676: #      CDWRD WRITES ONE WORD INTO THE CURRENT CODE BLOCK UNDER
                   14677: #      CONSTRUCTION. A NEW, LARGER, BLOCK IS ALLOCATED IF THERE
                   14678: #      IS INSUFFICIENT ROOM IN THE CURRENT BLOCK. CDWRD ENSURES
                   14679: #      THAT THERE ARE AT LEAST THREE WORDS LEFT IN THE BLOCK
                   14680: #      AFTER ENTERING THE NEW WORD. THIS GUARANTEES THAT ANY
                   14681: #      EXTRA SPACE AT THE END CAN BE SPLIT OFF AS A CCBLK.
                   14682: #
                   14683: #      (WA)                  WORD TO BE GENERATED
                   14684: #      JSR  CDWRD            CALL TO GENERATE WORD
                   14685: #
                   14686: cdwrd: #prc                    # entry point
                   14687:        movl    r9,-(sp)        # save entry xr
                   14688:        movl    r6,-(sp)        # save code word to be generated
                   14689: #
                   14690: #      MERGE BACK HERE AFTER ALLOCATING LARGER BLOCK
                   14691: #
                   14692: cdwd1: movl    r$ccb,r9        # load ptr to ccblk being built
                   14693:        tstl    r9              # jump if block allocated
                   14694:        bnequ   cdwd2
                   14695: #
                   14696: #      HERE WE ALLOCATE AN ENTIRELY FRESH BLOCK
                   14697: #
                   14698:        movl    $4*e$cbs,r6     # load initial length
                   14699:        jsb     alloc           # allocate ccblk
                   14700:        movl    $b$cct,(r9)     # store type word
                   14701:        movl    $4*cccod,cwcof  # set initial offset
                   14702:        movl    r6,4*cclen(r9)  # store block length
                   14703:        movl    r9,r$ccb        # store ptr to new block
                   14704: #
                   14705: #      HERE WE HAVE A BLOCK WE CAN USE
                   14706: #
                   14707: cdwd2: movl    cwcof,r6        # load current offset
                   14708:        addl2   $4*num04,r6     # adjust for test (four words)
                   14709:        cmpl    r6,4*cclen(r9)  # jump if room in this block
                   14710:        bgtru   0f
                   14711:        jmp     cdwd4
                   14712: 0:             
                   14713: #
                   14714: #      HERE IF NO ROOM IN CURRENT BLOCK
                   14715: #
                   14716:        cmpl    r6,mxlen        # jump if already at max size
                   14717:        blssu   0f
                   14718:        jmp     cdwd5
                   14719: 0:             
                   14720:        addl2   $4*e$cbs,r6     # else get new size
                   14721:        movl    r10,-(sp)       # save entry xl
                   14722:        movl    r9,r10          # copy pointer
                   14723:        cmpl    r6,mxlen        # jump if not too large
                   14724:        blssu   cdwd3
                   14725:        movl    mxlen,r6        # else reset to max allowed size
                   14726:        #page   
                   14727: #
                   14728: #      CDWRD (CONTINUED)
                   14729: #
                   14730: #      HERE WITH NEW BLOCK SIZE IN WA
                   14731: #
                   14732: cdwd3: jsb     alloc           # allocate new block
                   14733:        movl    r9,r$ccb        # store pointer to new block
                   14734:        movl    $b$cct,(r9)+    # store type word in new block
                   14735:        movl    r6,(r9)+        # store block length
                   14736:        addl2   $4*ccuse,r10    # point to ccuse,cccod fields in old
                   14737:        movl    (r10),r6        # load ccuse value
                   14738:        jsb     sbmvw           # copy useful words from old block
                   14739:        movl    (sp)+,r10       # restore xl
                   14740:        jmp     cdwd1           # merge back to try again
                   14741: #
                   14742: #      HERE WITH ROOM IN CURRENT BLOCK
                   14743: #
                   14744: cdwd4: movl    cwcof,r6        # load current offset
                   14745:        addl2   $4,r6           # get new offset
                   14746:        movl    r6,cwcof        # store new offset
                   14747:        movl    r6,4*ccuse(r9)  # store in ccblk for gbcol
                   14748:        subl2   $4,r6           # restore ptr to this word
                   14749:        addl2   r6,r9           # point to current entry
                   14750:        movl    (sp)+,r6        # reload word to generate
                   14751:        movl    r6,(r9)         # store word in block
                   14752:        movl    (sp)+,r9        # restore entry xr
                   14753:        rsb                     # return to caller
                   14754: #
                   14755: #      HERE IF COMPILED CODE IS TOO LONG FOR CDBLK
                   14756: #
                   14757: cdwd5: jmp     er_213          # syntax error. statement is too complicated.
                   14758:        #enp                    # end procedure cdwrd
                   14759:        #page   
                   14760: #
                   14761: #      CMGEN -- GENERATE CODE FOR CMBLK PTR
                   14762: #
                   14763: #      CMGEN IS A SUBSIDIARY PROCEDURE USED TO GENERATE VALUE
                   14764: #      CODE FOR A CMBLK PTR FROM THE MAIN CODE GENERATORS.
                   14765: #
                   14766: #      (XL)                  CMBLK POINTER
                   14767: #      (WB)                  OFFSET TO POINTER IN CMBLK
                   14768: #      JSR  CMGEN            CALL TO GENERATE CODE
                   14769: #      (XR,WA)               DESTROYED
                   14770: #      (WB)                  BUMPED BY ONE WORD
                   14771: #
                   14772: cmgen: #prc                    # entry point, recursive
                   14773:        movl    r10,r9          # copy cmblk pointer
                   14774:        addl2   r7,r9           # point to cmblk pointer
                   14775:        movl    (r9),r9         # load cmblk pointer
                   14776:        jsb     cdgvl           # generate code by value
                   14777:        addl2   $4,r7           # bump offset
                   14778:        rsb                     # return to caller
                   14779:        #enp                    # end procedure cmgen
                   14780:        #page   
                   14781: #
                   14782: #      CMPIL (COMPILE SOURCE CODE)
                   14783: #
                   14784: #      CMPIL IS USED TO CONVERT SNOBOL4 SOURCE CODE TO INTERNAL
                   14785: #      FORM (SEE CDBLK FORMAT). IT IS USED BOTH FOR THE INITIAL
                   14786: #      COMPILE AND AT RUN TIME BY THE CODE AND CONVERT FUNCTIONS
                   14787: #      THIS PROCEDURE HAS CONTROL FOR THE ENTIRE DURATION OF
                   14788: #      INITIAL COMPILATION. AN ERROR IN ANY PROCEDURE CALLED
                   14789: #      DURING COMPILATION WILL LEAD FIRST TO THE ERROR SECTION
                   14790: #      AND ULTIMATELY BACK HERE FOR RESUMED COMPILATION. THE
                   14791: #      RE-ENTRY POINTS AFTER AN ERROR ARE SPECIALLY LABELLED -
                   14792: #
                   14793: #      CMPCE                 RESUME AFTER CONTROL CARD ERROR
                   14794: #      CMPLE                 RESUME AFTER LABEL ERROR
                   14795: #      CMPSE                 RESUME AFTER STATEMENT ERROR
                   14796: #
                   14797: #      JSR  CMPIL            CALL TO COMPILE CODE
                   14798: #      (XR)                  PTR TO CDBLK FOR ENTRY STATEMENT
                   14799: #      (XL,WA,WB,WC,RA)      DESTROYED
                   14800: #
                   14801: #      THE FOLLOWING GLOBAL VARIABLES ARE REFERENCED
                   14802: #
                   14803: #      CMPSN                 NUMBER OF NEXT STATEMENT
                   14804: #                            TO BE COMPILED.
                   14805: #
                   14806: #      CSWXX                 CONTROL CARD SWITCH VALUES ARE
                   14807: #                            CHANGED WHEN RELEVANT CONTROL
                   14808: #                            CARDS ARE MET.
                   14809: #
                   14810: #      CWCOF                 OFFSET TO NEXT WORD IN CODE BLOCK
                   14811: #                            BEING BUILT (SEE CDWRD).
                   14812: #
                   14813: #      LSTSN                 NUMBER OF STATEMENT MOST RECENTLY
                   14814: #                            COMPILED (INITIALLY SET TO ZERO).
                   14815: #
                   14816: #      R$CIM                 CURRENT (INITIAL) COMPILER IMAGE
                   14817: #                            (ZERO FOR INITIAL COMPILE CALL)
                   14818: #
                   14819: #      R$CNI                 USED TO POINT TO FOLLOWING IMAGE.
                   14820: #                            (SEE READR PROCEDURE).
                   14821: #
                   14822: #      SCNGO                 GOTO SWITCH FOR SCANE PROCEDURE
                   14823: #
                   14824: #      SCNIL                 LENGTH OF CURRENT IMAGE EXCLUDING
                   14825: #                            CHARACTERS REMOVED BY -INPUT.
                   14826: #
                   14827: #      SCNPT                 CURRENT SCAN OFFSET, SEE SCANE.
                   14828: #
                   14829: #      SCNRS                 RESCAN SWITCH FOR SCANE PROCEDURE.
                   14830: #
                   14831: #      SCNSE                 OFFSET (IN R$CIM) OF MOST RECENTLY
                   14832: #                            SCANNED ELEMENT. SET ZERO IF NOT
                   14833: #                            CURRENTLY SCANNING ITEMS
                   14834:        #page   
                   14835: #
                   14836: #      CMPIL (CONTINUED)
                   14837: #
                   14838: #      STAGE               STGIC  INITIAL COMPILE IN PROGRESS
                   14839: #                          STGXC  CODE/CONVERT COMPILE
                   14840: #                          STGEV  BUILDING EXBLK FOR EVAL
                   14841: #                          STGXT  EXECUTE TIME (OUTSIDE COMPILE)
                   14842: #                          STGCE  INITIAL COMPILE AFTER END LINE
                   14843: #                          STGXE  EXECUTE COMPILE AFTER END LINE
                   14844: #
                   14845: #      CMPIL ALSO USES A FIXED NUMBER OF LOCATIONS ON THE
                   14846: #      MAIN STACK AS FOLLOWS. (THE DEFINITIONS OF THE ACTUAL
                   14847: #      OFFSETS ARE IN THE DEFINITIONS SECTION).
                   14848: #
                   14849: #      CMSTM(XS)             POINTER TO EXPAN TREE FOR BODY OF
                   14850: #                            STATEMENT (SEE EXPAN PROCEDURE).
                   14851: #
                   14852: #      CMSGO(XS)             POINTER TO TREE REPRESENTATION OF
                   14853: #                            SUCCESS GOTO (SEE PROCEDURE SCNGO)9
                   14854: #                            ZERO IF NO SUCCESS GOTO IS GIVEN
                   14855: #
                   14856: #      CMFGO(XS)             LIKE CMSGO FOR FAILURE GOTO.
                   14857: #
                   14858: #      CMCGO(XS)             SET NON-ZERO ONLY IF THERE IS A
                   14859: #                            CONDITIONAL GOTO. USED FOR -FAIL,
                   14860: #                            -NOFAIL CODE GENERATION.
                   14861: #
                   14862: #      CMPCD(XS)             POINTER TO CDBLK FOR PREVIOUS
                   14863: #                            STATEMENT. ZERO FOR 1ST STATEMENT.
                   14864: #
                   14865: #      CMFFP(XS)             SET NON-ZERO IF CDFAL IN PREVIOUS
                   14866: #                            CDBLK NEEDS FILLING WITH FORWARD
                   14867: #                            POINTER, ELSE SET TO ZERO.
                   14868: #
                   14869: #      CMFFC(XS)             SAME AS CMFFP FOR CURRENT CDBLK
                   14870: #
                   14871: #      CMSOP(XS)             OFFSET TO WORD IN PREVIOUS CDBLK
                   14872: #                            TO BE FILLED IN WITH FORWARD PTR
                   14873: #                            TO NEXT CDBLK FOR SUCCESS GOTO.
                   14874: #                            ZERO IF NO FILL IN IS REQUIRED.
                   14875: #
                   14876: #      CMSOC(XS)             SAME AS CMSOP FOR CURRENT CDBLK.
                   14877: #
                   14878: #      CMLBL(XS)             POINTER TO VRBLK FOR LABEL OF
                   14879: #                            CURRENT STATEMENT. ZERO IF NO LABEL
                   14880: #
                   14881: #      CMTRA(XS)             POINTER TO CDBLK FOR ENTRY STMNT.
                   14882:        #page   
                   14883: #
                   14884: #      CMPIL (CONTINUED)
                   14885: #
                   14886: #      ENTRY POINT
                   14887: #
                   14888: cmpil: #prc                    # entry point
                   14889:        movl    $cmnen,r7       # set number of stack work locations
                   14890: #
                   14891: #      LOOP TO INITIALIZE STACK WORKING LOCATIONS
                   14892: #
                   14893: cmp00: clrl    -(sp)           # store a zero, make one entry
                   14894:        sobgtr  r7,cmp00        # loop back until all set
                   14895:        movl    sp,cmpxs        # save stack pointer for error sec
                   14896:        #sss    cmpss           # save s-r stack pointer if any
                   14897: #
                   14898: #      LOOP THROUGH STATEMENTS
                   14899: #
                   14900: cmp01: movl    scnpt,r7        # set scan pointer offset
                   14901:        movl    r7,scnse        # set start of element location
                   14902:        movl    $ocer$,r6       # point to compile error call
                   14903:        jsb     cdwrd           # generate as temporary cdfal
                   14904:        cmpl    r7,scnil        # jump if chars left on this image
                   14905:        blssu   cmp04
                   14906: #
                   14907: #      LOOP HERE AFTER COMMENT OR CONTROL CARD
                   14908: #      ALSO SPECIAL ENTRY AFTER CONTROL CARD ERROR
                   14909: #
                   14910: cmpce: clrl    r9              # clear possible garbage xr value
                   14911:        cmpl    stage,$stgic    # skip unless initial compile
                   14912:        bnequ   cmp02
                   14913:        jsb     readr           # read next input image
                   14914:        tstl    r9              # jump if no input available
                   14915:        bnequ   0f
                   14916:        jmp     cmp09
                   14917: 0:             
                   14918:        jsb     nexts           # acquire next source image
                   14919:        movl    cmpsn,lstsn     # store stmt no for use by listr
                   14920:        clrl    scnpt           # reset scan pointer
                   14921:        jmp     cmp04           # go process image
                   14922: #
                   14923: #      FOR EXECUTE TIME COMPILE, PERMIT EMBEDDED CONTROL CARDS
                   14924: #      AND COMMENTS (BY SKIPPING TO NEXT SEMI-COLON)
                   14925: #
                   14926: cmp02: movl    r$cim,r9        # get current image
                   14927:        movl    scnpt,r7        # get current offset
                   14928:        movab   cfp$f(r9)[r7],r9# prepare to get chars
                   14929: #
                   14930: #      SKIP TO SEMI-COLON
                   14931: #
                   14932: cmp03: movzbl  (r9)+,r8        # get char
                   14933:        incl    scnpt           # advance offset
                   14934:        cmpl    r8,$ch$sm       # skip if semi-colon found
                   14935:        beqlu   cmp04
                   14936:        cmpl    scnpt,scnil     # loop if more chars
                   14937:        blssu   cmp03
                   14938:        clrl    r9              # clear garbage xr value
                   14939:        jmp     cmp09           # end of image
                   14940:        #page   
                   14941: #
                   14942: #      CMPIL (CONTINUED)
                   14943: #
                   14944: #      HERE WITH IMAGE AVAILABLE TO SCAN. NOTE THAT IF THE INPUT
                   14945: #      STRING IS NULL, THEN EVERYTHING IS OK SINCE NULL IS
                   14946: #      ACTUALLY ASSEMBLED AS A WORD OF BLANKS.
                   14947: #
                   14948: cmp04: movl    r$cim,r9        # point to current image
                   14949:        movl    scnpt,r7        # load current offset
                   14950:        movl    r7,r6           # copy for label scan
                   14951:        movab   cfp$f(r9)[r7],r9# point to first character
                   14952:        movzbl  (r9)+,r8        # load first character
                   14953:        cmpl    r8,$ch$sm       # no label if semicolon
                   14954:        bnequ   0f
                   14955:        jmp     cmp12
                   14956: 0:             
                   14957:        cmpl    r8,$ch$as       # loop back if comment card
                   14958:        bnequ   0f
                   14959:        jmp     cmpce
                   14960: 0:             
                   14961:        cmpl    r8,$ch$mn       # jump if control card
                   14962:        bnequ   0f
                   14963:        jmp     cmp32
                   14964: 0:             
                   14965:        movl    r$cim,r$cmp     # about to destroy r$cim
                   14966:        movl    $cmlab,r10      # point to label work string
                   14967:        movl    r10,r$cim       # scane is to scan work string
                   14968:        movab   cfp$f(r10),r10  # point to first character position
                   14969:        movb    r8,(r10)+       # store char just loaded
                   14970:        movl    $ch$sm,r8       # get a semicolon
                   14971:        movb    r8,(r10)        # store after first char
                   14972:        #csc    r10             # finished character storing
                   14973:        clrl    r10             # clear pointer
                   14974:        clrl    scnpt           # start at first character
                   14975:        movl    scnil,-(sp)     # preserve image length
                   14976:        movl    $num02,scnil    # read 2 chars at most
                   14977:        jsb     scane           # scan first char for type
                   14978:        movl    (sp)+,scnil     # restore image length
                   14979:        movl    r10,r8          # note return code
                   14980:        movl    r$cmp,r10       # get old r$cim
                   14981:        movl    r10,r$cim       # put it back
                   14982:        movl    r7,scnpt        # reinstate offset
                   14983:        tstl    scnbl           # blank seen - cant be label
                   14984:        beqlu   0f
                   14985:        jmp     cmp12
                   14986: 0:             
                   14987:        movl    r10,r9          # point to current image
                   14988:        movab   cfp$f(r9)[r7],r9# point to first char again
                   14989:        cmpl    r8,$t$var       # ok if letter
                   14990:        beqlu   cmp06
                   14991:        cmpl    r8,$t$con       # ok if digit
                   14992:        beqlu   cmp06
                   14993: #
                   14994: #      DROP IN OR JUMP FROM ERROR SECTION IF SCANE FAILED
                   14995: #
                   14996: cmple: movl    r$cmp,r$cim     # point to bad line
                   14997:        jmp     er_214          # bad label or misplaced continuation line
                   14998: #
                   14999: #      LOOP TO SCAN LABEL
                   15000: #
                   15001: cmp05: cmpl    r8,$ch$sm       # skip if semicolon
                   15002:        beqlu   cmp07
                   15003:        incl    r6              # bump offset
                   15004:        cmpl    r6,scnil        # jump if end of image (label end)
                   15005:        beqlu   cmp07
                   15006:        #page   
                   15007: #
                   15008: #      CMPIL (CONTINUED)
                   15009: #
                   15010: #      ENTER LOOP AT THIS POINT
                   15011: #
                   15012: cmp06: movzbl  (r9)+,r8        # else load next character
                   15013:        cmpl    r8,$ch$ht       # jump if horizontal tab
                   15014:        beqlu   cmp07
                   15015:        cmpl    r8,$ch$bl       # loop back if non-blank
                   15016:        bnequ   cmp05
                   15017: #
                   15018: #      HERE AFTER SCANNING OUT LABEL
                   15019: #
                   15020: cmp07: movl    r6,scnpt        # save updated scan offset
                   15021:        subl2   r7,r6           # get length of label
                   15022:        tstl    r6              # skip if label length zero
                   15023:        bnequ   0f
                   15024:        jmp     cmp12
                   15025: 0:             
                   15026:        clrl    r9              # clear garbage xr value
                   15027:        jsb     sbstr           # build scblk for label name
                   15028:        jsb     gtnvr           # locate/contruct vrblk
                   15029:        .long   invalid$        # dummy (impossible) error return
                   15030:        movl    r9,4*cmlbl(sp)  # store label pointer
                   15031:        tstl    4*vrlen(r9)     # jump if not system label
                   15032:        bnequ   cmp11
                   15033:        cmpl    4*vrsvp(r9),$v$end # jump if not end label
                   15034:        bnequ   cmp11
                   15035: #
                   15036: #      HERE FOR END LABEL SCANNED OUT
                   15037: #
                   15038:        addl2   $stgnd,stage    # adjust stage appropriately
                   15039:        jsb     scane           # scan out next element
                   15040:        cmpl    r10,$t$smc      # jump if end of image
                   15041:        bnequ   0f
                   15042:        jmp     cmp10
                   15043: 0:             
                   15044:        cmpl    r10,$t$var      # else error if not variable
                   15045:        bnequ   cmp08
                   15046: #
                   15047: #      HERE CHECK FOR VALID INITIAL TRANSFER
                   15048: #
                   15049:        cmpl    4*vrlbl(r9),$stndl # jump if not defined (error)
                   15050:        beqlu   cmp08
                   15051:        movl    4*vrlbl(r9),4*cmtra(sp) # else set initial entry pointer
                   15052:        jsb     scane           # scan next element
                   15053:        cmpl    r10,$t$smc      # jump if ok (end of image)
                   15054:        bnequ   0f
                   15055:        jmp     cmp10
                   15056: 0:             
                   15057: #
                   15058: #      HERE FOR BAD TRANSFER LABEL
                   15059: #
                   15060: cmp08: jmp     er_215          # syntax error. undefined or erroneous entry label
                   15061: #
                   15062: #      HERE FOR END OF INPUT (NO END LABEL DETECTED)
                   15063: #
                   15064: cmp09: addl2   $stgnd,stage    # adjust stage appropriately
                   15065:        cmpl    stage,$stgxe    # jump if code call (ok)
                   15066:        bnequ   0f
                   15067:        jmp     cmp10
                   15068: 0:             
                   15069:        jmp     er_216          # syntax error. missing end line
                   15070: #
                   15071: #      HERE AFTER PROCESSING END LINE (MERGE HERE ON END ERROR)
                   15072: #
                   15073: cmp10: movl    $ostp$,r6       # set stop call pointer
                   15074:        jsb     cdwrd           # generate as statement call
                   15075:        jmp     cmpse           # jump to generate as failure
                   15076:        #page   
                   15077: #
                   15078: #      CMPIL (CONTINUED)
                   15079: #
                   15080: #      HERE AFTER PROCESSING LABEL OTHER THAN END
                   15081: #
                   15082: cmp11: cmpl    stage,$stgic    # jump if code call - redef. ok
                   15083:        beqlu   0f
                   15084:        jmp     cmp12
                   15085: 0:             
                   15086:        cmpl    4*vrlbl(r9),$stndl # else check for redefinition
                   15087:        bnequ   0f
                   15088:        jmp     cmp12
                   15089: 0:             
                   15090:        clrl    4*cmlbl(sp)     # leave first label decln undisturbed
                   15091:        jmp     er_217          # syntax error. duplicate label
                   15092: #
                   15093: #      HERE AFTER DEALING WITH LABEL
                   15094: #
                   15095: cmp12: clrl    r7              # set flag for statement body
                   15096:        jsb     expan           # get tree for statement body
                   15097:        movl    r9,4*cmstm(sp)  # store for later use
                   15098:        clrl    4*cmsgo(sp)     # clear success goto pointer
                   15099:        clrl    4*cmfgo(sp)     # clear failure goto pointer
                   15100:        clrl    4*cmcgo(sp)     # clear conditional goto flag
                   15101:        jsb     scane           # scan next element
                   15102:        cmpl    r10,$t$col      # jump it not colon (no goto)
                   15103:        beqlu   0f
                   15104:        jmp     cmp18
                   15105: 0:             
                   15106: #
                   15107: #      LOOP TO PROCESS GOTO FIELDS
                   15108: #
                   15109: cmp13: movl    sp,scngo        # set goto flag
                   15110:        jsb     scane           # scan next element
                   15111:        cmpl    r10,$t$smc      # jump if no fields left
                   15112:        bnequ   0f
                   15113:        jmp     cmp31
                   15114: 0:             
                   15115:        cmpl    r10,$t$sgo      # jump if s for success goto
                   15116:        beqlu   cmp14
                   15117:        cmpl    r10,$t$fgo      # jump if f for failure goto
                   15118:        beqlu   cmp16
                   15119: #
                   15120: #      HERE FOR UNCONDITIONAL GOTO (I.E. NOT F OR S)
                   15121: #
                   15122:        movl    sp,scnrs        # set to rescan element not f,s
                   15123:        jsb     scngf           # scan out goto field
                   15124:        tstl    4*cmfgo(sp)     # error if fgoto already
                   15125:        bnequ   cmp17
                   15126:        movl    r9,4*cmfgo(sp)  # else set as fgoto
                   15127:        jmp     cmp15           # merge with sgoto circuit
                   15128: #
                   15129: #      HERE FOR SUCCESS GOTO
                   15130: #
                   15131: cmp14: jsb     scngf           # scan success goto field
                   15132:        movl    $num01,4*cmcgo(sp) # set conditional goto flag
                   15133: #
                   15134: #      UNCONTIONAL GOTO MERGES HERE
                   15135: #
                   15136: cmp15: tstl    4*cmsgo(sp)     # error if sgoto already given
                   15137:        bnequ   cmp17
                   15138:        movl    r9,4*cmsgo(sp)  # else set sgoto
                   15139:        jmp     cmp13           # loop back for next goto field
                   15140: #
                   15141: #      HERE FOR FAILURE GOTO
                   15142: #
                   15143: cmp16: jsb     scngf           # scan goto field
                   15144:        movl    $num01,4*cmcgo(sp) # set conditonal goto flag
                   15145:        tstl    4*cmfgo(sp)     # error if fgoto already given
                   15146:        bnequ   cmp17
                   15147:        movl    r9,4*cmfgo(sp)  # else store fgoto pointer
                   15148:        jmp     cmp13           # loop back for next field
                   15149:        #page   
                   15150: #
                   15151: #      CMPIL (CONTINUED)
                   15152: #
                   15153: #      HERE FOR DUPLICATED GOTO FIELD
                   15154: #
                   15155: cmp17: jmp     er_218          # syntax error. duplicated goto field
                   15156: #
                   15157: #      HERE TO GENERATE CODE
                   15158: #
                   15159: cmp18: clrl    scnse           # stop positional error flags
                   15160:        movl    4*cmstm(sp),r9  # load tree ptr for statement body
                   15161:        clrl    r7              # collectable value for wb for cdgvl
                   15162:        clrl    r8              # reset constant flag for cdgvl
                   15163:        jsb     expap           # test for pattern match
                   15164:        .long   cmp19           # jump if not pattern match
                   15165:        movl    $opms$,4*cmopn(r9) # else set pattern match pointer
                   15166:        movl    $c$pmt,4*cmtyp(r9)
                   15167: #
                   15168: #      HERE AFTER DEALING WITH SPECIAL PATTERN MATCH CASE
                   15169: #
                   15170: cmp19: jsb     cdgvl           # generate code for body of statement
                   15171:        movl    4*cmsgo(sp),r9  # load sgoto pointer
                   15172:        movl    r9,r6           # copy it
                   15173:        tstl    r9              # jump if no success goto
                   15174:        beqlu   cmp21
                   15175:        clrl    4*cmsoc(sp)     # clear success offset fillin ptr
                   15176:        cmpl    r9,state        # jump if complex goto
                   15177:        bgequ   cmp20
                   15178: #
                   15179: #      HERE FOR SIMPLE SUCCESS GOTO (LABEL)
                   15180: #
                   15181:        addl2   $4*vrtra,r6     # point to vrtra field as required
                   15182:        jsb     cdwrd           # generate success goto
                   15183:        jmp     cmp22           # jump to deal with fgoto
                   15184: #
                   15185: #      HERE FOR COMPLEX SUCCESS GOTO
                   15186: #
                   15187: cmp20: cmpl    r9,4*cmfgo(sp)  # no code if same as fgoto
                   15188:        beqlu   cmp22
                   15189:        clrl    r7              # else set ok value for cdgvl in wb
                   15190:        jsb     cdgcg           # generate code for success goto
                   15191:        jmp     cmp22           # jump to deal with fgoto
                   15192: #
                   15193: #      HERE FOR NO SUCCESS GOTO
                   15194: #
                   15195: cmp21: movl    cwcof,4*cmsoc(sp)# set success fill in offset
                   15196:        movl    $ocer$,r6       # point to compile error call
                   15197:        jsb     cdwrd           # generate as temporary value
                   15198:        #page   
                   15199: #
                   15200: #      CMPIL (CONTINUED)
                   15201: #
                   15202: #      HERE TO DEAL WITH FAILURE GOTO
                   15203: #
                   15204: cmp22: movl    4*cmfgo(sp),r9  # load failure goto pointer
                   15205:        movl    r9,r6           # copy it
                   15206:        clrl    4*cmffc(sp)     # set no fill in required yet
                   15207:        tstl    r9              # jump if no failure goto given
                   15208:        beqlu   cmp23
                   15209:        addl2   $4*vrtra,r6     # point to vrtra field in case
                   15210:        cmpl    r9,state        # jump to gen if simple fgoto
                   15211:        blequ   cmpse
                   15212: #
                   15213: #      HERE FOR COMPLEX FAILURE GOTO
                   15214: #
                   15215:        movl    cwcof,r7        # save offset to o$gof call
                   15216:        movl    $ogof$,r6       # point to failure goto call
                   15217:        jsb     cdwrd           # generate
                   15218:        movl    $ofif$,r6       # point to fail in fail word
                   15219:        jsb     cdwrd           # generate
                   15220:        jsb     cdgcg           # generate code for failure goto
                   15221:        movl    r7,r6           # copy offset to o$gof for cdfal
                   15222:        movl    $b$cdc,r7       # set complex case cdtyp
                   15223:        jmp     cmp25           # jump to build cdblk
                   15224: #
                   15225: #      HERE IF NO FAILURE GOTO GIVEN
                   15226: #
                   15227: cmp23: movl    $ounf$,r6       # load unexpected failure call in cas
                   15228:        movl    cswfl,r8        # get -nofail flag
                   15229:        bisl2   4*cmcgo(sp),r8  # check if conditional goto
                   15230:        tstl    r8              # jump if -nofail and no cond. goto
                   15231:        beqlu   cmpse
                   15232:        movl    sp,4*cmffc(sp)  # else set fill in flag
                   15233:        movl    $ocer$,r6       # and set compile error for temporary
                   15234: #
                   15235: #      MERGE HERE WITH CDFAL VALUE IN WA, SIMPLE CDBLK
                   15236: #      ALSO SPECIAL ENTRY AFTER STATEMENT ERROR
                   15237: #
                   15238: cmpse: movl    $b$cds,r7       # set cdtyp for simple case
                   15239:        #page   
                   15240: #
                   15241: #      CMPIL (CONTINUED)
                   15242: #
                   15243: #      MERGE HERE TO BUILD CDBLK
                   15244: #
                   15245: #      (WA)                  CDFAL VALUE TO BE GENERATED
                   15246: #      (WB)                  CDTYP VALUE TO BE GENERATED
                   15247: #
                   15248: #      AT THIS STAGE, WE CHOP OFF AN APPROPRIATE CHUNK OF THE
                   15249: #      CURRENT CCBLK AND CONVERT IT INTO A CDBLK. THE REMAINDER
                   15250: #      OF THE CCBLK IS REFORMATTED TO BE THE NEW CCBLK.
                   15251: #
                   15252: cmp25: movl    r$ccb,r9        # point to ccblk
                   15253:        movl    4*cmlbl(sp),r10 # get possible label pointer
                   15254:        tstl    r10             # skip if no label
                   15255:        beqlu   cmp26
                   15256:        clrl    4*cmlbl(sp)     # clear flag for next statement
                   15257:        movl    r9,4*vrlbl(r10) # put cdblk ptr in vrblk label field
                   15258: #
                   15259: #      MERGE AFTER DOING LABEL
                   15260: #
                   15261: cmp26: movl    r7,(r9)         # set type word for new cdblk
                   15262:        movl    r6,4*cdfal(r9)  # set failure word
                   15263:        movl    r9,r10          # copy pointer to ccblk
                   15264:        movl    4*ccuse(r9),r7  # load length gen (= new cdlen)
                   15265:        movl    4*cclen(r9),r8  # load total ccblk length
                   15266:        addl2   r7,r10          # point past cdblk
                   15267:        subl2   r7,r8           # get length left for chop off
                   15268:        movl    $b$cct,(r10)    # set type code for new ccblk at end
                   15269:        movl    $4*cccod,4*ccuse(r10) # set initial code offset
                   15270:        movl    $4*cccod,cwcof  # reinitialise cwcof
                   15271:        movl    r8,4*cclen(r10) # set new length
                   15272:        movl    r10,r$ccb       # set new ccblk pointer
                   15273:        movl    cmpsn,4*cdstm(r9)# set statement number
                   15274:        incl    cmpsn           # bump statement number
                   15275: #
                   15276: #      SET POINTERS IN PREVIOUS CODE BLOCK AS REQUIRED
                   15277: #
                   15278:        movl    4*cmpcd(sp),r10 # load ptr to previous cdblk
                   15279:        tstl    4*cmffp(sp)     # jump if no failure fill in required
                   15280:        beqlu   cmp27
                   15281:        movl    r9,4*cdfal(r10) # else set failure ptr in previous
                   15282: #
                   15283: #      HERE TO DEAL WITH SUCCESS FORWARD POINTER
                   15284: #
                   15285: cmp27: movl    4*cmsop(sp),r6  # load success offset
                   15286:        tstl    r6              # jump if no fill in required
                   15287:        beqlu   cmp28
                   15288:        addl2   r6,r10          # else point to fill in location
                   15289:        movl    r9,(r10)        # store forward pointer
                   15290:        clrl    r10             # clear garbage xl value
                   15291:        #page   
                   15292: #
                   15293: #      CMPIL (CONTINUED)
                   15294: #
                   15295: #      NOW SET FILL IN POINTERS FOR THIS STATEMENT
                   15296: #
                   15297: cmp28: movl    4*cmffc(sp),4*cmffp(sp) # copy failure fill in flag
                   15298:        movl    4*cmsoc(sp),4*cmsop(sp) # copy success fill in offset
                   15299:        movl    r9,4*cmpcd(sp)  # save ptr to this cdblk
                   15300:        tstl    4*cmtra(sp)     # jump if initial entry already set
                   15301:        bnequ   cmp29
                   15302:        movl    r9,4*cmtra(sp)  # else set ptr here as default
                   15303: #
                   15304: #      HERE AFTER COMPILING ONE STATEMENT
                   15305: #
                   15306: cmp29: cmpl    stage,$stgce    # jump if not end line just done
                   15307:        bgequ   0f
                   15308:        jmp     cmp01
                   15309: 0:             
                   15310:        tstl    cswls           # skip if -nolist
                   15311:        beqlu   cmp30
                   15312:        jsb     listr           # list last line
                   15313: #
                   15314: #      RETURN
                   15315: #
                   15316: cmp30: movl    4*cmtra(sp),r9  # load initial entry cdblk pointer
                   15317:        addl2   $4*cmnen,sp     # pop work locations off stack
                   15318:        rsb                     # and return to cmpil caller
                   15319: #
                   15320: #      HERE AT END OF GOTO FIELD
                   15321: #
                   15322: cmp31: movl    4*cmfgo(sp),r7  # get fail goto
                   15323:        bisl2   4*cmsgo(sp),r7  # or in success goto
                   15324:        tstl    r7              # ok if non-null field
                   15325:        beqlu   0f
                   15326:        jmp     cmp18
                   15327: 0:             
                   15328:        jmp     er_219          # syntax error. empty goto field
                   15329: #
                   15330: #      CONTROL CARD FOUND
                   15331: #
                   15332: cmp32: incl    r7              # point past ch$mn
                   15333:        jsb     cncrd           # process control card
                   15334:        clrl    scnse           # clear start of element loc.
                   15335:        jmp     cmpce           # loop for next statement
                   15336:        #enp                    # end procedure cmpil
                   15337:        #page   
                   15338: #
                   15339: #      CNCRD -- CONTROL CARD PROCESSOR
                   15340: #
                   15341: #      CALLED TO DEAL WITH CONTROL CARDS
                   15342: #
                   15343: #      R$CIM                 POINTS TO CURRENT IMAGE
                   15344: #      (WB)                  OFFSET TO 1ST CHAR OF CONTROL CARD
                   15345: #      JSR  CNCRD            CALL TO PROCESS CONTROL CARDS
                   15346: #      (XL,XR,WA,WB,WC,IA)   DESTROYED
                   15347: #
                   15348: cncrd: #prc                    # entry point
                   15349:        movl    r7,scnpt        # offset for control card scan
                   15350:        movl    $ccnoc,r6       # number of chars for comparison
                   15351:        movab   3+(4*0)(r6),r6  # convert to word count
                   15352:        ashl    $-2,r6,r6
                   15353:        movl    r6,cnswc        # save word count
                   15354: #
                   15355: #      LOOP HERE IF MORE THAN ONE CONTROL CARD
                   15356: #
                   15357: cnc01: cmpl    scnpt,scnil     # return if end of image
                   15358:        blssu   0f
                   15359:        jmp     cnc09
                   15360: 0:             
                   15361:        movl    r$cim,r9        # point to image
                   15362:        movl    scnpt,r11       # [get in scratch register]
                   15363:        movab   cfp$f(r9)[r11],r9# char ptr for first char
                   15364:        movzbl  (r9)+,r6        # get first char
                   15365:        bicl2   $ch$bl,r6       # fold to upper case
                   15366:        cmpl    r6,$ch$li       # special case of -inxxx
                   15367:        bnequ   0f
                   15368:        jmp     cnc07
                   15369: 0:             
                   15370:        movl    sp,scncc        # set flag for scane
                   15371:        jsb     scane           # scan card name
                   15372:        clrl    scncc           # clear scane flag
                   15373:        tstl    r10             # fail unless control card name
                   15374:        beqlu   0f
                   15375:        jmp     cnc06
                   15376: 0:             
                   15377:        movl    $ccnoc,r6       # no. of chars to be compared
                   15378:        cmpl    4*sclen(r9),r6  # fail if too few chars
                   15379:        bgequ   0f
                   15380:        jmp     cnc06
                   15381: 0:             
                   15382:        movl    r9,r10          # point to control card name
                   15383:        clrl    r7              # zero offset for substring
                   15384:        jsb     sbstr           # extract substring for comparison
                   15385:        movl    4*sclen(r9),r6  # reload length
                   15386:        jsb     flstg           # fold to upper case
                   15387:        movl    r9,cnscc        # keep control card substring ptr
                   15388:        movl    $ccnms,r9       # point to list of standard names
                   15389:        clrl    r7              # initialise name offset
                   15390:        movl    $cc$nc,r8       # number of standard names
                   15391: #
                   15392: #      TRY TO MATCH NAME
                   15393: #
                   15394: cnc02: movl    cnscc,r10       # point to name
                   15395:        movl    cnswc,r6        # counter for inner loop
                   15396:        jmp     cnc04           # jump into loop
                   15397: #
                   15398: #      INNER LOOP TO MATCH CARD NAME CHARS
                   15399: #
                   15400: cnc03: addl2   $4,r9           # bump standard names ptr
                   15401:        addl2   $4,r10          # bump name pointer
                   15402: #
                   15403: #      HERE TO INITIATE THE LOOP
                   15404: #
                   15405: cnc04: cmpl    4*schar(r10),(r9)# comp. up to cfp$c chars at once
                   15406:        bnequ   cnc05
                   15407:        sobgtr  r6,cnc03        # loop if more words to compare
                   15408:        #page   
                   15409: #
                   15410: #      CNCRD (CONTINUED)
                   15411: #
                   15412: #      MATCHED - BRANCH ON CARD OFFSET
                   15413: #
                   15414:        movl    r7,r10          # get name offset
                   15415:        casel   r10,$0,$cc$nc   # switch
                   15416: 5:             
                   15417:        .word   cnc37-5b        # -case
                   15418:        .word   cnc10-5b        # -double
                   15419:        .word   cnc11-5b        # -dump
                   15420:        .word   cnc12-5b        # -eject
                   15421:        .word   cnc13-5b        # -errors
                   15422:        .word   cnc14-5b        # -execute
                   15423:        .word   cnc15-5b        # -fail
                   15424:        .word   cnc16-5b        # -list
                   15425:        .word   cnc17-5b        # -noerrors
                   15426:        .word   cnc18-5b        # -noexecute
                   15427:        .word   cnc19-5b        # -nofail
                   15428:        .word   cnc20-5b        # -nolist
                   15429:        .word   cnc21-5b        # -noopt
                   15430:        .word   cnc22-5b        # -noprint
                   15431:        .word   cnc24-5b        # -optimise
                   15432:        .word   cnc25-5b        # -print
                   15433:        .word   cnc27-5b        # -single
                   15434:        .word   cnc28-5b        # -space
                   15435:        .word   cnc31-5b        # -stitle
                   15436:        .word   cnc32-5b        # -title
                   15437:        .word   cnc36-5b        # -trace
                   15438:        #esw                    # end switch
                   15439: #
                   15440: #      NOT MATCHED YET. ALIGN STD NAMES PTR AND TRY AGAIN
                   15441: #
                   15442: cnc05: addl2   $4,r9           # bump standard names ptr
                   15443:        sobgtr  r6,cnc05        # loop
                   15444:        incl    r7              # bump names offset
                   15445:        sobgtr  r8,cnc02        # continue if more names
                   15446: #
                   15447: #      INVALID CONTROL CARD NAME
                   15448: #
                   15449: cnc06: jmp     er_247          # invalid control card
                   15450: #
                   15451: #      SPECIAL PROCESSING FOR -INXXX
                   15452: #
                   15453: cnc07: movzbl  (r9),r6         # get next char
                   15454:        bicl2   $ch$bl,r6       # fold to upper case
                   15455:        cmpl    r6,$ch$ln       # fail if not letter n
                   15456:        beqlu   0f
                   15457:        jmp     cnc06
                   15458: 0:             
                   15459:        addl2   $num02,scnpt    # bump offset past -in
                   15460:        jsb     scane           # scan integer after -in
                   15461:        movl    r9,-(sp)        # stack scanned item
                   15462:        jsb     gtsmi           # check if integer
                   15463:        .long   cnc06           # fail if not integer
                   15464:        .long   cnc06           # fail if negative or large
                   15465:        movl    r9,cswin        # keep integer
                   15466:        #page   
                   15467: #
                   15468: #      CNCRD (CONTINUED)
                   15469: #
                   15470: #      CHECK FOR MORE CONTROL CARDS BEFORE RETURNING
                   15471: #
                   15472: cnc08: movl    scnpt,r6        # preserve in case xeq time compile
                   15473:        jsb     scane           # look for comma
                   15474:        cmpl    r10,$t$cma      # loop if comma found
                   15475:        bnequ   0f
                   15476:        jmp     cnc01
                   15477: 0:             
                   15478:        movl    r6,scnpt        # restore scnpt in case xeq time
                   15479: #
                   15480: #      RETURN POINT
                   15481: #
                   15482: cnc09: rsb                     # return
                   15483: #
                   15484: #      -DOUBLE
                   15485: #
                   15486: cnc10: movl    sp,cswdb        # set switch
                   15487:        jmp     cnc08           # merge
                   15488: #
                   15489: #      -DUMP
                   15490: #      THIS IS USED FOR SYSTEM DEBUGGING . IT HAS THE EFFECT OF
                   15491: #      PRODUCING A CORE DUMP AT COMPILATION TIME
                   15492: #
                   15493: cnc11: jsb     sysdm           # call dumper
                   15494:        jmp     cnc09           # finished
                   15495: #
                   15496: #      -EJECT
                   15497: #
                   15498: cnc12: tstl    cswls           # return if -nolist
                   15499:        bnequ   0f
                   15500:        jmp     cnc09
                   15501: 0:             
                   15502:        jsb     prtps           # eject
                   15503:        jsb     listt           # list title
                   15504:        jmp     cnc09           # finished
                   15505: #
                   15506: #      -ERRORS
                   15507: #
                   15508: cnc13: clrl    cswer           # clear switch
                   15509:        jmp     cnc08           # merge
                   15510: #
                   15511: #      -EXECUTE
                   15512: #
                   15513: cnc14: clrl    cswex           # clear switch
                   15514:        jmp     cnc08           # merge
                   15515: #
                   15516: #      -FAIL
                   15517: #
                   15518: cnc15: movl    sp,cswfl        # set switch
                   15519:        jmp     cnc08           # merge
                   15520: #
                   15521: #      -LIST
                   15522: #
                   15523: cnc16: movl    sp,cswls        # set switch
                   15524:        cmpl    stage,$stgic    # done if compile time
                   15525:        beqlu   cnc08
                   15526: #
                   15527: #      LIST CODE LINE IF EXECUTE TIME COMPILE
                   15528: #
                   15529:        clrl    lstpf           # permit listing
                   15530:        jsb     listr           # list line
                   15531:        jmp     cnc08           # merge
                   15532:        #page   
                   15533: #
                   15534: #      CNCRD (CONTINUED)
                   15535: #
                   15536: #      -NOERRORS
                   15537: #
                   15538: cnc17: movl    sp,cswer        # set switch
                   15539:        jmp     cnc08           # merge
                   15540: #
                   15541: #      -NOEXECUTE
                   15542: #
                   15543: cnc18: movl    sp,cswex        # set switch
                   15544:        jmp     cnc08           # merge
                   15545: #
                   15546: #      -NOFAIL
                   15547: #
                   15548: cnc19: clrl    cswfl           # clear switch
                   15549:        jmp     cnc08           # merge
                   15550: #
                   15551: #      -NOLIST
                   15552: #
                   15553: cnc20: clrl    cswls           # clear switch
                   15554:        jmp     cnc08           # merge
                   15555: #
                   15556: #      -NOOPTIMISE
                   15557: #
                   15558: cnc21: movl    sp,cswno        # set switch
                   15559:        jmp     cnc08           # merge
                   15560: #
                   15561: #      -NOPRINT
                   15562: #
                   15563: cnc22: clrl    cswpr           # clear switch
                   15564:        jmp     cnc08           # merge
                   15565: #
                   15566: #      -OPTIMISE
                   15567: #
                   15568: cnc24: clrl    cswno           # clear switch
                   15569:        jmp     cnc08           # merge
                   15570: #
                   15571: #      -PRINT
                   15572: #
                   15573: cnc25: movl    sp,cswpr        # set switch
                   15574:        jmp     cnc08           # merge
                   15575:        #page   
                   15576: #
                   15577: #      CNCRD (CONTINUED)
                   15578: #
                   15579: #      -SINGLE
                   15580: #
                   15581: cnc27: clrl    cswdb           # clear switch
                   15582:        jmp     cnc08           # merge
                   15583: #
                   15584: #      -SPACE
                   15585: #
                   15586: cnc28: tstl    cswls           # return if -nolist
                   15587:        bnequ   0f
                   15588:        jmp     cnc09
                   15589: 0:             
                   15590:        jsb     scane           # scan integer after -space
                   15591:        movl    $num01,r8       # 1 space in case
                   15592:        cmpl    r9,$t$smc       # jump if no integer
                   15593:        beqlu   cnc29
                   15594:        movl    r9,-(sp)        # stack it
                   15595:        jsb     gtsmi           # check integer
                   15596:        .long   cnc06           # fail if not integer
                   15597:        .long   cnc06           # fail if negative or large
                   15598:        tstl    r8              # jump if non zero
                   15599:        bnequ   cnc29
                   15600:        movl    $num01,r8       # else 1 space
                   15601: #
                   15602: #      MERGE WITH COUNT OF LINES TO SKIP
                   15603: #
                   15604: cnc29: addl2   r8,lstlc        # bump line count
                   15605:                                # convert to loop counter
                   15606:        cmpl    lstlc,lstnp     # jump if fits on page
                   15607:        blssu   cnc30
                   15608:        jsb     prtps           # eject
                   15609:        jsb     listt           # list title
                   15610:        jmp     cnc09           # merge
                   15611: #
                   15612: #      SKIP LINES
                   15613: #
                   15614: cnc30: jsb     prtnl           # print a blank
                   15615:        sobgtr  r8,cnc30        # loop
                   15616:        jmp     cnc09           # merge
                   15617:        #page   
                   15618: #
                   15619: #      CNCRD (CONTINUED)
                   15620: #
                   15621: #      -STITL
                   15622: #
                   15623: cnc31: movl    $r$stl,cnr$t    # ptr to r$stl
                   15624:        jmp     cnc33           # merge
                   15625: #
                   15626: #      -TITLE
                   15627: #
                   15628: cnc32: movl    $nulls,r$stl    # clear subtitle
                   15629:        movl    $r$ttl,cnr$t    # ptr to r$ttl
                   15630: #
                   15631: #      COMMON PROCESSING FOR -TITLE, -STITL
                   15632: #
                   15633: cnc33: movl    $nulls,r9       # null in case needed
                   15634:        movl    sp,cnttl        # set flag for next listr call
                   15635:        movl    $ccofs,r7       # offset to title/subtitle
                   15636:        movl    scnil,r6        # input image length
                   15637:        cmpl    r6,r7           # jump if no chars left
                   15638:        blequ   cnc34
                   15639:        subl2   r7,r6           # no of chars to extract
                   15640:        movl    r$cim,r10       # point to image
                   15641:        jsb     sbstr           # get title/subtitle
                   15642: #
                   15643: #      STORE TITLE/SUBTITLE
                   15644: #
                   15645: cnc34: movl    cnr$t,r10       # point to storage location
                   15646:        movl    r9,(r10)        # store title/subtitle
                   15647:        cmpl    r10,$r$stl      # return if stitl
                   15648:        bnequ   0f
                   15649:        jmp     cnc09
                   15650: 0:             
                   15651:        tstl    precl           # return if extended listing
                   15652:        beqlu   0f
                   15653:        jmp     cnc09
                   15654: 0:             
                   15655:        tstl    prich           # return if regular printer
                   15656:        bnequ   0f
                   15657:        jmp     cnc09
                   15658: 0:             
                   15659:        movl    4*sclen(r9),r10 # get length of title
                   15660:        movl    r10,r6          # copy it
                   15661:        tstl    r10             # jump if null
                   15662:        beqlu   cnc35
                   15663:        addl2   $num10,r10      # increment
                   15664:        cmpl    r10,prlen       # use default lstp0 val if too long
                   15665:        blssu   0f
                   15666:        jmp     cnc09
                   15667: 0:             
                   15668:        addl2   $num04,r6       # point just past title
                   15669: #
                   15670: #      STORE OFFSET TO PAGE NN MESSAGE FOR SHORT TITLE
                   15671: #
                   15672: cnc35: movl    r6,lstpo        # store offset
                   15673:        jmp     cnc09           # return
                   15674: #
                   15675: #      -TRACE
                   15676: #      PROVIDED FOR SYSTEM DEBUGGING.  TOGGLES THE SYSTEM LABEL
                   15677: #      TRACE SWITCH AT COMPILE TIME
                   15678: #
                   15679: cnc36: jsb     systt           # toggle switch
                   15680:        jmp     cnc08           # merge
                   15681: #
                   15682: #      -CASE
                   15683: #      SETS VALUE OF KVCAS SO THAT NAMES ARE FOLDED OR NOT
                   15684: #      DURING COMPILATION.
                   15685: #
                   15686: cnc37: jsb     scane           # scan integer after -case
                   15687:        clrl    r8              # get 0 in case none there
                   15688:        cmpl    r10,$t$smc      # skip if no integer
                   15689:        beqlu   cnc38
                   15690:        movl    r9,-(sp)        # stack it
                   15691:        jsb     gtsmi           # check integer
                   15692:        .long   cnc06           # fail if not integer
                   15693:        .long   cnc06           # fail if negative or too large
                   15694: cnc38: movl    r8,kvcas        # store new case value
                   15695:        jmp     cnc09           # merge
                   15696:        #enp                    # end procedure cncrd
                   15697:        #page   
                   15698: #
                   15699: #      DFFNC -- DEFINE FUNCTION
                   15700: #
                   15701: #      DFFNC IS CALLED WHENEVER A NEW FUNCTION IS ASSIGNED TO
                   15702: #      A VARIABLE. IT DEALS WITH EXTERNAL FUNCTION USE COUNTS.
                   15703: #
                   15704: #      (XR)                  POINTER TO VRBLK
                   15705: #      (XL)                  POINTER TO NEW FUNCTION BLOCK
                   15706: #      JSR  DFFNC            CALL TO DEFINE FUNCTION
                   15707: #      (WA,WB)               DESTROYED
                   15708: #
                   15709: dffnc: #prc                    # entry point
                   15710:        cmpl    (r10),$b$efc    # skip if new function not external
                   15711:        bnequ   dffn1
                   15712:        incl    4*efuse(r10)    # else increment its use count
                   15713: #
                   15714: #      HERE AFTER DEALING WITH NEW FUNCTION USE COUNT
                   15715: #
                   15716: dffn1: movl    r9,r6           # save vrblk pointer
                   15717:        movl    4*vrfnc(r9),r9  # load old function pointer
                   15718:        cmpl    (r9),$b$efc     # jump if old function not external
                   15719:        bnequ   dffn2
                   15720:        movl    4*efuse(r9),r7  # else get use count
                   15721:        decl    r7              # decrement
                   15722:        movl    r7,4*efuse(r9)  # store decremented value
                   15723:        tstl    r7              # jump if use count still non-zero
                   15724:        bnequ   dffn2
                   15725:        jsb     sysul           # else call system unload function
                   15726: #
                   15727: #      HERE AFTER DEALING WITH OLD FUNCTION USE COUNT
                   15728: #
                   15729: dffn2: movl    r6,r9           # restore vrblk pointer
                   15730:        movl    r10,r6          # copy function block ptr
                   15731:        cmpl    r9,$r$yyy       # skip checks if opsyn op definition
                   15732:        blssu   dffn3
                   15733:        tstl    4*vrlen(r9)     # jump if not system variable
                   15734:        bnequ   dffn3
                   15735: #
                   15736: #      FOR SYSTEM VARIABLE, CHECK FOR ILLEGAL REDEFINITION
                   15737: #
                   15738:        movl    4*vrsvp(r9),r10 # point to svblk
                   15739:        movl    4*svbit(r10),r7 # load bit indicators
                   15740:        mcoml   btfnc,r11       # is it a system function
                   15741:        bicl2   r11,r7
                   15742:        tstl    r7              # redef ok if not
                   15743:        beqlu   dffn3
                   15744:        jmp     er_248          # attempted redefinition of system function
                   15745: #
                   15746: #      HERE IF REDEFINITION IS PERMITTED
                   15747: #
                   15748: dffn3: movl    r6,4*vrfnc(r9)  # store new function pointer
                   15749:        movl    r6,r10          # restore function block pointer
                   15750:        rsb                     # return to dffnc caller
                   15751:        #enp                    # end procedure dffnc
                   15752:        #page   
                   15753: #
                   15754: #      DTACH -- DETACH I/O ASSOCIATED NAMES
                   15755: #
                   15756: #      DETACHES TRBLKS FROM I/O ASSOCIATED VARIABLES, REMOVES
                   15757: #      ENTRY FROM IOCHN CHAIN ATTACHED TO FILEARG1 VRBLK AND MAY
                   15758: #      REMOVE VRBLK ACCESS AND STORE TRAPS.
                   15759: #      INPUT, OUTPUT, TERMINAL ARE HANDLED SPECIALLY.
                   15760: #
                   15761: #      (XL)                  I/O ASSOC. VBL NAME BASE PTR
                   15762: #      (WA)                  OFFSET TO NAME
                   15763: #      JSR  DTACH            CALL FOR DETACH OPERATION
                   15764: #      (XL,XR,WA,WB,WC)      DESTROYED
                   15765: #
                   15766: dtach: #prc                    # entry point
                   15767:        movl    r10,dtcnb       # store name base (gbcol not called)
                   15768:        addl2   r6,r10          # point to name location
                   15769:        movl    r10,dtcnm       # store it
                   15770: #
                   15771: #      LOOP TO SEARCH FOR I/O TRBLK
                   15772: #
                   15773: dtch1: movl    r10,r9          # copy name pointer
                   15774: #
                   15775: #      CONTINUE AFTER BLOCK DELETION
                   15776: #
                   15777: dtch2: movl    (r10),r10       # point to next value
                   15778:        cmpl    (r10),$b$trt    # jump at chain end
                   15779:        bnequ   dtch6
                   15780:        movl    4*trtyp(r10),r6 # get trap block type
                   15781:        cmpl    r6,$trtin       # jump if input
                   15782:        beqlu   dtch3
                   15783:        cmpl    r6,$trtou       # jump if output
                   15784:        beqlu   dtch3
                   15785:        addl2   $4*trnxt,r10    # point to next link
                   15786:        jmp     dtch1           # loop
                   15787: #
                   15788: #      DELETE AN OLD ASSOCIATION
                   15789: #
                   15790: dtch3: movl    4*trval(r10),(r9)# delete trblk
                   15791:        movl    r10,r6          # dump xl ...
                   15792:        movl    r9,r7           # ... and xr
                   15793:        movl    4*trtrf(r10),r10# point to trtrf trap block
                   15794:        tstl    r10             # jump if no iochn
                   15795:        beqlu   dtch5
                   15796:        cmpl    (r10),$b$trt    # jump if input, output, terminal
                   15797:        bnequ   dtch5
                   15798: #
                   15799: #      LOOP TO SEARCH IOCHN CHAIN FOR NAME PTR
                   15800: #
                   15801: dtch4: movl    r10,r9          # remember link ptr
                   15802:        movl    4*trtrf(r10),r10# point to next link
                   15803:        tstl    r10             # jump if end of chain
                   15804:        beqlu   dtch5
                   15805:        movl    4*ionmb(r10),r8 # get name base
                   15806:        addl2   4*ionmo(r10),r8 # add offset
                   15807:        cmpl    r8,dtcnm        # loop if no match
                   15808:        bnequ   dtch4
                   15809:        movl    4*trtrf(r10),4*trtrf(r9) # remove name from chain
                   15810:        #page   
                   15811: #
                   15812: #      DTACH (CONTINUED)
                   15813: #
                   15814: #      PREPARE TO RESUME I/O TRBLK SCAN
                   15815: #
                   15816: dtch5: movl    r6,r10          # recover xl ...
                   15817:        movl    r7,r9           # ... and xr
                   15818:        addl2   $4*trval,r10    # point to value field
                   15819:        jmp     dtch2           # continue
                   15820: #
                   15821: #      EXIT POINT
                   15822: #
                   15823: dtch6: movl    dtcnb,r9        # possible vrblk ptr
                   15824:        jsb     setvr           # reset vrblk if necessary
                   15825:        rsb                     # return
                   15826:        #enp                    # end procedure dtach
                   15827:        #page   
                   15828: #
                   15829: #      DTYPE -- GET DATATYPE NAME
                   15830: #
                   15831: #      (XR)                  OBJECT WHOSE DATATYPE IS REQUIRED
                   15832: #      JSR  DTYPE            CALL TO GET DATATYPE
                   15833: #      (XR)                  RESULT DATATYPE
                   15834: #
                   15835: dtype: #prc                    # entry point
                   15836:        cmpl    (r9),$b$pdt     # jump if prog.defined
                   15837:        beqlu   dtyp1
                   15838:        movl    (r9),r9         # load type word
                   15839:        movzwl  -2(r9),r9       # get entry point id (block code)
                   15840:        moval   0[r9],r9        # convert to byte offset
                   15841:        movl    l^scnmt(r9),r9  # load table entry
                   15842:        rsb                     # exit to dtype caller
                   15843: #
                   15844: #      HERE IF PROGRAM DEFINED
                   15845: #
                   15846: dtyp1: movl    4*pddfp(r9),r9  # point to dfblk
                   15847:        movl    4*dfnam(r9),r9  # get datatype name from dfblk
                   15848:        rsb                     # return to dtype caller
                   15849:        #enp                    # end procedure dtype
                   15850:        #page   
                   15851: #
                   15852: #      DUMPR -- PRINT DUMP OF STORAGE
                   15853: #
                   15854: #      (XR)                  DUMP ARGUMENT (SEE BELOW)
                   15855: #      JSR  DUMPR            CALL TO PRINT DUMP
                   15856: #      (XR,XL)               DESTROYED
                   15857: #      (WA,WB,WC,RA)         DESTROYED
                   15858: #
                   15859: #      THE DUMP ARGUMENT HAS THE FOLLOWING SIGNIFICANCE
                   15860: #
                   15861: #      DMARG = 0             NO DUMP PRINTED
                   15862: #      DMARG = 1             PARTIAL DUMP (NAT VARS, KEYWORDS)
                   15863: #      DMARG EQ 2            FULL DUMP (INCL ARRAYS ETC.)
                   15864: #      DMARG GE 3            CORE DUMP
                   15865: #
                   15866: #      SINCE DUMPR SCRAMBLES STORE, IT IS NOT PERMISSIBLE TO
                   15867: #      COLLECT IN MID-DUMP. HENCE A COLLECT IS DONE INITIALLY
                   15868: #      AND THEN IF STORE RUNS OUT AN ERROR MESSAGE IS PRODUCED.
                   15869: #
                   15870: dumpr: #prc                    # entry point
                   15871:        tstl    r9              # skip dump if argument is zero
                   15872:        bnequ   0f
                   15873:        jmp     dmp28
                   15874: 0:             
                   15875:        cmpl    r9,$num02       # jump if core dump required
                   15876:        blequ   0f
                   15877:        jmp     dmp29
                   15878: 0:             
                   15879:        clrl    r10             # clear xl
                   15880:        clrl    r7              # zero move offset
                   15881:        movl    r9,dmarg        # save dump argument
                   15882:        jsb     gbcol           # collect garbage
                   15883:        jsb     prtpg           # eject printer
                   15884:        movl    $dmhdv,r9       # point to heading for variables
                   15885:        jsb     prtst           # print it
                   15886:        jsb     prtnl           # terminate print line
                   15887:        jsb     prtnl           # and print a blank line
                   15888: #
                   15889: #      FIRST ALL NATURAL VARIABLE BLOCKS (VRBLK) WHOSE VALUES
                   15890: #      ARE NON-NULL ARE LINKED IN LEXICAL ORDER USING DMVCH AS
                   15891: #      THE CHAIN HEAD AND CHAINING THROUGH THE VRGET FIELDS.
                   15892: #      NOTE THAT THIS SCRAMBLES STORE IF THE PROCESS IS
                   15893: #      INTERRUPTED BEFORE COMPLETION E.G. BY EXCEEDING TIME  OR
                   15894: #      PRINT LIMITS. SINCE THE SUBSEQUENT CORE DUMPS AND
                   15895: #      FAILURES IF EXECUTION IS RESUMED ARE VERY CONFUSING, THE
                   15896: #      EXECUTION TIME ERROR ROUTINE CHECKS FOR THIS EVENT AND
                   15897: #      ATTEMPTS AN UNSCRAMBLE. SIMILAR PRECAUTIONS SHOULD BE
                   15898: #      OBSERVED IF TRANSLATE TIME DUMPING IS IMPLEMENTED.
                   15899: #
                   15900:        clrl    dmvch           # set null chain to start
                   15901:        movl    hshtb,r6        # point to hash table
                   15902: #
                   15903: #      LOOP THROUGH HEADERS IN HASH TABLE
                   15904: #
                   15905: dmp00: movl    r6,r9           # copy hash bucket pointer
                   15906:        addl2   $4,r6           # bump pointer
                   15907:        subl2   $4*vrnxt,r9     # set offset to merge
                   15908: #
                   15909: #      LOOP THROUGH VRBLKS ON ONE CHAIN
                   15910: #
                   15911: dmp01: movl    4*vrnxt(r9),r9  # point to next vrblk on chain
                   15912:        tstl    r9              # jump if end of this hash chain
                   15913:        bnequ   0f
                   15914:        jmp     dmp09
                   15915: 0:             
                   15916:        movl    r9,r10          # else copy vrblk pointer
                   15917:        #page   
                   15918: #
                   15919: #      DUMPR (CONTINUED)
                   15920: #
                   15921: #      LOOP TO FIND VALUE AND SKIP IF NULL
                   15922: #
                   15923: dmp02: movl    4*vrval(r10),r10# load value
                   15924:        cmpl    r10,$nulls      # loop for next vrblk if null value
                   15925:        beqlu   dmp01
                   15926:        cmpl    (r10),$b$trt    # loop back if value is trapped
                   15927:        beqlu   dmp02
                   15928: #
                   15929: #      NON-NULL VALUE, PREPARE TO SEARCH CHAIN
                   15930: #
                   15931:        movl    r9,r8           # save vrblk pointer
                   15932:        addl2   $4*vrsof,r9     # adjust ptr to be like scblk ptr
                   15933:        tstl    4*sclen(r9)     # jump if non-system variable
                   15934:        bnequ   dmp03
                   15935:        movl    4*vrsvo(r9),r9  # else load ptr to name in svblk
                   15936: #
                   15937: #      HERE WITH NAME POINTER FOR NEW BLOCK IN XR
                   15938: #
                   15939: dmp03: movl    r9,r7           # save pointer to chars
                   15940:        movl    r6,dmpsv        # save hash bucket pointer
                   15941:        movl    $dmvch,r6       # point to chain head
                   15942: #
                   15943: #      LOOP TO SEARCH CHAIN FOR CORRECT INSERTION POINT
                   15944: #
                   15945: dmp04: movl    r6,dmpch        # save chain pointer
                   15946:        movl    r6,r10          # copy it
                   15947:        movl    (r10),r9        # load pointer to next entry
                   15948:        tstl    r9              # jump if end of chain to insert
                   15949:        bnequ   0f
                   15950:        jmp     dmp08
                   15951: 0:             
                   15952:        addl2   $4*vrsof,r9     # else get name ptr for chained vrblk
                   15953:        tstl    4*sclen(r9)     # jump if not system variable
                   15954:        bnequ   dmp05
                   15955:        movl    4*vrsvo(r9),r9  # else point to name in svblk
                   15956: #
                   15957: #      HERE PREPARE TO COMPARE THE NAMES
                   15958: #
                   15959: #      (WA)                  SCRATCH
                   15960: #      (WB)                  POINTER TO STRING OF ENTERING VRBLK
                   15961: #      (WC)                  POINTER TO ENTERING VRBLK
                   15962: #      (XR)                  POINTER TO STRING OF CURRENT BLOCK
                   15963: #      (XL)                  SCRATCH
                   15964: #
                   15965: dmp05: movl    r7,r10          # point to entering vrblk string
                   15966:        movl    4*sclen(r10),r6 # load its length
                   15967:        movab   cfp$f(r10),r10  # point to chars of entering string
                   15968:        cmpl    r6,4*sclen(r9)  # jump if entering length high
                   15969:        bgequ   dmp06
                   15970:        movab   cfp$f(r9),r9    # else point to chars of old string
                   15971:        jsb     sbcmc           # compare, insert if new is llt old
                   15972:        .long   dmp08
                   15973:        .long   dmp07
                   15974:        jmp     dmp08           # or if leq (we had shorter length)
                   15975: #
                   15976: #      HERE WHEN NEW LENGTH IS LONGER THAN OLD LENGTH
                   15977: #
                   15978: dmp06: movl    4*sclen(r9),r6  # load shorter length
                   15979:        movab   cfp$f(r9),r9    # point to chars of old string
                   15980:        jsb     sbcmc           # compare, insert if new one low
                   15981:        .long   dmp08
                   15982:        .long   dmp07
                   15983:        #page   
                   15984: #
                   15985: #      DUMPR (CONTINUED)
                   15986: #
                   15987: #      HERE WE MOVE OUT ON THE CHAIN
                   15988: #
                   15989: dmp07: movl    dmpch,r10       # copy chain pointer
                   15990:        movl    (r10),r6        # move to next entry on chain
                   15991:        jmp     dmp04           # loop back
                   15992: #
                   15993: #      HERE AFTER LOCATING THE PROPER INSERTION POINT
                   15994: #
                   15995: dmp08: movl    dmpch,r10       # copy chain pointer
                   15996:        movl    dmpsv,r6        # restore hash bucket pointer
                   15997:        movl    r8,r9           # restore vrblk pointer
                   15998:        movl    (r10),4*vrget(r9)# link vrblk to rest of chain
                   15999:        movl    r9,(r10)        # link vrblk into current chain loc
                   16000:        jmp     dmp01           # loop back for next vrblk
                   16001: #
                   16002: #      HERE AFTER PROCESSING ALL VRBLKS ON ONE CHAIN
                   16003: #
                   16004: dmp09: cmpl    r6,hshte        # loop back if more buckets to go
                   16005:        beqlu   0f
                   16006:        jmp     dmp00
                   16007: 0:             
                   16008: #
                   16009: #      LOOP TO GENERATE DUMP OF NATURAL VARIABLE VALUES
                   16010: #
                   16011: dmp10: movl    dmvch,r9        # load pointer to next entry on chain
                   16012:        tstl    r9              # jump if end of chain
                   16013:        beqlu   dmp11
                   16014:        movl    (r9),dmvch      # else update chain ptr to next entry
                   16015:        jsb     setvr           # restore vrget field
                   16016:        movl    r9,r10          # copy vrblk pointer (name base)
                   16017:        movl    $4*vrval,r6     # set offset for vrblk name
                   16018:        jsb     prtnv           # print name = value
                   16019:        jmp     dmp10           # loop back till all printed
                   16020: #
                   16021: #      PREPARE TO PRINT KEYWORDS
                   16022: #
                   16023: dmp11: jsb     prtnl           # print blank line
                   16024:        jsb     prtnl           # and another
                   16025:        movl    $dmhdk,r9       # point to keyword heading
                   16026:        jsb     prtst           # print heading
                   16027:        jsb     prtnl           # end line
                   16028:        jsb     prtnl           # print one blank line
                   16029:        movl    $vdmkw,r10      # point to list of keyword svblk ptrs
                   16030:        #page   
                   16031: #
                   16032: #      DUMPR (CONTINUED)
                   16033: #
                   16034: #      LOOP TO DUMP KEYWORD VALUES
                   16035: #
                   16036: dmp12: movl    (r10)+,r9       # load next svblk ptr from table
                   16037:        tstl    r9              # jump if end of list
                   16038:        beqlu   dmp13
                   16039:        movl    $ch$am,r6       # load ampersand
                   16040:        jsb     prtch           # print ampersand
                   16041:        jsb     prtst           # print keyword name
                   16042:        movl    4*svlen(r9),r6  # load name length from svblk
                   16043:        movab   3+(4*svchs)(r6),r6 # get length of name
                   16044:        bicl2   $3,r6
                   16045:        addl2   r6,r9           # point to svknm field
                   16046:        movl    (r9),dmpkn      # store in dummy kvblk
                   16047:        movl    $tmbeb,r9       # point to blank-equal-blank
                   16048:        jsb     prtst           # print it
                   16049:        movl    r10,dmpsv       # save table pointer
                   16050:        movl    $dmpkb,r10      # point to dummy kvblk
                   16051:        movl    $4*kvvar,r6     # set zero offset
                   16052:        jsb     acess           # get keyword value
                   16053:        .long   invalid$        # failure is impossible
                   16054:        jsb     prtvl           # print keyword value
                   16055:        jsb     prtnl           # terminate print line
                   16056:        movl    dmpsv,r10       # restore table pointer
                   16057:        jmp     dmp12           # loop back till all printed
                   16058: #
                   16059: #      HERE AFTER COMPLETING PARTIAL DUMP
                   16060: #
                   16061: dmp13: cmpl    dmarg,$num01    # exit if partial dump complete
                   16062:        bnequ   0f
                   16063:        jmp     dmp27
                   16064: 0:             
                   16065:        movl    dnamb,r9        # else point to first dynamic block
                   16066: #
                   16067: #      LOOP THROUGH BLOCKS IN DYNAMIC STORAGE
                   16068: #
                   16069: dmp14: cmpl    r9,dnamp        # jump if end of used region
                   16070:        bnequ   0f
                   16071:        jmp     dmp27
                   16072: 0:             
                   16073:        movl    (r9),r6         # else load first word of block
                   16074:        cmpl    r6,$b$vct       # jump if vector
                   16075:        beqlu   dmp16
                   16076:        cmpl    r6,$b$art       # jump if array
                   16077:        beqlu   dmp17
                   16078:        cmpl    r6,$b$pdt       # jump if program defined
                   16079:        beqlu   dmp18
                   16080:        cmpl    r6,$b$tbt       # jump if table
                   16081:        beqlu   dmp19
                   16082:        cmpl    r6,$b$bct       # jump if buffer
                   16083:        bnequ   0f
                   16084:        jmp     dmp30
                   16085: 0:             
                   16086: #
                   16087: #      MERGE HERE TO MOVE TO NEXT BLOCK
                   16088: #
                   16089: dmp15: jsb     blkln           # get length of block
                   16090:        addl2   r6,r9           # point past this block
                   16091:        jmp     dmp14           # loop back for next block
                   16092:        #page   
                   16093: #
                   16094: #      DUMPR (CONTINUED)
                   16095: #
                   16096: #      HERE FOR VECTOR
                   16097: #
                   16098: dmp16: movl    $4*vcvls,r7     # set offset to first value
                   16099:        jmp     dmp19           # jump to merge
                   16100: #
                   16101: #      HERE FOR ARRAY
                   16102: #
                   16103: dmp17: movl    4*arofs(r9),r7  # set offset to arpro field
                   16104:        addl2   $4,r7           # bump to get offset to values
                   16105:        jmp     dmp19           # jump to merge
                   16106: #
                   16107: #      HERE FOR PROGRAM DEFINED
                   16108: #
                   16109: dmp18: movl    $4*pdfld,r7     # point to values, merge
                   16110: #
                   16111: #      HERE FOR TABLE (OTHERS MERGE)
                   16112: #
                   16113: dmp19: tstl    4*idval(r9)     # ignore block if zero id value
                   16114:        bnequ   0f
                   16115:        jmp     dmp15
                   16116: 0:             
                   16117:        jsb     blkln           # else get block length
                   16118:        movl    r9,r10          # copy block pointer
                   16119:        movl    r6,dmpsv        # save length
                   16120:        movl    r7,r6           # copy offset to first value
                   16121:        jsb     prtnl           # print blank line
                   16122:        movl    r6,dmpsa        # preserve offset
                   16123:        jsb     prtvl           # print block value (for title)
                   16124:        movl    dmpsa,r6        # recover offset
                   16125:        jsb     prtnl           # end print line
                   16126:        cmpl    (r9),$b$tbt     # jump if table
                   16127:        beqlu   dmp22
                   16128:        subl2   $4,r6           # point before first word
                   16129: #
                   16130: #      LOOP TO PRINT CONTENTS OF ARRAY, VECTOR, OR PROGRAM DEF
                   16131: #
                   16132: dmp20: movl    r10,r9          # copy block pointer
                   16133:        addl2   $4,r6           # bump offset
                   16134:        addl2   r6,r9           # point to next value
                   16135:        cmpl    r6,dmpsv        # exit if end (xr past block)
                   16136:        bnequ   0f
                   16137:        jmp     dmp14
                   16138: 0:             
                   16139:        subl2   $4*vrval,r9     # subtract offset to merge into loop
                   16140: #
                   16141: #      LOOP TO FIND VALUE AND IGNORE NULLS
                   16142: #
                   16143: dmp21: movl    4*vrval(r9),r9  # load next value
                   16144:        cmpl    r9,$nulls       # loop back if null value
                   16145:        beqlu   dmp20
                   16146:        cmpl    (r9),$b$trt     # loop back if trapped
                   16147:        beqlu   dmp21
                   16148:        jsb     prtnv           # else print name = value
                   16149:        jmp     dmp20           # loop back for next field
                   16150:        #page   
                   16151: #
                   16152: #      DUMPR (CONTINUED)
                   16153: #
                   16154: #      HERE TO DUMP A TABLE
                   16155: #
                   16156: dmp22: movl    $4*tbbuk,r8     # set offset to first bucket
                   16157:        movl    $4*teval,r6     # set name offset for all teblks
                   16158: #
                   16159: #      LOOP THROUGH TABLE BUCKETS
                   16160: #
                   16161: dmp23: movl    r10,-(sp)       # save tbblk pointer
                   16162:        addl2   r8,r10          # point to next bucket header
                   16163:        addl2   $4,r8           # bump bucket offset
                   16164:        subl2   $4*tenxt,r10    # subtract offset to merge into loop
                   16165: #
                   16166: #      LOOP TO PROCESS TEBLKS ON ONE CHAIN
                   16167: #
                   16168: dmp24: movl    4*tenxt(r10),r10# point to next teblk
                   16169:        cmpl    r10,(sp)        # jump if end of chain
                   16170:        beqlu   dmp26
                   16171:        movl    r10,r9          # else copy teblk pointer
                   16172: #
                   16173: #      LOOP TO FIND VALUE AND IGNORE IF NULL
                   16174: #
                   16175: dmp25: movl    4*teval(r9),r9  # load next value
                   16176:        cmpl    r9,$nulls       # ignore if null value
                   16177:        beqlu   dmp24
                   16178:        cmpl    (r9),$b$trt     # loop back if trapped
                   16179:        beqlu   dmp25
                   16180:        movl    r8,dmpsv        # else save offset pointer
                   16181:        jsb     prtnv           # print name = value
                   16182:        movl    dmpsv,r8        # reload offset
                   16183:        jmp     dmp24           # loop back for next teblk
                   16184: #
                   16185: #      HERE TO MOVE TO NEXT HASH CHAIN
                   16186: #
                   16187: dmp26: movl    (sp)+,r10       # restore tbblk pointer
                   16188:        cmpl    r8,4*tblen(r10) # loop back if more buckets to go
                   16189:        bnequ   dmp23
                   16190:        movl    r10,r9          # else copy table pointer
                   16191:        addl2   r8,r9           # point to following block
                   16192:        jmp     dmp14           # loop back to process next block
                   16193: #
                   16194: #      HERE AFTER COMPLETING DUMP
                   16195: #
                   16196: dmp27: jsb     prtpg           # eject printer
                   16197: #
                   16198: #      MERGE HERE IF NO DUMP GIVEN (DMARG=0)
                   16199: #
                   16200: dmp28: rsb                     # return to dump caller
                   16201: #
                   16202: #      CALL SYSTEM CORE DUMP ROUTINE
                   16203: #
                   16204: dmp29: jsb     sysdm           # call it
                   16205:        jmp     dmp28           # return
                   16206:        #page   
                   16207: #
                   16208: #      DUMPR (CONTINUED)
                   16209: #
                   16210: #      HERE TO DUMP BUFFER BLOCK
                   16211: #
                   16212: dmp30: jsb     prtnl           # print blank line
                   16213:        jsb     prtvl           # print value id for title
                   16214:        jsb     prtnl           # force new line
                   16215:        movl    $ch$dq,r6       # load double quote
                   16216:        jsb     prtch           # print it
                   16217:        movl    4*bclen(r9),r8  # load defined length
                   16218:        tstl    r8              # skip characters if none
                   16219:        beqlu   dmp32
                   16220:                                # load count for loop
                   16221:        movl    r9,r7           # save bcblk ptr
                   16222:        movl    4*bcbuf(r9),r9  # point to bfblk
                   16223:        movab   cfp$f(r9),r9    # get set to load characters
                   16224: #
                   16225: #      LOOP HERE STUFFING CHARACTERS IN OUTPUT STREAM
                   16226: #
                   16227: dmp31: movzbl  (r9)+,r6        # get next character
                   16228:        jsb     prtch           # stuff it
                   16229:        sobgtr  r8,dmp31        # branch for next one
                   16230:        movl    r7,r9           # restore bcblk pointer
                   16231: #
                   16232: #      MERGE TO STUFF CLOSING QUOTE MARK
                   16233: #
                   16234: dmp32: movl    $ch$dq,r6       # stuff quote
                   16235:        jsb     prtch           # print it
                   16236:        jsb     prtnl           # print new line
                   16237:        movl    (r9),r6         # get first wd for blkln
                   16238:        jmp     dmp15           # merge to get next block
                   16239:        #enp                    # end procedure dumpr
                   16240:        #page   
                   16241: #
                   16242: #      ERMSG -- PRINT ERROR CODE AND ERROR MESSAGE
                   16243: #
                   16244: #      KVERT                 ERROR CODE
                   16245: #      JSR  ERMSG            CALL TO PRINT MESSAGE
                   16246: #      (XR,XL,WA,WB,WC,IA)   DESTROYED
                   16247: #
                   16248: ermsg: #prc                    # entry point
                   16249:        jsb     prtis           # print error ptr or blank line
                   16250:        movl    kvert,r6        # load error code
                   16251:        movl    $ermms,r9       # point to error message /error/
                   16252:        jsb     prtst           # print it
                   16253:        jsb     ertex           # get error message text
                   16254:        addl2   $thsnd,r6       # bump error code for print
                   16255:        movl    r6,r5           # fail code in int acc
                   16256:        jsb     prtin           # print code (now have error1xxx)
                   16257:        movl    prbuf,r10       # point to print buffer
                   16258:        movl    $num05,r11      # [get in scratch register]
                   16259:        movab   cfp$f(r10)[r11],r10 # point to the 1
                   16260:        movl    $ch$bl,r6       # load a blank
                   16261:        movb    r6,(r10)        # store blank over 1 (error xxx)
                   16262:        #csc    r10             # complete store characters
                   16263:        clrl    r10             # clear garbage pointer in xl
                   16264:        movl    r9,r6           # keep error text
                   16265:        movl    $ermns,r9       # point to / -- /
                   16266:        jsb     prtst           # print it
                   16267:        movl    r6,r9           # get error text again
                   16268:        jsb     prtst           # print error message text
                   16269:        jsb     prtis           # print line
                   16270:        jsb     prtis           # print blank line
                   16271:        rsb                     # return to ermsg caller
                   16272:        #enp                    # end procedure ermsg
                   16273:        #page   
                   16274: #
                   16275: #      ERTEX -- GET ERROR MESSAGE TEXT
                   16276: #
                   16277: #      (WA)                  ERROR CODE
                   16278: #      JSR  ERTEX            CALL TO GET ERROR TEXT
                   16279: #      (XR)                  PTR TO ERROR TEXT IN DYNAMIC
                   16280: #      (R$ETX)               COPY OF PTR TO ERROR TEXT
                   16281: #      (XL,WC,IA)            DESTROYED
                   16282: #
                   16283: ertex: #prc                    # entry point
                   16284:        movl    r6,ertwa        # save wa
                   16285:        movl    r7,ertwb        # save wb
                   16286:        jsb     sysem           # get failure message text
                   16287:        movl    r9,r10          # copy pointer to it
                   16288:        movl    4*sclen(r9),r6  # get length of string
                   16289:        tstl    r6              # jump if null
                   16290:        beqlu   ert02
                   16291:        clrl    r7              # offset of zero
                   16292:        jsb     sbstr           # copy into dynamic store
                   16293:        movl    r9,r$etx        # store for relocation
                   16294: #
                   16295: #      RETURN
                   16296: #
                   16297: ert01: movl    ertwb,r7        # restore wb
                   16298:        movl    ertwa,r6        # restore wa
                   16299:        rsb                     # return to caller
                   16300: #
                   16301: #      RETURN ERRTEXT CONTENTS INSTEAD OF NULL
                   16302: #
                   16303: ert02: movl    r$etx,r9        # get errtext
                   16304:        jmp     ert01           # return
                   16305:        #enp    
                   16306:        #page   
                   16307: #
                   16308: #      EVALI -- EVALUATE INTEGER ARGUMENT
                   16309: #
                   16310: #      EVALI IS USED BY PATTERN PRIMITIVES LEN,TAB,RTAB,POS,RPOS
                   16311: #      WHEN THEIR ARGUMENT IS AN EXPRESSION VALUE.
                   16312: #
                   16313: #      (XR)                  NODE POINTER
                   16314: #      (WB)                  CURSOR
                   16315: #      JSR  EVALI            CALL TO EVALUATE INTEGER
                   16316: #      PPM  LOC              TRANSFER LOC FOR NON-INTEGER ARG
                   16317: #      PPM  LOC              TRANSFER LOC FOR OUT OF RANGE ARG
                   16318: #      PPM  LOC              TRANSFER LOC FOR EVALUATION FAILURE
                   16319: #      PPM  LOC              TRANSFER LOC FOR SUCCESSFUL EVAL
                   16320: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   16321: #      (XR)                  PTR TO NODE WITH INTEGER ARGUMENT
                   16322: #      (WC,XL,RA)            DESTROYED
                   16323: #
                   16324: #      ON RETURN, THE NODE POINTED TO HAS THE INTEGER ARGUMENT
                   16325: #      IN PARM1 AND THE PROPER SUCCESSOR POINTER IN PTHEN.
                   16326: #      THIS ALLOWS MERGING WITH THE NORMAL (INTEGER ARG) CASE.
                   16327: #
                   16328: evali: #prc                    # entry point (recursive)
                   16329:        jsb     evalp           # evaluate expression
                   16330:        .long   evli1           # jump on failure
                   16331:        movl    r10,-(sp)       # stack result for gtsmi
                   16332:        movl    4*pthen(r9),r10 # load successor pointer
                   16333:        jsb     gtsmi           # convert arg to small integer
                   16334:        .long   evli2           # jump if not integer
                   16335:        .long   evli3           # jump if out of range
                   16336:        movl    r9,evliv        # store result in special dummy node
                   16337:        movl    r10,evlis       # store successor pointer
                   16338:        movl    $evlin,r9       # point to dummy node with result
                   16339:        addl3   $4*3,(sp)+,r11  # take successful exit
                   16340:        jmp     *(r11)+
                   16341: #
                   16342: #      HERE IF EVALUATION FAILS
                   16343: #
                   16344: evli1: addl3   $4*2,(sp)+,r11  # take failure return
                   16345:        jmp     *(r11)+
                   16346: #
                   16347: #      HERE IF ARGUMENT IS NOT INTEGER
                   16348: #
                   16349: evli2: movl    (sp)+,r11       # take non-integer error exit
                   16350:        jmp     *(r11)+
                   16351: #
                   16352: #      HERE IF ARGUMENT IS OUT OF RANGE
                   16353: #
                   16354: evli3: addl3   $4*1,(sp)+,r11  # take out-of-range error exit
                   16355:        jmp     *(r11)+
                   16356:        #enp                    # end procedure evali
                   16357:        #page   
                   16358: #
                   16359: #      EVALP -- EVALUATE EXPRESSION DURING PATTERN MATCH
                   16360: #
                   16361: #      EVALP IS USED TO EVALUATE AN EXPRESSION (BY VALUE) DURING
                   16362: #      A PATTERN MATCH. THE EFFECT IS LIKE EVALX, BUT PATTERN
                   16363: #      VARIABLES ARE STACKED AND RESTORED IF NECESSARY.
                   16364: #
                   16365: #      EVALP ALSO DIFFERS FROM EVALX IN THAT IF THE RESULT IS
                   16366: #      AN EXPRESSION IT IS REEVALUATED. THIS OCCURS REPEATEDLY.
                   16367: #
                   16368: #      (XR)                  NODE POINTER
                   16369: #      (WB)                  PATTERN MATCH CURSOR
                   16370: #      JSR  EVALP            CALL TO EVALUATE EXPRESSION
                   16371: #      PPM  LOC              TRANSFER LOC IF EVALUATION FAILS
                   16372: #      (XL)                  RESULT
                   16373: #      (WA)                  FIRST WORD OF RESULT BLOCK
                   16374: #      (XR,WB)               DESTROYED (FAILURE CASE ONLY)
                   16375: #      (WC,RA)               DESTROYED
                   16376: #
                   16377: #      THE EXPRESSION POINTER IS STORED IN PARM1 OF THE NODE
                   16378: #
                   16379: #      CONTROL RETURNS TO FAILP ON FAILURE OF EVALUATION
                   16380: #
                   16381: evalp: #prc                    # entry point (recursive)
                   16382:        movl    4*parm1(r9),r10 # load expression pointer
                   16383:        cmpl    (r10),$b$exl    # jump if exblk case
                   16384:        beqlu   evlp1
                   16385: #
                   16386: #      HERE FOR CASE OF SEBLK
                   16387: #
                   16388: #      WE CAN GIVE A FAST RETURN IF THE VALUE OF THE VRBLK IS
                   16389: #      NOT AN EXPRESSION AND IS NOT TRAPPED.
                   16390: #
                   16391:        movl    4*sevar(r10),r10# load vrblk pointer
                   16392:        movl    4*vrval(r10),r10# load value of vrblk
                   16393:        movl    (r10),r6        # load first word of value
                   16394:        cmpl    r6,$b$t$$       # jump if not seblk, trblk or exblk
                   16395:        bgequ   evlp3
                   16396: #
                   16397: #      HERE FOR EXBLK OR SEBLK WITH EXPR VALUE OR TRAPPED VALUE
                   16398: #
                   16399: evlp1: movl    r9,-(sp)        # stack node pointer
                   16400:        movl    r7,-(sp)        # stack cursor
                   16401:        movl    r$pms,-(sp)     # stack subject string pointer
                   16402:        movl    pmssl,-(sp)     # stack subject string length
                   16403:        movl    pmdfl,-(sp)     # stack dot flag
                   16404:        movl    pmhbs,-(sp)     # stack history stack base pointer
                   16405:        movl    4*parm1(r9),r9  # load expression pointer
                   16406:        #page   
                   16407: #
                   16408: #      EVALP (CONTINUED)
                   16409: #
                   16410: #      LOOP BACK HERE TO REEVALUATE EXPRESSION RESULT
                   16411: #
                   16412: evlp2: clrl    r7              # set flag for by value
                   16413:        jsb     evalx           # evaluate expression
                   16414:        .long   evlp4           # jump on failure
                   16415:        movl    (r9),r6         # else load first word of value
                   16416:        cmpl    r6,$b$e$$       # loop back to reevaluate expression
                   16417:        blequ   evlp2
                   16418: #
                   16419: #      HERE TO RESTORE PATTERN VALUES AFTER SUCCESSFUL EVAL
                   16420: #
                   16421:        movl    r9,r10          # copy result pointer
                   16422:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   16423:        movl    (sp)+,pmdfl     # restore dot flag
                   16424:        movl    (sp)+,pmssl     # restore subject string length
                   16425:        movl    (sp)+,r$pms     # restore subject string pointer
                   16426:        movl    (sp)+,r7        # restore cursor
                   16427:        movl    (sp)+,r9        # restore node pointer
                   16428: #
                   16429: #      COMMON EXIT POINT
                   16430: #
                   16431: evlp3: addl2   $4*1,(sp)       # return to evalp caller
                   16432:        rsb     
                   16433: #
                   16434: #      HERE FOR FAILURE DURING EVALUATION
                   16435: #
                   16436: evlp4: movl    (sp)+,pmhbs     # restore history stack base pointer
                   16437:        movl    (sp)+,pmdfl     # restore dot flag
                   16438:        movl    (sp)+,pmssl     # restore subject string length
                   16439:        movl    (sp)+,r$pms     # restore subject string pointer
                   16440:        addl2   $4*num02,sp     # remove node ptr, cursor
                   16441:        movl    (sp)+,r11       # take failure exit
                   16442:        jmp     *(r11)+
                   16443:        #enp                    # end procedure evalp
                   16444:        #page   
                   16445: #
                   16446: #      EVALS -- EVALUATE STRING ARGUMENT
                   16447: #
                   16448: #      EVALS IS USED BY SPAN, ANY, NOTANY, BREAK, BREAKX WHEN
                   16449: #      THEY ARE PASSED AN EXPRESSION ARGUMENT.
                   16450: #
                   16451: #      (XR)                  NODE POINTER
                   16452: #      (WB)                  CURSOR
                   16453: #      JSR  EVALS            CALL TO EVALUATE STRING
                   16454: #      PPM  LOC              TRANSFER LOC FOR NON-STRING ARG
                   16455: #      PPM  LOC              TRANSFER LOC FOR EVALUATION FAILURE
                   16456: #      PPM  LOC              TRANSFER LOC FOR SUCCESSFUL EVAL
                   16457: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   16458: #      (XR)                  PTR TO NODE WITH PARMS SET
                   16459: #      (XL,WC,RA)            DESTROYED
                   16460: #
                   16461: #      ON RETURN, THE NODE POINTED TO HAS A CHARACTER TABLE
                   16462: #      POINTER IN PARM1 AND A BIT MASK IN PARM2. THE PROPER
                   16463: #      SUCCESSOR IS STORED IN PTHEN OF THIS NODE. THUS IT IS
                   16464: #      OK FOR MERGING WITH THE NORMAL (MULTI-CHAR STRING) CASE.
                   16465: #
                   16466: evals: #prc                    # entry point (recursive)
                   16467:        jsb     evalp           # evaluate expression
                   16468:        .long   evls1           # jump if evaluation fails
                   16469:        movl    4*pthen(r9),-(sp)# save successor pointer
                   16470:        movl    r7,-(sp)        # save cursor
                   16471:        movl    r10,-(sp)       # stack result ptr for patst
                   16472:        clrl    r7              # dummy pcode for one char string
                   16473:        clrl    r8              # dummy pcode for expression arg
                   16474:        movl    $p$brk,r10      # appropriate pcode for our use
                   16475:        jsb     patst           # call routine to build node
                   16476:        .long   evls2           # jump if not string
                   16477:        movl    (sp)+,r7        # restore cursor
                   16478:        movl    (sp)+,4*pthen(r9)# store successor pointer
                   16479:        addl3   $4*2,(sp)+,r11  # take success return
                   16480:        jmp     *(r11)+
                   16481: #
                   16482: #      HERE IF EVALUATION FAILS
                   16483: #
                   16484: evls1: addl3   $4*1,(sp)+,r11  # take failure return
                   16485:        jmp     *(r11)+
                   16486: #
                   16487: #      HERE IF ARGUMENT IS NOT STRING
                   16488: #
                   16489: evls2: addl2   $4*num02,sp     # pop successor and cursor
                   16490:        movl    (sp)+,r11       # take non-string error exit
                   16491:        jmp     *(r11)+
                   16492:        #enp                    # end procedure evals
                   16493:        #page   
                   16494: #
                   16495: #      EVALX -- EVALUATE EXPRESSION
                   16496: #
                   16497: #      EVALX IS CALLED TO EVALUATE AN EXPRESSION
                   16498: #
                   16499: #      (XR)                  POINTER TO EXBLK OR SEBLK
                   16500: #      (WB)                  0 IF BY VALUE, 1 IF BY NAME
                   16501: #      JSR  EVALX            CALL TO EVALUATE EXPRESSION
                   16502: #      PPM  LOC              TRANSFER LOC IF EVALUATION FAILS
                   16503: #      (XR)                  RESULT IF CALLED BY VALUE
                   16504: #      (XL,WA)               RESULT NAME BASE,OFFSET IF BY NAME
                   16505: #      (XR)                  DESTROYED (NAME CASE ONLY)
                   16506: #      (XL,WA)               DESTROYED (VALUE CASE ONLY)
                   16507: #      (WB,WC,RA)            DESTROYED
                   16508: #
                   16509: evalx: #prc                    # entry point, recursive
                   16510:        cmpl    (r9),$b$exl     # jump if exblk case
                   16511:        beqlu   evlx2
                   16512: #
                   16513: #      HERE FOR SEBLK
                   16514: #
                   16515:        movl    4*sevar(r9),r10 # load vrblk pointer (name base)
                   16516:        movl    $4*vrval,r6     # set name offset
                   16517:        tstl    r7              # jump if called by name
                   16518:        beqlu   0f
                   16519:        jmp     evlx1
                   16520: 0:             
                   16521:        jsb     acess           # call routine to access value
                   16522:        .long   evlx9           # jump if failure on access
                   16523: #
                   16524: #      MERGE HERE TO EXIT FOR SEBLK CASE
                   16525: #
                   16526: evlx1: addl2   $4*1,(sp)       # return to evalx caller
                   16527:        rsb     
                   16528:        #page   
                   16529: #
                   16530: #      EVALX (CONTINUED)
                   16531: #
                   16532: #      HERE FOR FULL EXPRESSION (EXBLK) CASE
                   16533: #
                   16534: #      IF AN ERROR OCCURS IN THE EXPRESSION CODE AT EXECUTION
                   16535: #      TIME, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   16536: #      WITHOUT RETURNING TO THIS ROUTINE.
                   16537: #      THE FOLLOWING ENTRIES ARE MADE ON THE STACK BEFORE
                   16538: #      GIVING CONTROL TO THE EXPRESSION CODE
                   16539: #
                   16540: #                            EVALX RETURN POINT
                   16541: #                            SAVED VALUE OF R$COD
                   16542: #                            CODE POINTER (-R$COD)
                   16543: #                            SAVED VALUE OF FLPTR
                   16544: #                            0 IF BY VALUE, 1 IF BY NAME
                   16545: #      FLPTR --------------- *EXFLC, FAIL OFFSET IN EXBLK
                   16546: #
                   16547: evlx2: movl    r3,r8           # get code pointer
                   16548:        movl    r$cod,r6        # load code block pointer
                   16549:        subl2   r6,r8           # get code pointer as offset
                   16550:        movl    r6,-(sp)        # stack old code block pointer
                   16551:        movl    r8,-(sp)        # stack relative code offset
                   16552:        movl    flptr,-(sp)     # stack old failure pointer
                   16553:        movl    r7,-(sp)        # stack name/value indicator
                   16554:        movl    $4*exflc,-(sp)  # stack new fail offset
                   16555:        movl    flptr,gtcef     # keep in case of error
                   16556:        movl    r$cod,r$gtc     # keep code block pointer similarly
                   16557:        movl    sp,flptr        # set new failure pointer
                   16558:        movl    r9,r$cod        # set new code block pointer
                   16559:        movl    kvstn,4*exstm(r9)# remember stmnt number
                   16560:        addl2   $4*excod,r9     # point to first code word
                   16561:        movl    r9,r3           # set code pointer
                   16562:        cmpl    stage,$stgxt    # jump if not execution time
                   16563:        beqlu   0f
                   16564:        jmp     exits
                   16565: 0:             
                   16566:        movl    $stgee,stage    # evaluating expression
                   16567:        jmp     exits           # jump to execute first code word
                   16568:        #page   
                   16569: #
                   16570: #      EVALX (CONTINUED)
                   16571: #
                   16572: #      COME HERE IF SUCCESSFUL RETURN BY VALUE (SEE O$RVL)
                   16573: #
                   16574: evlx3: movl    (sp)+,r9        # load value
                   16575:        tstl    4*1(sp) # jump if called by value
                   16576:        beqlu   evlx5
                   16577:        jmp     er_249          # expression evaluated by name returned value
                   16578: #
                   16579: #      HERE FOR EXPRESSION RETURNING BY NAME (SEE O$RNM)
                   16580: #
                   16581: evlx4: movl    (sp)+,r6        # load name offset
                   16582:        movl    (sp)+,r10       # load name base
                   16583:        tstl    4*1(sp) # jump if called by name
                   16584:        bnequ   evlx5
                   16585:        jsb     acess           # else access value first
                   16586:        .long   evlx6           # jump if failure during access
                   16587: #
                   16588: #      HERE AFTER LOADING CORRECT RESULT INTO XR OR XL,WA
                   16589: #
                   16590: evlx5: clrl    r7              # note successful
                   16591:        jmp     evlx7           # merge
                   16592: #
                   16593: #      HERE FOR FAILURE IN EXPRESSION EVALUATION (SEE O$FEX)
                   16594: #
                   16595: evlx6: movl    sp,r7           # note unsuccessful
                   16596: #
                   16597: #      RESTORE ENVIRONMENT
                   16598: #
                   16599: evlx7: cmpl    stage,$stgee    # skip if was not previously xt
                   16600:        bnequ   evlx8
                   16601:        movl    $stgxt,stage    # execute time
                   16602: #
                   16603: #      MERGE WITH STAGE SET UP
                   16604: #
                   16605: evlx8: addl2   $4*num02,sp     # pop name/value indicator, *exfal
                   16606:        movl    (sp)+,flptr     # restore old failure pointer
                   16607:        movl    (sp)+,r8        # load code offset
                   16608:        addl2   (sp),r8         # make code pointer absolute
                   16609:        movl    (sp)+,r$cod     # restore old code block pointer
                   16610:        movl    r8,r3           # restore old code pointer
                   16611:        tstl    r7              # jump for successful return
                   16612:        bnequ   0f
                   16613:        jmp     evlx1
                   16614: 0:             
                   16615: #
                   16616: #      MERGE HERE FOR FAILURE IN SEBLK CASE
                   16617: #
                   16618: evlx9: movl    (sp)+,r11       # take failure exit
                   16619:        jmp     *(r11)+
                   16620:        #enp                    # end of procedure evalx
                   16621:        #page   
                   16622: #
                   16623: #      EXBLD -- BUILD EXBLK
                   16624: #
                   16625: #      EXBLD IS USED TO BUILD AN EXPRESSION BLOCK FROM THE
                   16626: #      CODE COMPILED MOST RECENTLY IN THE CURRENT CCBLK.
                   16627: #
                   16628: #      (XL)                  OFFSET IN CCBLK TO START OF CODE
                   16629: #      (WB)                  INTEGER IN RANGE 0 LE N LE MXLEN
                   16630: #      JSR  EXBLD            CALL TO BUILD EXBLK
                   16631: #      (XR)                  PTR TO CONSTRUCTED EXBLK
                   16632: #      (WA,WB,XL)            DESTROYED
                   16633: #
                   16634: exbld: #prc                    # entry point
                   16635:        movl    r10,r6          # copy offset to start of code
                   16636:        subl2   $4*excod,r6     # calc reduction in offset in exblk
                   16637:        movl    r6,-(sp)        # stack for later
                   16638:        movl    cwcof,r6        # load final offset
                   16639:        subl2   r10,r6          # compute length of code
                   16640:        addl2   $4*exsi$,r6     # add space for standard fields
                   16641:        jsb     alloc           # allocate space for exblk
                   16642:        movl    r9,-(sp)        # save pointer to exblk
                   16643:        movl    $b$exl,4*extyp(r9) # store type word
                   16644:        clrl    4*exstm(r9)     # zeroise stmnt number field
                   16645:        movl    r6,4*exlen(r9)  # store length
                   16646:        movl    $ofex$,4*exflc(r9) # store failure word
                   16647:        addl2   $4*exsi$,r9     # set xr for sysmw
                   16648:        movl    r10,cwcof       # reset offset to start of code
                   16649:        addl2   r$ccb,r10       # point to start of code
                   16650:        subl2   $4*exsi$,r6     # length of code to move
                   16651:        movl    r6,-(sp)        # stack length of code
                   16652:        jsb     sbmvw           # move code to exblk
                   16653:        movl    (sp)+,r6        # get length of code
                   16654:        ashl    $-2,r6,r6       # convert byte count to word count
                   16655:                                # prepare counter for loop
                   16656:        movl    (sp),r10        # copy exblk ptr, dont unstack
                   16657:        addl2   $4*excod,r10    # point to code itself
                   16658:        movl    4*1(sp),r7      # get reduction in offset
                   16659: #
                   16660: #      THIS LOOP SEARCHES FOR NEGATION AND SELECTION CODE SO
                   16661: #      THAT THE OFFSETS COMPUTED WHILST CODE WAS IN CODE BLOCK
                   16662: #      CAN BE TRANSFORMED TO REDUCED VALUES APPLICABLE IN AN
                   16663: #      EXBLK.
                   16664: #
                   16665: exbl1: movl    (r10)+,r9       # get next code word
                   16666:        cmpl    r9,$osla$       # jump if selection found
                   16667:        beqlu   exbl3
                   16668:        cmpl    r9,$onta$       # jump if negation found
                   16669:        beqlu   exbl3
                   16670:        sobgtr  r6,exbl1        # loop to end of code
                   16671: #
                   16672: #      NO SELECTION FOUND OR MERGE TO EXIT ON TERMINATION
                   16673: #
                   16674: exbl2: movl    (sp)+,r9        # pop exblk ptr into xr
                   16675:        movl    (sp)+,r10       # pop reduction constant
                   16676:        rsb                     # return to caller
                   16677:        #page   
                   16678: #
                   16679: #      EXBLD (CONTINUED)
                   16680: #
                   16681: #      SELECTION OR NEGATION FOUND
                   16682: #      REDUCE THE OFFSETS AS NEEDED. OFFSETS OCCUR IN WORDS
                   16683: #      FOLLOWING CODE WORDS -
                   16684: #           =ONTA$, =OSLA$, =OSLB$, =OSLC$
                   16685: #
                   16686: exbl3: subl2   r7,(r10)+       # adjust offset
                   16687:        sobgtr  r6,exbl4        # decrement count
                   16688: #
                   16689: exbl4: sobgtr  r6,exbl5        # decrement count
                   16690: #
                   16691: #      CONTINUE SEARCH FOR MORE OFFSETS
                   16692: #
                   16693: exbl5: movl    (r10)+,r9       # get next code word
                   16694:        cmpl    r9,$osla$       # jump if offset found
                   16695:        beqlu   exbl3
                   16696:        cmpl    r9,$oslb$       # jump if offset found
                   16697:        beqlu   exbl3
                   16698:        cmpl    r9,$oslc$       # jump if offset found
                   16699:        beqlu   exbl3
                   16700:        cmpl    r9,$onta$       # jump if offset found
                   16701:        beqlu   exbl3
                   16702:        sobgtr  r6,exbl5        # loop
                   16703:        jmp     exbl2           # merge to return
                   16704:        #enp                    # end procedure exbld
                   16705:        #page   
                   16706: #
                   16707: #      EXPAN -- ANALYZE EXPRESSION
                   16708: #
                   16709: #      THE EXPRESSION ANALYZER (EXPAN) PROCEDURE IS USED TO SCAN
                   16710: #      AN EXPRESSION AND CONVERT IT INTO A TREE REPRESENTATION.
                   16711: #      SEE DESCRIPTIONS OF CMBLK, CUBLK, CBBLK IN THE STRUCTURES
                   16712: #      SECTION FOR DETAILED FORMAT OF TREE BLOCKS.
                   16713: #
                   16714: #      THE ANALYZER USES A SIMPLE PRECEDENCE SCHEME IN WHICH
                   16715: #      OPERANDS AND OPERATORS ARE PLACED ON A SINGLE STACK
                   16716: #      AND CONDENSATIONS ARE MADE WHEN LOW PRECEDENCE OPERATORS
                   16717: #      ARE STACKED AFTER A HIGHER PRECEDENCE OPERATOR. A GLOBAL
                   16718: #      VARIABLE (IN WB) KEEPS TRACK OF THE LEVEL AS FOLLOWS.
                   16719: #
                   16720: #      0    SCANNING OUTER LEVEL OF STATEMENT OR EXPRESSION
                   16721: #      1    SCANNING OUTER LEVEL OF NORMAL GOTO
                   16722: #      2    SCANNING OUTER LEVEL OF DIRECT GOTO
                   16723: #      3    SCANNING INSIDE ARRAY BRACKETS
                   16724: #      4    SCANNING INSIDE GROUPING PARENTHESES
                   16725: #      5    SCANNING INSIDE FUNCTION PARENTHESES
                   16726: #
                   16727: #      THIS VARIABLE IS SAVED ON THE STACK ON ENCOUNTERING A
                   16728: #      GROUPING AND RESTORED AT THE END OF THE GROUPING.
                   16729: #
                   16730: #      ANOTHER GLOBAL VARIABLE (IN WC) COUNTS THE NUMBER OF
                   16731: #      ITEMS AT ONE GROUPING LEVEL AND IS INCREMENTED FOR EACH
                   16732: #      COMMA ENCOUNTERED. IT IS STACKED WITH THE LEVEL INDICATOR
                   16733: #
                   16734: #      THE SCAN IS CONTROLLED BY A THREE STATE FINITE MACHINE.
                   16735: #      A GLOBAL VARIABLE STORED IN WA IS THE CURRENT STATE.
                   16736: #
                   16737: #      WA=0                  NOTHING SCANNED AT THIS LEVEL
                   16738: #      WA=1                  OPERAND EXPECTED
                   16739: #      WA=2                  OPERATOR EXPECTED
                   16740: #
                   16741: #      (WB)                  CALL TYPE (SEE BELOW)
                   16742: #      JSR  EXPAN            CALL TO ANALYZE EXPRESSION
                   16743: #      (XR)                  POINTER TO RESULTING TREE
                   16744: #      (XL,WA,WB,WC,RA)      DESTROYED
                   16745: #
                   16746: #      THE ENTRY VALUE OF WB INDICATES THE CALL TYPE AS FOLLOWS.
                   16747: #
                   16748: #      0    SCANNING EITHER THE MAIN BODY OF A STATEMENT OR THE
                   16749: #           TEXT OF AN EXPRESSION (FROM EVAL CALL). VALID
                   16750: #           TERMINATORS ARE COLON, SEMICOLON. THE RESCAN FLAG IS
                   16751: #           SET TO RETURN THE TERMINATOR ON THE NEXT SCANE CALL.
                   16752: #
                   16753: #      1    SCANNING A NORMAL GOTO. THE ONLY VALID
                   16754: #           TERMINATOR IS A RIGHT PAREN.
                   16755: #
                   16756: #      2    SCANNING A DIRECT GOTO. THE ONLY VALID
                   16757: #           TERMINATOR IS A RIGHT BRACKET.
                   16758:        #page   
                   16759: #
                   16760: #      EXPAN (CONTINUED)
                   16761: #
                   16762: #      ENTRY POINT
                   16763: #
                   16764: expan: #prc                    # entry point
                   16765:        clrl    -(sp)           # set top of stack indicator
                   16766:        clrl    r6              # set initial state to zero
                   16767:        clrl    r8              # zero counter value
                   16768: #
                   16769: #      LOOP HERE FOR SUCCESSIVE ENTRIES
                   16770: #
                   16771: exp01: jsb     scane           # scan next element
                   16772:        addl2   r6,r10          # add state to syntax code
                   16773:        casel   r10,$0,$t$nes   # switch on element type/state
                   16774: 5:             
                   16775:        .word   exp27-5b        # unop, s=0
                   16776:        .word   exp27-5b        # unop, s=1
                   16777:        .word   exp04-5b        # unop, s=2
                   16778:        .word   exp06-5b        # left paren, s=0
                   16779:        .word   exp06-5b        # left paren, s=1
                   16780:        .word   exp04-5b        # left paren, s=2
                   16781:        .word   exp08-5b        # left brkt, s=0
                   16782:        .word   exp08-5b        # left brkt, s=1
                   16783:        .word   exp09-5b        # left brkt, s=2
                   16784:        .word   exp02-5b        # comma, s=0
                   16785:        .word   exp05-5b        # comma, s=1
                   16786:        .word   exp11-5b        # comma, s=2
                   16787:        .word   exp10-5b        # function, s=0
                   16788:        .word   exp10-5b        # function, s=1
                   16789:        .word   exp04-5b        # function, s=2
                   16790:        .word   exp03-5b        # variable, s=0
                   16791:        .word   exp03-5b        # variable, state one
                   16792:        .word   exp04-5b        # variable, s=2
                   16793:        .word   exp03-5b        # constant, s=0
                   16794:        .word   exp03-5b        # constant, s=1
                   16795:        .word   exp04-5b        # constant, s=2
                   16796:        .word   exp05-5b        # binop, s=0
                   16797:        .word   exp05-5b        # binop, s=1
                   16798:        .word   exp26-5b        # binop, s=2
                   16799:        .word   exp02-5b        # right paren, s=0
                   16800:        .word   exp05-5b        # right paren, s=1
                   16801:        .word   exp12-5b        # right paren, s=2
                   16802:        .word   exp02-5b        # right brkt, s=0
                   16803:        .word   exp05-5b        # right brkt, s=1
                   16804:        .word   exp18-5b        # right brkt, s=2
                   16805:        .word   exp02-5b        # colon, s=0
                   16806:        .word   exp05-5b        # colon, s=1
                   16807:        .word   exp19-5b        # colon, s=2
                   16808:        .word   exp02-5b        # semicolon, s=0
                   16809:        .word   exp05-5b        # semicolon, s=1
                   16810:        .word   exp19-5b        # semicolon, s=2
                   16811:        #esw                    # end switch on element type/state
                   16812:        #page   
                   16813: #
                   16814: #      EXPAN (CONTINUED)
                   16815: #
                   16816: #      HERE FOR RBR,RPR,COL,SMC,CMA IN STATE 0
                   16817: #
                   16818: #      SET TO RESCAN THE TERMINATOR ENCOUNTERED AND CREATE
                   16819: #      A NULL CONSTANT (CASE OF OMITTED NULL)
                   16820: #
                   16821: exp02: movl    sp,scnrs        # set to rescan element
                   16822:        movl    $nulls,r9       # point to null, merge
                   16823: #
                   16824: #      HERE FOR VAR OR CON IN STATES 0,1
                   16825: #
                   16826: #      STACK THE VARIABLE/CONSTANT AND SET STATE=2
                   16827: #
                   16828: exp03: movl    r9,-(sp)        # stack pointer to operand
                   16829:        movl    $num02,r6       # set state 2
                   16830:        jmp     exp01           # jump for next element
                   16831: #
                   16832: #      HERE FOR VAR,CON,LPR,FNC,UOP IN STATE 2
                   16833: #
                   16834: #      WE RESCAN THE ELEMENT AND CREATE A CONCATENATION OPERATOR
                   16835: #      THIS IS THE CASE OF THE BLANK CONCATENATION OPERATOR.
                   16836: #
                   16837: exp04: movl    sp,scnrs        # set to rescan element
                   16838:        movl    $opdvc,r9       # point to concat operator dv
                   16839:        tstl    r7              # ok if at top level
                   16840:        beqlu   exp4a
                   16841:        movl    $opdvp,r9       # else point to unmistakable concat.
                   16842: #
                   16843: #      MERGE HERE WHEN XR SET UP WITH PROPER CONCATENATION DVBLK
                   16844: #
                   16845: exp4a: tstl    scnbl           # merge bop if blanks, else error
                   16846:        beqlu   0f
                   16847:        jmp     exp26
                   16848: 0:             
                   16849:        decl    scnse           # adjust start of element location
                   16850:        jmp     er_220          # syntax error. missing operator
                   16851: #
                   16852: #      HERE FOR CMA,RPR,RBR,COL,SMC,BOP(S=1) BOP(S=0)
                   16853: #
                   16854: #      THIS IS AN ERRONOUS CONTRUCTION
                   16855: #
                   16856: exp05: decl    scnse           # adjust start of element location
                   16857:        jmp     er_221          # syntax error. missing operand
                   16858: #
                   16859: #      HERE FOR LPR (S=0,1)
                   16860: #
                   16861: exp06: movl    $num04,r10      # set new level indicator
                   16862:        clrl    r9              # set zero value for cmopn
                   16863:        #page   
                   16864: #
                   16865: #      EXPAN (CONTINUED)
                   16866: #
                   16867: #      MERGE HERE TO STORE OLD LEVEL ON STACK AND START NEW ONE
                   16868: #
                   16869: exp07: movl    r9,-(sp)        # stack cmopn value
                   16870:        movl    r8,-(sp)        # stack old counter
                   16871:        movl    r7,-(sp)        # stack old level indicator
                   16872:        jsb     sbchk           # check for stack overflow
                   16873:        clrl    r6              # set new state to zero
                   16874:        movl    r10,r7          # set new level indicator
                   16875:        movl    $num01,r8       # initialize new counter
                   16876:        jmp     exp01           # jump to scan next element
                   16877: #
                   16878: #      HERE FOR LBR (S=0,1)
                   16879: #
                   16880: #      THIS IS AN ILLEGAL USE OF LEFT BRACKET
                   16881: #
                   16882: exp08: jmp     er_222          # syntax error. invalid use of left bracket
                   16883: #
                   16884: #      HERE FOR LBR (S=2)
                   16885: #
                   16886: #      SET NEW LEVEL AND START TO SCAN SUBSCRIPTS
                   16887: #
                   16888: exp09: movl    (sp)+,r9        # load array ptr for cmopn
                   16889:        movl    $num03,r10      # set new level indicator
                   16890:        jmp     exp07           # jump to stack old and start new
                   16891: #
                   16892: #      HERE FOR FNC (S=0,1)
                   16893: #
                   16894: #      STACK OLD LEVEL AND START TO SCAN ARGUMENTS
                   16895: #
                   16896: exp10: movl    $num05,r10      # set new lev indic (xr=vrblk=cmopn)
                   16897:        jmp     exp07           # jump to stack old and start new
                   16898: #
                   16899: #      HERE FOR CMA (S=2)
                   16900: #
                   16901: #      INCREMENT ARGUMENT COUNT AND CONTINUE
                   16902: #
                   16903: exp11: incl    r8              # increment counter
                   16904:        jsb     expdm           # dump operators at this level
                   16905:        clrl    -(sp)           # set new level for parameter
                   16906:        clrl    r6              # set new state
                   16907:        cmpl    r7,$num02       # loop back unless outer level
                   16908:        blequ   0f
                   16909:        jmp     exp01
                   16910: 0:             
                   16911:        jmp     er_223          # syntax error. invalid use of comma
                   16912:        #page   
                   16913: #
                   16914: #      EXPAN (CONTINUED)
                   16915: #
                   16916: #      HERE FOR RPR (S=2)
                   16917: #
                   16918: #      AT OUTER LEVEL IN A NORMAL GOTO THIS IS A TERMINATOR
                   16919: #      OTHERWISE IT MUST TERMINATE A FUNCTION OR GROUPING
                   16920: #
                   16921: exp12: cmpl    r7,$num01       # end of normal goto
                   16922:        bnequ   0f
                   16923:        jmp     exp20
                   16924: 0:             
                   16925:        cmpl    r7,$num05       # end of function arguments
                   16926:        beqlu   exp13
                   16927:        cmpl    r7,$num04       # end of grouping / selection
                   16928:        beqlu   exp14
                   16929:        jmp     er_224          # syntax error. unbalanced right parenthesis
                   16930: #
                   16931: #      HERE AT END OF FUNCTION ARGUMENTS
                   16932: #
                   16933: exp13: movl    $c$fnc,r10      # set cmtyp value for function
                   16934:        jmp     exp15           # jump to build cmblk
                   16935: #
                   16936: #      HERE FOR END OF GROUPING
                   16937: #
                   16938: exp14: cmpl    r8,$num01       # jump if end of grouping
                   16939:        beqlu   exp17
                   16940:        movl    $c$sel,r10      # else set cmtyp for selection
                   16941: #
                   16942: #      MERGE HERE TO BUILD CMBLK FOR LEVEL JUST SCANNED AND
                   16943: #      TO POP UP TO THE PREVIOUS SCAN LEVEL BEFORE CONTINUING.
                   16944: #
                   16945: exp15: jsb     expdm           # dump operators at this level
                   16946:        movl    r8,r6           # copy count
                   16947:        addl2   $cmvls,r6       # add for standard fields at start
                   16948:        moval   0[r6],r6        # convert length to bytes
                   16949:        jsb     alloc           # allocate space for cmblk
                   16950:        movl    $b$cmt,(r9)     # store type code for cmblk
                   16951:        movl    r10,4*cmtyp(r9) # store cmblk node type indicator
                   16952:        movl    r6,4*cmlen(r9)  # store length
                   16953:        addl2   r6,r9           # point past end of block
                   16954:                                # set loop counter
                   16955: #
                   16956: #      LOOP TO MOVE REMAINING WORDS TO CMBLK
                   16957: #
                   16958: exp16: movl    (sp)+,-(r9)     # move one operand ptr from stack
                   16959:        movl    (sp)+,r7        # pop to old level indicator
                   16960:        sobgtr  r8,exp16        # loop till all moved
                   16961:        #page   
                   16962: #
                   16963: #      EXPAN (CONTINUED)
                   16964: #
                   16965: #      COMPLETE CMBLK AND STACK POINTER TO IT ON STACK
                   16966: #
                   16967:        subl2   $4*cmvls,r9     # point back to start of block
                   16968:        movl    (sp)+,r8        # restore old counter
                   16969:        movl    (sp),4*cmopn(r9)# store operand ptr in cmblk
                   16970:        movl    r9,(sp)         # stack cmblk pointer
                   16971:        movl    $num02,r6       # set new state
                   16972:        jmp     exp01           # back for next element
                   16973: #
                   16974: #      HERE AT END OF A PARENTHESIZED EXPRESSION
                   16975: #
                   16976: exp17: jsb     expdm           # dump operators at this level
                   16977:        movl    (sp)+,r9        # restore xr
                   16978:        movl    (sp)+,r7        # restore outer level
                   16979:        movl    (sp)+,r8        # restore outer count
                   16980:        movl    r9,(sp)         # store opnd over unused cmopn val
                   16981:        movl    $num02,r6       # set new state
                   16982:        jmp     exp01           # back for next ele8ent
                   16983: #
                   16984: #      HERE FOR RBR (S=2)
                   16985: #
                   16986: #      AT OUTER LEVEL IN A DIRECT GOTO, THIS IS A TERMINATOR.
                   16987: #      OTHERWISE IT MUST TERMINATE A SUBSCRIPT LIST.
                   16988: #
                   16989: exp18: movl    $c$arr,r10      # set cmtyp for array reference
                   16990:        cmpl    r7,$num03       # jump to build cmblk if end arrayref
                   16991:        beqlu   exp15
                   16992:        cmpl    r7,$num02       # jump if end of direct goto
                   16993:        bnequ   0f
                   16994:        jmp     exp20
                   16995: 0:             
                   16996:        jmp     er_225          # syntax error. unbalanced right bracket
                   16997:        #page   
                   16998: #
                   16999: #      EXPAN (CONTINUED)
                   17000: #
                   17001: #      HERE FOR COL,SMC (S=2)
                   17002: #
                   17003: #      ERROR UNLESS TERMINATING STATEMENT BODY AT OUTER LEVEL
                   17004: #
                   17005: exp19: movl    sp,scnrs        # rescan terminator
                   17006:        movl    r7,r10          # copy level indicator
                   17007:        casel   r10,$0,$6       # switch on level indicator
                   17008: 5:             
                   17009:        .word   exp20-5b        # normal outer level
                   17010:        .word   exp22-5b        # fail if normal goto
                   17011:        .word   exp23-5b        # fail if direct goto
                   17012:        .word   exp24-5b        # fail array brackets
                   17013:        .word   exp21-5b        # fail if in grouping
                   17014:        .word   exp21-5b        # fail function args
                   17015:        #esw                    # end switch on level
                   17016: #
                   17017: #      HERE AT NORMAL END OF EXPRESSION
                   17018: #
                   17019: exp20: jsb     expdm           # dump remaining operators
                   17020:        movl    (sp)+,r9        # load tree pointer
                   17021:        addl2   $4,sp           # pop off bottom of stack marker
                   17022:        rsb                     # return to expan caller
                   17023: #
                   17024: #      MISSING RIGHT PAREN
                   17025: #
                   17026: exp21: jmp     er_226          # syntax error. missing right paren
                   17027: #
                   17028: #      MISSING RIGHT PAREN IN GOTO FIELD
                   17029: #
                   17030: exp22: jmp     er_227          # syntax error. right paren missing from goto
                   17031: #
                   17032: #      MISSING BRACKET IN GOTO
                   17033: #
                   17034: exp23: jmp     er_228          # syntax error. right bracket missing from goto
                   17035: #
                   17036: #      MISSING ARRAY BRACKET
                   17037: #
                   17038: exp24: jmp     er_229          # syntax error. missing right array bracket
                   17039:        #page   
                   17040: #
                   17041: #      EXPAN (CONTINUED)
                   17042: #
                   17043: #      LOOP HERE WHEN AN OPERATOR CAUSES AN OPERATOR DUMP
                   17044: #
                   17045: exp25: movl    r9,expsv
                   17046:        jsb     expop           # pop one operator
                   17047:        movl    expsv,r9        # restore op dv pointer and merge
                   17048: #
                   17049: #      HERE FOR BOP (S=2)
                   17050: #
                   17051: #      REMOVE OPERATORS (CONDENSE) FROM STACK UNTIL NO MORE
                   17052: #      LEFT AT THIS LEVEL OR TOP ONE HAS LOWER PRECEDENCE.
                   17053: #      LOOP HERE TILL THIS CONDITION IS MET.
                   17054: #
                   17055: exp26: movl    4*1(sp),r10     # load operator dvptr from stack
                   17056:        cmpl    r10,$num05      # jump if bottom of stack level
                   17057:        blequ   exp27
                   17058:        cmpl    4*dvrpr(r9),4*dvlpr(r10) # else pop if new prec is lo
                   17059:        blssu   exp25
                   17060: #
                   17061: #      HERE FOR UOP (S=0,1)
                   17062: #
                   17063: #      BINARY OPERATOR MERGES AFTER PRECEDENCE CHECK
                   17064: #
                   17065: #      THE OPERATOR DV IS STORED ON THE STACK AND THE SCAN
                   17066: #      CONTINUES AFTER SETTING THE SCAN STATE TO ONE.
                   17067: #
                   17068: exp27: movl    r9,-(sp)        # stack operator dvptr on stack
                   17069:        jsb     sbchk           # check for stack overflow
                   17070:        movl    $num01,r6       # set new state
                   17071:        cmpl    r9,$opdvs       # back for next element unless =
                   17072:        beqlu   0f
                   17073:        jmp     exp01
                   17074: 0:             
                   17075: #
                   17076: #      HERE FOR SPECIAL CASE OF BINARY =. THE SYNTAX ALLOWS A
                   17077: #      NULL RIGHT ARGUMENT FOR THIS OPERATOR TO BE LEFT
                   17078: #      OUT. ACCORDINGLY WE RESET TO STATE ZERO TO GET PROPER
                   17079: #      ACTION ON A TERMINATOR (SUPPLY A NULL CONSTANT).
                   17080: #
                   17081:        clrl    r6              # set state zero
                   17082:        jmp     exp01           # jump for next element
                   17083:        #enp                    # end procedure expan
                   17084:        #page   
                   17085: #
                   17086: #      EXPAP -- TEST FOR PATTERN MATCH TREE
                   17087: #
                   17088: #      EXPAP IS PASSED AN EXPRESSION TREE TO DETERMINE IF IT
                   17089: #      IS A PATTERN MATCH. THE FOLLOWING ARE RECOGIZED AS
                   17090: #      MATCHES IN THE CONTEXT OF THIS CALL.
                   17091: #
                   17092: #      1)   AN EXPLICIT USE OF BINARY QUESTION MARK
                   17093: #      2)   A CONCATENATION
                   17094: #      3)   AN ALTERNATION WHOSE LEFT OPERAND IS A CONCATENATION
                   17095: #
                   17096: #      (XR)                  PTR TO EXPAN TREE
                   17097: #      JSR  EXPAP            CALL TO TEST FOR PATTERN MATCH
                   17098: #      PPM  LOC              TRANSFER LOC IF NOT A PATTERN MATCH
                   17099: #      (WA)                  DESTROYED
                   17100: #      (XR)                  UNCHANGED (IF NOT MATCH)
                   17101: #      (XR)                  PTR TO BINARY OPERATOR BLK IF MATCH
                   17102: #
                   17103: expap: #prc                    # entry point
                   17104:        movl    r10,-(sp)       # save xl
                   17105:        cmpl    (r9),$b$cmt     # no match if not complex
                   17106:        bnequ   expp2
                   17107:        movl    4*cmtyp(r9),r6  # else load type code
                   17108:        cmpl    r6,$c$cnc       # concatenation is a match
                   17109:        beqlu   expp1
                   17110:        cmpl    r6,$c$pmt       # binary question mark is a match
                   17111:        beqlu   expp1
                   17112:        cmpl    r6,$c$alt       # else not match unless alternation
                   17113:        bnequ   expp2
                   17114: #
                   17115: #      HERE FOR ALTERNATION. CHANGE (A B) / C TO A QM (B / C)
                   17116: #
                   17117:        movl    4*cmlop(r9),r10 # load left operand pointer
                   17118:        cmpl    (r10),$b$cmt    # not match if left opnd not complex
                   17119:        bnequ   expp2
                   17120:        cmpl    4*cmtyp(r10),$c$cnc # not match if left op not conc
                   17121:        bnequ   expp2
                   17122:        movl    4*cmrop(r10),4*cmlop(r9) # xr points to (b / c)
                   17123:        movl    r9,4*cmrop(r10) # set xl opnds to a, (b / c)
                   17124:        movl    r10,r9          # point to this altered node
                   17125: #
                   17126: #      EXIT HERE FOR PATTERN MATCH
                   17127: #
                   17128: expp1: movl    (sp)+,r10       # restore entry xl
                   17129:        addl2   $4*1,(sp)       # give pattern match return
                   17130:        rsb     
                   17131: #
                   17132: #      EXIT HERE IF NOT PATTERN MATCH
                   17133: #
                   17134: expp2: movl    (sp)+,r10       # restore entry xl
                   17135:        movl    (sp)+,r11       # give non-match return
                   17136:        jmp     *(r11)+
                   17137:        #enp                    # end procedure expap
                   17138:        #page   
                   17139: #
                   17140: #      EXPDM -- DUMP OPERATORS AT CURRENT LEVEL (FOR EXPAN)
                   17141: #
                   17142: #      EXPDM USES EXPOP TO CONDENSE ALL OPERATORS AT THIS SYNTAX
                   17143: #      LEVEL. THE STACK BOTTOM IS RECOGNIZED FROM THE LEVEL
                   17144: #      VALUE WHICH IS SAVED ON THE TOP OF THE STACK.
                   17145: #
                   17146: #      JSR  EXPDM            CALL TO DUMP OPERATORS
                   17147: #      (XS)                  POPPED AS REQUIRED
                   17148: #      (XR,WA)               DESTROYED
                   17149: #
                   17150:        .data   1
                   17151: expdm_s:       .long   0
                   17152:        .text   0
                   17153: expdm: movl    (sp)+,expdm_s   # entry point
                   17154:        movl    r10,r$exs       # save xl value
                   17155: #
                   17156: #      LOOP TO DUMP OPERATORS
                   17157: #
                   17158: exdm1: cmpl    4*1(sp),$num05  # jump if stack bottom (saved level
                   17159:        blequ   exdm2
                   17160:        jsb     expop           # else pop one operator
                   17161:        jmp     exdm1           # and loop back
                   17162: #
                   17163: #      HERE AFTER POPPING ALL OPERATORS
                   17164: #
                   17165: exdm2: movl    r$exs,r10       # restore xl
                   17166:        clrl    r$exs           # release save location
                   17167:        jmp     *expdm_s        # return to expdm caller
                   17168:        #enp                    # end procedure expdm
                   17169:        #page   
                   17170: #
                   17171: #      EXPOP-- POP OPERATOR (FOR EXPAN)
                   17172: #
                   17173: #      EXPOP IS USED BY THE EXPAN ROUTINE TO CONDENSE ONE
                   17174: #      OPERATOR FROM THE TOP OF THE SYNTAX STACK. AN APPROPRIATE
                   17175: #      CMBLK IS BUILT FOR THE OPERATOR (UNARY OR BINARY) AND A
                   17176: #      POINTER TO THIS CMBLK IS STACKED.
                   17177: #
                   17178: #      EXPOP IS ALSO USED BY SCNGF (GOTO FIELD SCAN) PROCEDURE
                   17179: #
                   17180: #      JSR  EXPOP            CALL TO POP OPERATOR
                   17181: #      (XS)                  POPPED APPROPRIATELY
                   17182: #      (XR,XL,WA)            DESTROYED
                   17183: #
                   17184:        .data   1
                   17185: expop_s:       .long   0
                   17186:        .text   0
                   17187: expop: movl    (sp)+,expop_s   # entry point
                   17188:        movl    4*1(sp),r9      # load operator dv pointer
                   17189:        cmpl    4*dvlpr(r9),$lluno # jump if unary
                   17190:        beqlu   expo2
                   17191: #
                   17192: #      HERE FOR BINARY OPERATOR
                   17193: #
                   17194:        movl    $4*cmbs$,r6     # set size of binary operator cmblk
                   17195:        jsb     alloc           # allocate space for cmblk
                   17196:        movl    (sp)+,4*cmrop(r9)# pop and store right operand ptr
                   17197:        movl    (sp)+,r10       # pop and load operator dv ptr
                   17198:        movl    (sp),4*cmlop(r9)# store left operand pointer
                   17199: #
                   17200: #      COMMON EXIT POINT
                   17201: #
                   17202: expo1: movl    $b$cmt,(r9)     # store type code for cmblk
                   17203:        movl    4*dvtyp(r10),4*cmtyp(r9) # store cmblk node type code
                   17204:        movl    r10,4*cmopn(r9) # store dvptr (=ptr to dac o$xxx)
                   17205:        movl    r6,4*cmlen(r9)  # store cmblk length
                   17206:        movl    r9,(sp)         # store resulting node ptr on stack
                   17207:        jmp     *expop_s        # return to expop caller
                   17208: #
                   17209: #      HERE FOR UNARY OPERATOR
                   17210: #
                   17211: expo2: movl    $4*cmus$,r6     # set size of unary operator cmblk
                   17212:        jsb     alloc           # allocate space for cmblk
                   17213:        movl    (sp)+,4*cmrop(r9)# pop and store operand pointer
                   17214:        movl    (sp),r10        # load operator dv pointer
                   17215:        jmp     expo1           # merge back to exit
                   17216:        #enp                    # end procedure expop
                   17217:        #page   
                   17218: #
                   17219: #      FLSTG -- FOLD STRING TO UPPER CASE
                   17220: #
                   17221: #      FLSTG FOLDS A CHARACTER STRING CONTAINING LOWER CASE
                   17222: #      CHARACCTERS TO ONE CONTAINING UPPER CASE CHARACTERS.
                   17223: #      FOLDING IS ONLY DONE IF &CASE (KVCAS) IS NOT ZERO.
                   17224: #
                   17225: #      (XR)                  STRING ARGUMENT
                   17226: #      (WA)                  LENGTH OF STRING
                   17227: #      JSR  FLSTG            CALL TO FOLD STRING
                   17228: #      (XR)                  RESULT STRING (POSSIBLY ORIGINAL)
                   17229: #      (WC)                  DESTROYED
                   17230: #
                   17231: flstg: #prc                    # entry point
                   17232:        tstl    kvcas           # skip if &case is 0
                   17233:        beqlu   fst99
                   17234:        movl    r10,-(sp)       # save xl across call
                   17235:        movl    r9,-(sp)        # save original scblk ptr
                   17236:        jsb     alocs           # allocate new string block
                   17237:        movl    (sp),r10        # point to original scblk
                   17238:        movl    r9,-(sp)        # save pointer to new scblk
                   17239:        movab   cfp$f(r10),r10  # point to original chars
                   17240:        movab   cfp$f(r9),r9    # point to new chars
                   17241:        clrl    -(sp)           # init did fold flag
                   17242:                                # load loop counter
                   17243: fst01: movzbl  (r10)+,r6       # load character
                   17244:        cmpl    $ch$$a,r6       # skip if less than lc a
                   17245:        bgtru   fst02
                   17246:        cmpl    r6,$ch$$$       # skip if greater than lc z
                   17247:        bgtru   fst02
                   17248:        bicl2   $ch$bl,r6       # fold character to upper case
                   17249:        movl    sp,(sp)         # set did fold character flag
                   17250: fst02: movb    r6,(r9)+        # store (possibly folded) character
                   17251:        sobgtr  r8,fst01        # loop thru entire string
                   17252:        #csc    r9              # complete store characters
                   17253:        tstl    (sp)+           # skip if folding done
                   17254:        bnequ   fst10
                   17255:        movl    (sp)+,dnamp     # do not need new scblk
                   17256:        movl    (sp)+,r9        # return original scblk
                   17257:        jmp     fst20           # merge below
                   17258: fst10: movl    (sp)+,r9        # return new scblk
                   17259:        addl2   $4,sp           # throw away original scblk pointer
                   17260: fst20: movl    4*sclen(r9),r6  # reload string length
                   17261:        movl    (sp)+,r10       # restore xl
                   17262: fst99: rsb                     # return
                   17263:        #enp    
                   17264:        #page   
                   17265: #
                   17266: #      GBCOL -- PERFORM GARBAGE COLLECTION
                   17267: #
                   17268: #      GBCOL PERFORMS A GARBAGE COLLECTION ON THE DYNAMIC REGION
                   17269: #      ALL BLOCKS WHICH ARE NO LONGER IN USE ARE ELIMINATED
                   17270: #      BY MOVING BLOCKS WHICH ARE IN USE DOWN AND RESETTING
                   17271: #      DNAMP, THE POINTER TO THE NEXT AVAILABLE LOCATION.
                   17272: #
                   17273: #      (WB)                  MOVE OFFSET (SEE BELOW)
                   17274: #      JSR  GBCOL            CALL TO COLLECT GARBAGE
                   17275: #      (XR)                  DESTROYED
                   17276: #
                   17277: #      THE FOLLOWING CONDITIONS MUST BE MET AT THE TIME WHEN
                   17278: #      GBCOL IS CALLED.
                   17279: #
                   17280: #      1)   ALL POINTERS TO BLOCKS IN THE DYNAMIC AREA MUST BE
                   17281: #           ACCESSIBLE TO THE GARBAGE COLLECTOR. THIS MEANS
                   17282: #           THAT THEY MUST OCCUR IN ONE OF THE FOLLOWING.
                   17283: #
                   17284: #           A)               MAIN STACK, WITH CURRENT TOP
                   17285: #                            ELEMENT BEING INDICATED BY XS
                   17286: #
                   17287: #           B)               IN RELOCATABLE FIELDS OF VRBLKS.
                   17288: #
                   17289: #           C)               IN REGISTER XL AT THE TIME OF CALL
                   17290: #
                   17291: #           E)               IN THE SPECIAL REGION OF WORKING
                   17292: #                            STORAGE WHERE NAMES BEGIN WITH R$.
                   17293: #
                   17294: #      2)   ALL POINTERS MUST POINT TO THE START OF BLOCKS WITH
                   17295: #           THE SOLE EXCEPTION OF THE CONTENTS OF THE CODE
                   17296: #           POINTER REGISTER WHICH POINTS INTO THE R$COD BLOCK.
                   17297: #
                   17298: #      3)   NO LOCATION WHICH APPEARS TO CONTAIN A POINTER
                   17299: #           INTO THE DYNAMIC REGION MAY OCCUR UNLESS IT IS IN
                   17300: #           FACT A POINTER TO THE START OF THE BLOCK. HOWEVER
                   17301: #           POINTERS OUTSIDE THIS AREA MAY OCCUR AND WILL
                   17302: #           NOT BE CHANGED BY THE GARBAGE COLLECTOR.
                   17303: #           IT IS ESPECIALLY IMPORTANT TO MAKE SURE THAT XL
                   17304: #           DOES NOT CONTAIN A GARBAGE VALUE FROM SOME PROCESS
                   17305: #           CARRIED OUT BEFORE THE CALL TO THE COLLECTOR.
                   17306: #
                   17307: #      GBCOL HAS THE CAPABILITY OF MOVING THE FINAL COMPACTED
                   17308: #      RESULT UP IN MEMORY (WITH ADDRESSES ADJUSTED ACCORDINGLY)
                   17309: #      THIS IS USED TO ADD SPACE TO THE STATIC REGION. THE
                   17310: #      ENTRY VALUE OF WB IS THE NUMBER OF BYTES TO MOVE UP.
                   17311: #      THE CALLER MUST GUARANTEE THAT THERE IS ENOUGH ROOM.
                   17312: #      FURTHERMORE THE VALUE IN WB IF IT IS NON-ZERO, MUST BE AT
                   17313: #      LEAST 256 SO THAT THE MWB INSTRUCTION CONDITIONS ARE MET.
                   17314:        #page   
                   17315: #
                   17316: #      GBCOL (CONTINUED)
                   17317: #
                   17318: #      THE ALGORITHM, WHICH IS A MODIFICATION OF THE LISP-2
                   17319: #      GARBAGE COLLECTOR DEVISED BY R.DEWAR AND K.BELCHER
                   17320: #      TAKES THREE PASSES AS FOLLOWS.
                   17321: #
                   17322: #      1)   ALL POINTERS IN MEMORY ARE SCANNED AND BLOCKS IN USE
                   17323: #           DETERMINED FROM THIS SCAN. NOTE THAT THIS PROCEDURE
                   17324: #           IS RECURSIVE AND USES THE MAIN STACK FOR LINKAGE.
                   17325: #           THE MARKING PROCESS IS THUS SIMILAR TO THAT USED IN
                   17326: #           A STANDARD LISP COLLECTOR. HOWEVER THE METHOD OF
                   17327: #           ACTUALLY MARKING THE BLOCKS IS DIFFERENT.
                   17328: #
                   17329: #           THE FIRST FIELD OF A BLOCK NORMALLY CONTAINS A
                   17330: #           CODE ENTRY POINT POINTER. SUCH AN ENTRY POINTER
                   17331: #           CAN BE DISTINGUISHED FROM THE ADDRESS OF ANY POINTER
                   17332: #           TO BE PROCESSED BY THE COLLECTOR. DURING GARBAGE
                   17333: #           COLLECTION, THIS WORD IS USED TO BUILD A BACK CHAIN
                   17334: #           OF POINTERS THROUGH FIELDS WHICH POINT TO THE BLOCK.
                   17335: #           THE END OF THE CHAIN IS MARKED BY THE OCCURENCE
                   17336: #           OF THE WORD WHICH USED TO BE IN THE FIRST WORD OF
                   17337: #           THE BLOCK. THIS BACKCHAIN SERVES BOTH AS A MARK
                   17338: #           INDICATING THAT THE BLOCK IS IN USE AND AS A LIST OF
                   17339: #           REFERENCES FOR THE RELOCATION PHASE.
                   17340: #
                   17341: #      2)   STORAGE IS SCANNED SEQUENTIALLY TO DISCOVER WHICH
                   17342: #           BLOCKS ARE CURRENTLY IN USE AS INDICATED BY THE
                   17343: #           PRESENCE OF A BACKCHAIN. TWO POINTERS ARE MAINTAINED
                   17344: #           ONE SCANS THROUGH LOOKING AT EACH BLOCK. THE OTHER
                   17345: #           IS INCREMENTED ONLY FOR BLOCKS FOUND TO BE IN USE.
                   17346: #           IN THIS WAY, THE EVENTUAL LOCATION OF EACH BLOCK CAN
                   17347: #           BE DETERMINED WITHOUT ACTUALLY MOVING ANY BLOCKS.
                   17348: #           AS EACH BLOCK WHICH IS IN USE IS PROCESSED, THE BACK
                   17349: #           CHAIN IS USED TO RESET ALL POINTERS WHICH POINT TO
                   17350: #           THIS BLOCK TO CONTAIN ITS NEW ADDRESS, I.E. THE
                   17351: #           ADDRESS IT WILL OCCUPY AFTER THE BLOCKS ARE MOVED.
                   17352: #           THE FIRST WORD OF THE BLOCK, TAKEN FROM THE END OF
                   17353: #           THE CHAIN IS RESTORED AT THIS POINT.
                   17354: #
                   17355: #           DURING PASS 2, THE COLLECTOR BUILDS BLOCKS WHICH
                   17356: #           DESCRIBE THE REGIONS OF STORAGE WHICH ARE TO BE
                   17357: #           MOVED IN THE THIRD PASS. THERE IS ONE DESCRIPTOR FOR
                   17358: #           EACH CONTIGUOUS SET OF GOOD BLOCKS. THE DESCRIPTOR
                   17359: #           IS BUILT JUST BEHIND THE BLOCK TO BE MOVED AND
                   17360: #           CONTAINS A POINTER TO THE NEXT BLOCK AND THE NUMBER
                   17361: #           OF WORDS TO BE MOVED.
                   17362: #
                   17363: #      3)   IN THE THIRD AND FINAL PASS, THE MOVE DESCRIPTOR
                   17364: #           BLOCKS BUILT IN PASS TWO ARE USED TO ACTUALLY MOVE
                   17365: #           THE BLOCKS DOWN TO THE BOTTOM OF THE DYNAMIC REGION.
                   17366: #           THE COLLECTION IS THEN COMPLETE AND THE NEXT
                   17367: #           AVAILABLE LOCATION POINTER IS RESET.
                   17368:        #page   
                   17369: #
                   17370: #      GBCOL (CONTINUED)
                   17371: #
                   17372: gbcol: #prc                    # entry point
                   17373:        tstl    dmvch           # fail if in mid-dump
                   17374:        beqlu   0f
                   17375:        jmp     gbc14
                   17376: 0:             
                   17377:        movl    sp,gbcfl        # note gbcol entered
                   17378:        movl    r6,gbsva        # save entry wa
                   17379:        movl    r7,gbsvb        # save entry wb
                   17380:        movl    r8,gbsvc        # save entry wc
                   17381:        movl    r10,-(sp)       # save entry xl
                   17382:        movl    r3,r6           # get code pointer value
                   17383:        subl2   r$cod,r6        # make relative
                   17384:        movl    r6,r3           # and restore
                   17385: #
                   17386: #      PROCESS STACK ENTRIES
                   17387: #
                   17388:        movl    sp,r9           # point to stack front
                   17389:        movl    stbas,r10       # point past end of stack
                   17390:        cmpl    r10,r9          # ok if d-stack
                   17391:        bgequ   gbc00
                   17392:        movl    r10,r9          # reverse if ...
                   17393:        movl    sp,r10          # ... u-stack
                   17394: #
                   17395: #      PROCESS THE STACK
                   17396: #
                   17397: gbc00: jsb     gbcpf           # process pointers on stack
                   17398: #
                   17399: #      PROCESS SPECIAL WORK LOCATIONS
                   17400: #
                   17401:        movl    $r$aaa,r9       # point to start of relocatable locs
                   17402:        movl    $r$yyy,r10      # point past end of relocatable locs
                   17403:        jsb     gbcpf           # process work fields
                   17404: #
                   17405: #      PREPARE TO PROCESS VARIABLE BLOCKS
                   17406: #
                   17407:        movl    hshtb,r6        # point to first hash slot pointer
                   17408: #
                   17409: #      LOOP THROUGH HASH SLOTS
                   17410: #
                   17411: gbc01: movl    r6,r10          # point to next slot
                   17412:        addl2   $4,r6           # bump bucket pointer
                   17413:        movl    r6,gbcnm        # save bucket pointer
                   17414:        #page   
                   17415: #
                   17416: #      GBCOL (CONTINUED)
                   17417: #
                   17418: #      LOOP THROUGH VARIABLES ON ONE HASH CHAIN
                   17419: #
                   17420: gbc02: movl    (r10),r9        # load ptr to next vrblk
                   17421:        tstl    r9              # jump if end of chain
                   17422:        beqlu   gbc03
                   17423:        movl    r9,r10          # else copy vrblk pointer
                   17424:        addl2   $4*vrval,r9     # point to first reloc fld
                   17425:        addl2   $4*vrnxt,r10    # point past last (and to link ptr)
                   17426:        jsb     gbcpf           # process reloc fields in vrblk
                   17427:        jmp     gbc02           # loop back for next block
                   17428: #
                   17429: #      HERE AT END OF ONE HASH CHAIN
                   17430: #
                   17431: gbc03: movl    gbcnm,r6        # restore bucket pointer
                   17432:        cmpl    r6,hshte        # loop back if more buckets to go
                   17433:        bnequ   gbc01
                   17434:        #page   
                   17435: #
                   17436: #      GBCOL (CONTINUED)
                   17437: #
                   17438: #      NOW WE ARE READY TO START PASS TWO. REGISTERS ARE USED
                   17439: #      AS FOLLOWS IN PASS TWO.
                   17440: #
                   17441: #      (XR)                  SCANS THROUGH ALL BLOCKS
                   17442: #      (WC)                  POINTER TO EVENTUAL LOCATION
                   17443: #
                   17444: #      THE MOVE DESCRIPTION BLOCKS BUILT IN THIS PASS HAVE
                   17445: #      THE FOLLOWING FORMAT.
                   17446: #
                   17447: #      WORD 1                POINTER TO NEXT MOVE BLOCK,
                   17448: #                            ZERO IF END OF CHAIN OF BLOCKS
                   17449: #
                   17450: #      WORD 2                LENGTH OF BLOCKS TO BE MOVED IN
                   17451: #                            BYTES. SET TO THE ADDRESS OF THE
                   17452: #                            FIRST BYTE WHILE ACTUALLY SCANNING
                   17453: #                            THE BLOCKS.
                   17454: #
                   17455: #      THE FIRST ENTRY ON THIS CHAIN IS A SPECIAL ENTRY
                   17456: #      CONSISTING OF THE TWO WORDS GBCNM AND GBCNS. AFTER
                   17457: #      BUILDING THE CHAIN OF MOVE DESCRIPTORS, GBCNM POINTS TO
                   17458: #      THE FIRST REAL MOVE BLOCK, AND GBCNS IS THE LENGTH OF
                   17459: #      BLOCKS IN USE AT THE START OF STORAGE WHICH NEED NOT
                   17460: #      BE MOVED SINCE THEY ARE IN THE CORRECT POSITION.
                   17461: #
                   17462: gbc04: movl    dnamb,r9        # point to first block
                   17463:        movl    r9,r8           # set as first eventual location
                   17464:        addl2   gbsvb,r8        # add offset for eventual move up
                   17465:        clrl    gbcnm           # clear initial forward pointer
                   17466:        movl    $gbcnm,gbclm    # initialize ptr to last move block
                   17467:        movl    r9,gbcns        # initialize first address
                   17468: #
                   17469: #      LOOP THROUGH A SERIES OF BLOCKS IN USE
                   17470: #
                   17471: gbc05: cmpl    r9,dnamp        # jump if end of used region
                   17472:        beqlu   gbc07
                   17473:        movl    (r9),r6         # else get first word
                   17474:        cmpl    r6,$p$yyy       # skip if not entry ptr (in use)
                   17475:        bgequ   gbc06
                   17476:        cmpl    r6,$b$aaa       # jump if entry pointer (unused)
                   17477:        bgequ   gbc07
                   17478: #
                   17479: #      HERE FOR BLOCK IN USE, LOOP TO RELOCATE REFERENCES
                   17480: #
                   17481: gbc06: movl    r6,r10          # copy pointer
                   17482:        movl    (r10),r6        # load forward pointer
                   17483:        movl    r8,(r10)        # relocate reference
                   17484:        cmpl    r6,$p$yyy       # loop back if not end of chain
                   17485:        bgequ   gbc06
                   17486:        cmpl    r6,$b$aaa       # loop back if not end of chain
                   17487:        blequ   gbc06
                   17488:        #page   
                   17489: #
                   17490: #      GBCOL (CONTINUED)
                   17491: #
                   17492: #      AT END OF CHAIN, RESTORE FIRST WORD AND BUMP PAST
                   17493: #
                   17494:        movl    r6,(r9)         # restore first word
                   17495:        jsb     blkln           # get length of this block
                   17496:        addl2   r6,r9           # bump actual pointer
                   17497:        addl2   r6,r8           # bump eventual pointer
                   17498:        jmp     gbc05           # loop back for next block
                   17499: #
                   17500: #      HERE AT END OF A SERIES OF BLOCKS IN USE
                   17501: #
                   17502: gbc07: movl    r9,r6           # copy pointer past last block
                   17503:        movl    gbclm,r10       # point to previous move block
                   17504:        subl2   4*1(r10),r6     # subtract starting address
                   17505:        movl    r6,4*1(r10)     # store length of block to be moved
                   17506: #
                   17507: #      LOOP THROUGH A SERIES OF BLOCKS NOT IN USE
                   17508: #
                   17509: gbc08: cmpl    r9,dnamp        # jump if end of used region
                   17510:        beqlu   gbc10
                   17511:        movl    (r9),r6         # else load first word of next block
                   17512:        cmpl    r6,$p$yyy       # jump if in use
                   17513:        bgequ   gbc09
                   17514:        cmpl    r6,$b$aaa       # jump if in use
                   17515:        blequ   gbc09
                   17516:        jsb     blkln           # else get length of next block
                   17517:        addl2   r6,r9           # push pointer
                   17518:        jmp     gbc08           # and loop back
                   17519: #
                   17520: #      HERE FOR A BLOCK IN USE AFTER PROCESSING A SERIES OF
                   17521: #      BLOCKS WHICH WERE NOT IN USE, BUILD NEW MOVE BLOCK.
                   17522: #
                   17523: gbc09: subl2   $4*num02,r9     # point 2 words behind for move block
                   17524:        movl    gbclm,r10       # point to previous move block
                   17525:        movl    r9,(r10)        # set forward ptr in previous block
                   17526:        clrl    (r9)            # zero forward ptr of new block
                   17527:        movl    r9,gbclm        # remember address of this block
                   17528:        movl    r9,r10          # copy ptr to move block
                   17529:        addl2   $4*num02,r9     # point back to block in use
                   17530:        movl    r9,4*1(r10)     # store starting address
                   17531:        jmp     gbc06           # jump to process block in use
                   17532:        #page   
                   17533: #
                   17534: #      GBCOL (CONTINUED)
                   17535: #
                   17536: #      HERE FOR PASS THREE -- ACTUALLY MOVE THE BLOCKS DOWN
                   17537: #
                   17538: #      (XL)                  POINTER TO OLD LOCATION
                   17539: #      (XR)                  POINTER TO NEW LOCATION
                   17540: #
                   17541: gbc10: movl    dnamb,r9        # point to start of storage
                   17542:        addl2   gbcns,r9        # bump past unmoved blocks at start
                   17543: #
                   17544: #      LOOP THROUGH MOVE DESCRIPTORS
                   17545: #
                   17546: gbc11: movl    gbcnm,r10       # point to next move block
                   17547:        tstl    r10             # jump if end of chain
                   17548:        beqlu   gbc12
                   17549:        movl    (r10)+,gbcnm    # move pointer down chain
                   17550:        movl    (r10)+,r6       # get length to move
                   17551:        jsb     sbmvw           # perform move
                   17552:        jmp     gbc11           # loop back
                   17553: #
                   17554: #      NOW TEST FOR MOVE UP
                   17555: #
                   17556: gbc12: movl    r9,dnamp        # set next available loc ptr
                   17557:        movl    gbsvb,r7        # reload move offset
                   17558:        tstl    r7              # jump if no move required
                   17559:        beqlu   gbc13
                   17560:        movl    r9,r10          # else copy old top of core
                   17561:        addl2   r7,r9           # point to new top of core
                   17562:        movl    r9,dnamp        # save new top of core pointer
                   17563:        movl    r10,r6          # copy old top
                   17564:        subl2   dnamb,r6        # minus old bottom = length
                   17565:        addl2   r7,dnamb        # bump bottom to get new value
                   17566:        jsb     sbmwb           # perform move (backwards)
                   17567: #
                   17568: #      MERGE HERE TO EXIT
                   17569: #
                   17570: gbc13: movl    gbsva,r6        # restore wa
                   17571:        movl    r3,r8           # get code pointer
                   17572:        addl2   r$cod,r8        # make absolute again
                   17573:        movl    r8,r3           # and replace absolute value
                   17574:        movl    gbsvc,r8        # restore wc
                   17575:        movl    (sp)+,r10       # restore entry xl
                   17576:        incl    gbcnt           # increment count of collections
                   17577:        clrl    r9              # clear garbage value in xr
                   17578:        clrl    gbcfl           # note exit from gbcol
                   17579:        rsb                     # exit to gbcol caller
                   17580: #
                   17581: #      GARBAGE COLLECTION NOT ALLOWED WHILST DUMPING
                   17582: #
                   17583: gbc14: incl    errft           # fatal error
                   17584:        jmp     er_250          # insufficient memory to complete dump
                   17585:        #enp                    # end procedure gbcol
                   17586:        #page   
                   17587: #
                   17588: #      GBCPF -- PROCESS FIELDS FOR GARBAGE COLLECTOR
                   17589: #
                   17590: #      THIS PROCEDURE IS USED BY THE GARBAGE COLLECTOR TO
                   17591: #      PROCESS FIELDS IN PASS ONE. SEE GBCOL FOR FULL DETAILS.
                   17592: #
                   17593: #      (XR)                  PTR TO FIRST LOCATION TO PROCESS
                   17594: #      (XL)                  PTR PAST LAST LOCATION TO PROCESS
                   17595: #      JSR  GBCPF            CALL TO PROCESS FIELDS
                   17596: #      (XR,WA,WB,WC,IA)      DESTROYED
                   17597: #
                   17598: #      NOTE THAT ALTHOUGH THIS PROCEDURE USES A RECURSIVE
                   17599: #      APPROACH, IT CONTROLS ITS OWN STACK AND IS NOT RECURSIVE.
                   17600: #
                   17601: gbcpf: #prc                    # entry point
                   17602:        clrl    -(sp)           # set zero to mark bottom of stack
                   17603:        movl    r10,-(sp)       # save end pointer
                   17604: #
                   17605: #      MERGE HERE TO GO DOWN A LEVEL AND START A NEW LOOP
                   17606: #
                   17607: #      1(XS)                 NEXT LVL FIELD PTR (0 AT OUTER LVL)
                   17608: #      0(XS)                 PTR PAST LAST FIELD TO PROCESS
                   17609: #      (XR)                  PTR TO FIRST FIELD TO PROCESS
                   17610: #
                   17611: #      LOOP TO PROCESS SUCCESSIVE FIELDS
                   17612: #
                   17613: gpf01: movl    (r9),r10        # load field contents
                   17614:        movl    r9,r8           # save field pointer
                   17615:        cmpl    r10,dnamb       # jump if not ptr into dynamic area
                   17616:        blssu   gpf02
                   17617:        cmpl    r10,dnamp       # jump if not ptr into dynamic area
                   17618:        bgequ   gpf02
                   17619: #
                   17620: #      HERE WE HAVE A PTR TO A BLOCK IN THE DYNAMIC AREA.
                   17621: #      LINK THIS FIELD ONTO THE REFERENCE BACKCHAIN.
                   17622: #
                   17623:        movl    (r10),r6        # load ptr to chain (or entry ptr)
                   17624:        movl    r9,(r10)        # set this field as new head of chain
                   17625:        movl    r6,(r9)         # set forward pointer
                   17626: #
                   17627: #      NOW SEE IF THIS BLOCK HAS BEEN PROCESSED BEFORE
                   17628: #
                   17629:        cmpl    r6,$p$yyy       # jump if already processed
                   17630:        bgequ   gpf02
                   17631:        cmpl    r6,$b$aaa       # jump if not already processed
                   17632:        bgequ   gpf03
                   17633: #
                   17634: #      HERE TO MOVE TO NEXT FIELD
                   17635: #
                   17636: gpf02: movl    r8,r9           # restore field pointer
                   17637:        addl2   $4,r9           # bump to next field
                   17638:        cmpl    r9,(sp)         # loop back if more to go
                   17639:        bnequ   gpf01
                   17640:        #page   
                   17641: #
                   17642: #      GBCPF (CONTINUED)
                   17643: #
                   17644: #      HERE WE POP UP A LEVEL AFTER FINISHING A BLOCK
                   17645: #
                   17646:        movl    (sp)+,r10       # restore pointer past end
                   17647:        movl    (sp)+,r8        # restore block pointer
                   17648:        tstl    r8              # continue loop unless outer levl
                   17649:        bnequ   gpf02
                   17650:        rsb                     # return to caller if outer level
                   17651: #
                   17652: #      HERE TO PROCESS AN ACTIVE BLOCK WHICH HAS NOT BEEN DONE
                   17653: #
                   17654: gpf03: movl    r10,r9          # copy block pointer
                   17655:        movl    r6,r10          # copy first word of block
                   17656:        movzwl  -2(r10),r10     # load entry point id (bl$xx)
                   17657: #
                   17658: #      BLOCK TYPE SWITCH. NOTE THAT BLOCKS WITH NO RELOCATABLE
                   17659: #      FIELDS JUST RETURN TO GPF02 HERE TO CONTINE TO NEXT FLD.
                   17660: #
                   17661:        casel   r10,$0,$bl$$$   # switch on block type
                   17662: 5:             
                   17663:        .word   gpf06-5b        # arblk
                   17664:        .word   gpf18-5b        # bcblk
                   17665:        .word   gpf08-5b        # cdblk
                   17666:        .word   gpf17-5b        # exblk
                   17667:        .word   gpf02-5b        # icblk
                   17668:        .word   gpf10-5b        # nmblk
                   17669:        .word   gpf10-5b        # p0blk
                   17670:        .word   gpf12-5b        # p1blk
                   17671:        .word   gpf12-5b        # p2blk
                   17672:        .word   gpf02-5b        # rcblk
                   17673:        .word   gpf02-5b        # scblk
                   17674:        .word   gpf02-5b        # seblk
                   17675:        .word   gpf08-5b        # tbblk
                   17676:        .word   gpf08-5b        # vcblk
                   17677:        .word   gpf02-5b        # xnblk
                   17678:        .word   gpf09-5b        # xrblk
                   17679:        .word   gpf13-5b        # pdblk
                   17680:        .word   gpf16-5b        # trblk
                   17681:        .word   gpf02-5b        # bfblk
                   17682:        .word   gpf07-5b        # ccblk
                   17683:        .word   gpf04-5b        # cmblk
                   17684:        .word   gpf02-5b        # ctblk
                   17685:        .word   gpf02-5b        # dfblk
                   17686:        .word   gpf02-5b        # efblk
                   17687:        .word   gpf10-5b        # evblk
                   17688:        .word   gpf11-5b        # ffblk
                   17689:        .word   gpf02-5b        # kvblk
                   17690:        .word   gpf14-5b        # pfblk
                   17691:        .word   gpf15-5b        # teblk
                   17692:        #esw                    # end of jump table
                   17693:        #page   
                   17694: #
                   17695: #      GBCPF (CONTINUED)
                   17696: #
                   17697: #      CMBLK
                   17698: #
                   17699: gpf04: movl    4*cmlen(r9),r6  # load length
                   17700:        movl    $4*cmtyp,r7     # set offset
                   17701: #
                   17702: #      HERE TO PUSH DOWN TO NEW LEVEL
                   17703: #
                   17704: #      (WC)                  FIELD PTR AT PREVIOUS LEVEL
                   17705: #      (XR)                  PTR TO NEW BLOCK
                   17706: #      (WA)                  LENGTH (RELOC FLDS + FLDS AT START)
                   17707: #      (WB)                  OFFSET TO FIRST RELOC FIELD
                   17708: #
                   17709: gpf05: addl2   r9,r6           # point past last reloc field
                   17710:        addl2   r7,r9           # point to first reloc field
                   17711:        movl    r8,-(sp)        # stack old field pointer
                   17712:        movl    r6,-(sp)        # stack new limit pointer
                   17713:        jsb     sbchk           # check for stack overflow
                   17714:        jmp     gpf01           # if ok, back to process
                   17715: #
                   17716: #      ARBLK
                   17717: #
                   17718: gpf06: movl    4*arlen(r9),r6  # load length
                   17719:        movl    4*arofs(r9),r7  # set offset to 1st reloc fld (arpro)
                   17720:        jmp     gpf05           # all set
                   17721: #
                   17722: #      CCBLK
                   17723: #
                   17724: gpf07: movl    4*ccuse(r9),r6  # set length in use
                   17725:        movl    $4*ccuse,r7     # 1st word (make sure at least one)
                   17726:        jmp     gpf05           # all set
                   17727:        #page   
                   17728: #
                   17729: #      GBCPF (CONTINUED)
                   17730: #
                   17731: #      CDBLK, TBBLK, VCBLK
                   17732: #
                   17733: gpf08: movl    4*offs2(r9),r6  # load length
                   17734:        movl    $4*offs3,r7     # set offset
                   17735:        jmp     gpf05           # jump back
                   17736: #
                   17737: #      XRBLK
                   17738: #
                   17739: gpf09: movl    4*xrlen(r9),r6  # load length
                   17740:        movl    $4*xrptr,r7     # set offset
                   17741:        jmp     gpf05           # jump back
                   17742: #
                   17743: #      EVBLK, NMBLK, P0BLK
                   17744: #
                   17745: gpf10: movl    $4*offs2,r6     # point past second field
                   17746:        movl    $4*offs1,r7     # offset is one (only reloc fld is 2)
                   17747:        jmp     gpf05           # all set
                   17748: #
                   17749: #      FFBLK
                   17750: #
                   17751: gpf11: movl    $4*ffofs,r6     # set length
                   17752:        movl    $4*ffnxt,r7     # set offset
                   17753:        jmp     gpf05           # all set
                   17754: #
                   17755: #      P1BLK, P2BLK
                   17756: #
                   17757: gpf12: movl    $4*parm2,r6     # length (parm2 is non-relocatable)
                   17758:        movl    $4*pthen,r7     # set offset
                   17759:        jmp     gpf05           # all set
                   17760:        #page   
                   17761: #
                   17762: #      GBCPF (CONTINUED)
                   17763: #
                   17764: #      PDBLK
                   17765: #
                   17766: gpf13: movl    4*pddfp(r9),r10 # load ptr to dfblk
                   17767:        movl    4*dfpdl(r10),r6 # get pdblk length
                   17768:        movl    $4*pdfld,r7     # set offset
                   17769:        jmp     gpf05           # all set
                   17770: #
                   17771: #      PFBLK
                   17772: #
                   17773: gpf14: movl    $4*pfarg,r6     # length past last reloc
                   17774:        movl    $4*pfcod,r7     # offset to first reloc
                   17775:        jmp     gpf05           # all set
                   17776: #
                   17777: #      TEBLK
                   17778: #
                   17779: gpf15: movl    $4*tesi$,r6     # set length
                   17780:        movl    $4*tesub,r7     # and offset
                   17781:        jmp     gpf05           # all set
                   17782: #
                   17783: #      TRBLK
                   17784: #
                   17785: gpf16: movl    $4*trsi$,r6     # set length
                   17786:        movl    $4*trval,r7     # and offset
                   17787:        jmp     gpf05           # all set
                   17788: #
                   17789: #      EXBLK
                   17790: #
                   17791: gpf17: movl    4*exlen(r9),r6  # load length
                   17792:        movl    $4*exflc,r7     # set offset
                   17793:        jmp     gpf05           # jump back
                   17794: #
                   17795: #      BCBLK
                   17796: #
                   17797: gpf18: movl    $4*bcsi$,r6     # set length
                   17798:        movl    $4*bcbuf,r7     # and offset
                   17799:        jmp     gpf05           # all set
                   17800:        #enp                    # end procedure gbcpf
                   17801:        #page   
                   17802: #
                   17803: #      GTARR -- GET ARRAY
                   17804: #
                   17805: #      GTARR IS PASSED AN OBJECT AND RETURNS AN ARRAY IF POSSIBL
                   17806: #
                   17807: #      (XR)                  VALUE TO BE CONVERTED
                   17808: #      JSR  GTARR            CALL TO GET ARRAY
                   17809: #      PPM  LOC              TRANSFER LOC FOR CONVERT IMPOSSIBLE
                   17810: #      (XR)                  RESULTING ARRAY
                   17811: #      (XL,WA,WB,WC)         DESTROYED
                   17812: #
                   17813: gtarr: #prc                    # entry point
                   17814:        movl    (r9),r6         # load type word
                   17815:        cmpl    r6,$b$art       # exit if already an array
                   17816:        bnequ   0f
                   17817:        jmp     gtar8
                   17818: 0:             
                   17819:        cmpl    r6,$b$vct       # exit if already an array
                   17820:        bnequ   0f
                   17821:        jmp     gtar8
                   17822: 0:             
                   17823:        cmpl    r6,$b$tbt       # else fail if not a table (sgd02)
                   17824:        beqlu   0f
                   17825:        jmp     gta9a
                   17826: 0:             
                   17827: #
                   17828: #      HERE WE CONVERT A TABLE TO AN ARRAY
                   17829: #
                   17830:        movl    r9,-(sp)        # replace tbblk pointer on stack
                   17831:        clrl    r9              # signal first pass
                   17832:        clrl    r7              # zero non-null element count
                   17833: #
                   17834: #      THE FOLLOWING CODE IS EXECUTED TWICE. ON THE FIRST PASS,
                   17835: #      SIGNALLED BY XR=0, THE NUMBER OF NON-NULL ELEMENTS IN
                   17836: #      THE TABLE IS COUNTED IN WB. IN THE SECOND PASS, WHERE
                   17837: #      XR IS A POINTER INTO THE ARBLK, THE NAME AND VALUE ARE
                   17838: #      ENTERED INTO THE CURRENT ARBLK LOCATION.
                   17839: #
                   17840: gtar1: movl    (sp),r10        # point to table
                   17841:        addl2   4*tblen(r10),r10# point past last bucket
                   17842:        subl2   $4*tbbuk,r10    # set first bucket offset
                   17843:        movl    r10,r6          # copy adjusted pointer
                   17844: #
                   17845: #      LOOP THROUGH BUCKETS IN TABLE BLOCK
                   17846: #      NEXT THREE LINES OF CODE RELY ON TENXT HAVING A VALUE
                   17847: #      1 LESS THAN TBBUK.
                   17848: #
                   17849: gtar2: movl    r6,r10          # copy bucket pointer
                   17850:        subl2   $4,r6           # decrement bucket pointer
                   17851: #
                   17852: #      LOOP THROUGH TEBLKS ON ONE BUCKET CHAIN
                   17853: #
                   17854: gtar3: movl    4*tenxt(r10),r10# point to next teblk
                   17855:        cmpl    r10,(sp)        # jump if chain end (tbblk ptr)
                   17856:        beqlu   gtar6
                   17857:        movl    r10,cnvtp       # else save teblk pointer
                   17858: #
                   17859: #      LOOP TO FIND VALUE DOWN TRBLK CHAIN
                   17860: #
                   17861: gtar4: movl    4*teval(r10),r10# load value
                   17862:        cmpl    (r10),$b$trt    # loop till value found
                   17863:        beqlu   gtar4
                   17864:        movl    r10,r8          # copy value
                   17865:        movl    cnvtp,r10       # restore teblk pointer
                   17866:        #page   
                   17867: #
                   17868: #      GTARR (CONTINUED)
                   17869: #
                   17870: #      NOW CHECK FOR NULL AND TEST CASES
                   17871: #
                   17872:        cmpl    r8,$nulls       # loop back to ignore null value
                   17873:        beqlu   gtar3
                   17874:        tstl    r9              # jump if second pass
                   17875:        bnequ   gtar5
                   17876:        incl    r7              # for the first pass, bump count
                   17877:        jmp     gtar3           # and loop back for next teblk
                   17878: #
                   17879: #      HERE IN SECOND PASS
                   17880: #
                   17881: gtar5: movl    4*tesub(r10),(r9)+ # store subscript name
                   17882:        movl    r8,(r9)+        # store value in arblk
                   17883:        jmp     gtar3           # loop back for next teblk
                   17884: #
                   17885: #      HERE AFTER SCANNING TEBLKS ON ONE CHAIN
                   17886: #
                   17887: gtar6: cmpl    r6,(sp)         # loop back if more buckets to go
                   17888:        bnequ   gtar2
                   17889:        tstl    r9              # else jump if second pass
                   17890:        bnequ   gtar7
                   17891: #
                   17892: #      HERE AFTER COUNTING NON-NULL ELEMENTS
                   17893: #
                   17894:        tstl    r7              # fail if no non-null elements
                   17895:        bnequ   0f
                   17896:        jmp     gtar9
                   17897: 0:             
                   17898:        movl    r7,r6           # else copy count
                   17899:        addl2   r7,r6           # double (two words/element)
                   17900:        addl2   $arvl2,r6       # add space for standard fields
                   17901:        moval   0[r6],r6        # convert length to bytes
                   17902:        cmpl    r6,mxlen        # fail if too long for array
                   17903:        blssu   0f
                   17904:        jmp     gtar9
                   17905: 0:             
                   17906:        jsb     alloc           # else allocate space for arblk
                   17907:        movl    $b$art,(r9)     # store type word
                   17908:        clrl    4*idval(r9)     # zero id for the moment
                   17909:        movl    r6,4*arlen(r9)  # store length
                   17910:        movl    $num02,4*arndm(r9) # set dimensions = 2
                   17911:        movl    intv1,r5        # get integer one
                   17912:        movl    r5,4*arlbd(r9)  # store as lbd 1
                   17913:        movl    r5,4*arlb2(r9)  # store as lbd 2
                   17914:        movl    intv2,r5        # load integer two
                   17915:        movl    r5,4*ardm2(r9)  # store as dim 2
                   17916:        movl    r7,r5           # get element count as integer
                   17917:        movl    r5,4*ardim(r9)  # store as dim 1
                   17918:        clrl    4*arpr2(r9)     # zero prototype field for now
                   17919:        movl    $4*arpr2,4*arofs(r9) # set offset field (signal pass 2)
                   17920:        movl    r9,r7           # save arblk pointer
                   17921:        addl2   $4*arvl2,r9     # point to first element location
                   17922:        jmp     gtar1           # jump back to fill in elements
                   17923:        #page   
                   17924: #
                   17925: #      GTARR (CONTINUED)
                   17926: #
                   17927: #      HERE AFTER FILLING IN ELEMENT VALUES
                   17928: #
                   17929: gtar7: movl    r7,r9           # restore arblk pointer
                   17930:        movl    r7,(sp)         # store as result
                   17931: #
                   17932: #      NOW WE NEED THE ARRAY PROTOTYPE WHICH IS OF THE FORM NN,2
                   17933: #      THIS IS OBTAINED BY BUILDING THE STRING FOR NN02 AND
                   17934: #      CHANGING THE ZERO TO A COMMA BEFORE STORING IT.
                   17935: #
                   17936:        movl    4*ardim(r9),r5  # get number of elements (nn)
                   17937:        mull2   intvh,r5        # multiply by 100
                   17938:        addl2   intv2,r5        # add 2 (nn02)
                   17939:        jsb     icbld           # build integer
                   17940:        movl    r9,-(sp)        # store ptr for gtstg
                   17941:        jsb     gtstg           # convert to string
                   17942:        .long   invalid$        # convert fail is impossible
                   17943:        movl    r9,r10          # copy string pointer
                   17944:        movl    (sp)+,r9        # reload arblk pointer
                   17945:        movl    r10,4*arpr2(r9) # store prototype ptr (nn02)
                   17946:        subl2   $num02,r6       # adjust length to point to zero
                   17947:        movab   cfp$f(r10)[r6],r10 # point to zero
                   17948:        movl    $ch$cm,r7       # load a comma
                   17949:        movb    r7,(r10)        # store a comma over the zero
                   17950:        #csc    r10             # complete store characters
                   17951: #
                   17952: #      NORMAL RETURN
                   17953: #
                   17954: gtar8: addl2   $4*1,(sp)       # return to caller
                   17955:        rsb     
                   17956: #
                   17957: #      NON-CONVERSION RETURN
                   17958: #
                   17959: gtar9: movl    (sp)+,r9        # restore stack for conv err (sgd02)
                   17960: #
                   17961: #      MERGE TO TAKE CONVERT ERROR WHEN STACK ADJUSTED OK
                   17962: #
                   17963: gta9a: movl    (sp)+,r11       # return
                   17964:        jmp     *(r11)+
                   17965:        #enp                    # procedure gtarr
                   17966:        #page   
                   17967: #
                   17968: #      GTCOD -- CONVERT TO CODE
                   17969: #
                   17970: #      (XR)                  OBJECT TO BE CONVERTED
                   17971: #      JSR  GTCOD            CALL TO CONVERT TO CODE
                   17972: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   17973: #      (XR)                  POINTER TO RESULTING CDBLK
                   17974: #      (XL,WA,WB,WC,RA)      DESTROYED
                   17975: #
                   17976: #      IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE-
                   17977: #      EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   17978: #      WITHOUT RETURNING TO THIS ROUTINE.
                   17979: #
                   17980: gtcod: #prc                    # entry point
                   17981:        cmpl    (r9),$b$cds     # jump if already code
                   17982:        beqlu   gtcd1
                   17983:        cmpl    (r9),$b$cdc     # jump if already code
                   17984:        beqlu   gtcd1
                   17985: #
                   17986: #      HERE WE MUST GENERATE A CDBLK BY COMPILATION
                   17987: #
                   17988:        movl    r9,-(sp)        # stack argument for gtstg
                   17989:        jsb     gtstg           # convert argument to string
                   17990:        .long   gtcd2           # jump if non-convertible
                   17991:        movl    flptr,gtcef     # save fail ptr in case of error
                   17992:        movl    r$cod,r$gtc     # also save code ptr
                   17993:        movl    r9,r$cim        # else set image pointer
                   17994:        movl    r6,scnil        # set image length
                   17995:        clrl    scnpt           # set scan pointer
                   17996:        movl    $stgxc,stage    # set stage for execute compile
                   17997:        movl    cmpsn,lstsn     # in case listr called
                   17998:        jsb     cmpil           # compile string
                   17999:        movl    $stgxt,stage    # reset stage for execute time
                   18000:        clrl    r$cim           # clear image
                   18001: #
                   18002: #      MERGE HERE IF NO CONVERT REQUIRED
                   18003: #
                   18004: gtcd1: addl2   $4*1,(sp)       # give normal gtcod return
                   18005:        rsb     
                   18006: #
                   18007: #      HERE IF UNCONVERTIBLE
                   18008: #
                   18009: gtcd2: movl    (sp)+,r11       # give error return
                   18010:        jmp     *(r11)+
                   18011:        #enp                    # end procedure gtcod
                   18012:        #page   
                   18013: #
                   18014: #      GTEXP -- CONVERT TO EXPRESSION
                   18015: #
                   18016: #      (XR)                  INPUT VALUE TO BE CONVERTED
                   18017: #      JSR  GTEXP            CALL TO CONVERT TO EXPRESSION
                   18018: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18019: #      (XR)                  POINTER TO RESULT EXBLK OR SEBLK
                   18020: #      (XL,WA,WB,WC,RA)      DESTROYED
                   18021: #
                   18022: #      IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE-
                   18023: #      EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   18024: #      WITHOUT RETURNING TO THIS ROUTINE.
                   18025: #
                   18026: gtexp: #prc                    # entry point
                   18027:        cmpl    (r9),$b$e$$     # jump if already an expression
                   18028:        bgtru   0f
                   18029:        jmp     gtex1
                   18030: 0:             
                   18031:        movl    r9,-(sp)        # store argument for gtstg
                   18032:        jsb     gtstg           # convert argument to string
                   18033:        .long   gtex2           # jump if unconvertible
                   18034: #
                   18035: #      CHECK THE LAST CHARACTER OF THE STRING FOR COLON OR
                   18036: #      SEMICOLON.  THESE CHARACTERS CAN LEGITIMATELY END AN
                   18037: #      EXPRESSION IN OPEN CODE, SO EXPAN WILL NOT DETECT THEM
                   18038: #      AS ERRORS, BUT THEY ARE INVALID AS TERMINATORS FOR A
                   18039: #      STRING THAT IS BEING CONVERTED TO EXPRESSION FORM.
                   18040: #
                   18041:        movl    r9,r10          # copy input string pointer (reg06)
                   18042:        movab   cfp$f(r10)[r6],r10 # point one past the string end (reg06)
                   18043:        movzbl  -(r10),r10      # fetch the last character (reg06)
                   18044:        cmpl    r10,$ch$cl      # error if it is a semicolon (reg06)
                   18045:        beqlu   gtex2
                   18046:        cmpl    r10,$ch$sm      # or if it is a colon (reg06)
                   18047:        beqlu   gtex2
                   18048: #
                   18049: #      HERE WE CONVERT A STRING BY COMPILATION
                   18050: #
                   18051:        movl    r9,r$cim        # set input image pointer
                   18052:        clrl    scnpt           # set scan pointer
                   18053:        movl    r6,scnil        # set input image length
                   18054:        clrl    r7              # set code for normal scan
                   18055:        movl    flptr,gtcef     # save fail ptr in case of error
                   18056:        movl    r$cod,r$gtc     # also save code ptr
                   18057:        movl    $stgev,stage    # adjust stage for compile
                   18058:        movl    $t$uok,scntp    # indicate unary operator acceptable
                   18059:        jsb     expan           # build tree for expression
                   18060:        clrl    scnrs           # reset rescan flag
                   18061:        cmpl    scnpt,scnil     # error if not end of image
                   18062:        bnequ   gtex2
                   18063:        clrl    r7              # set ok value for cdgex call
                   18064:        movl    r9,r10          # copy tree pointer
                   18065:        jsb     cdgex           # build expression block
                   18066:        clrl    r$cim           # clear pointer
                   18067:        movl    $stgxt,stage    # restore stage for execute time
                   18068: #
                   18069: #      MERGE HERE IF NO CONVERSION REQUIRED
                   18070: #
                   18071: gtex1: addl2   $4*1,(sp)       # return to gtexp caller
                   18072:        rsb     
                   18073: #
                   18074: #      HERE IF UNCONVERTIBLE
                   18075: #
                   18076: gtex2: movl    (sp)+,r11       # take error exit
                   18077:        jmp     *(r11)+
                   18078:        #enp                    # end procedure gtexp
                   18079:        #page   
                   18080: #
                   18081: #      GTINT -- GET INTEGER VALUE
                   18082: #
                   18083: #      GTINT IS PASSED AN OBJECT AND RETURNS AN INTEGER AFTER
                   18084: #      PERFORMING ANY NECESSARY CONVERSIONS.
                   18085: #
                   18086: #      (XR)                  VALUE TO BE CONVERTED
                   18087: #      JSR  GTINT            CALL TO CONVERT TO INTEGER
                   18088: #      PPM  LOC              TRANSFER LOC FOR CONVERT IMPOSSIBLE
                   18089: #      (XR)                  RESULTING INTEGER
                   18090: #      (WC,RA)               DESTROYED
                   18091: #      (WA,WB)               DESTROYED (ONLY ON CONVERSION ERR)
                   18092: #      (XR)                  UNCHANGED (ON CONVERT ERROR)
                   18093: #
                   18094: gtint: #prc                    # entry point
                   18095:        cmpl    (r9),$b$icl     # jump if already an integer
                   18096:        beqlu   gtin2
                   18097:        movl    r6,gtina        # else save wa
                   18098:        movl    r7,gtinb        # save wb
                   18099:        jsb     gtnum           # convert to numeric
                   18100:        .long   gtin3           # jump if unconvertible
                   18101:        cmpl    r6,$b$icl       # jump if integer
                   18102:        beqlu   gtin1
                   18103: #
                   18104: #      HERE WE CONVERT A REAL TO INTEGER
                   18105: #
                   18106:        movf    4*rcval(r9),r2  # load real value
                   18107:        cvtfl   r2,r5           # convert to integer (err if ovflow)
                   18108:        bvs     gtin3
                   18109:        jsb     icbld           # if ok build icblk
                   18110: #
                   18111: #      HERE AFTER SUCCESSFUL CONVERSION TO INTEGER
                   18112: #
                   18113: gtin1: movl    gtina,r6        # restore wa
                   18114:        movl    gtinb,r7        # restore wb
                   18115: #
                   18116: #      COMMON EXIT POINT
                   18117: #
                   18118: gtin2: addl2   $4*1,(sp)       # return to gtint caller
                   18119:        rsb     
                   18120: #
                   18121: #      HERE ON CONVERSION ERROR
                   18122: #
                   18123: gtin3: movl    (sp)+,r11       # take convert error exit
                   18124:        jmp     *(r11)+
                   18125:        #enp                    # end procedure gtint
                   18126:        #page   
                   18127: #
                   18128: #      GTNUM -- GET NUMERIC VALUE
                   18129: #
                   18130: #      GTNUM IS GIVEN AN OBJECT AND RETURNS EITHER AN INTEGER
                   18131: #      OR A REAL, PERFORMING ANY NECESSARY CONVERSIONS.
                   18132: #
                   18133: #      (XR)                  OBJECT TO BE CONVERTED
                   18134: #      JSR  GTNUM            CALL TO CONVERT TO NUMERIC
                   18135: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18136: #      (XR)                  POINTER TO RESULT (INT OR REAL)
                   18137: #      (WA)                  FIRST WORD OF RESULT BLOCK
                   18138: #      (WB,WC,RA)            DESTROYED
                   18139: #      (XR)                  UNCHANGED (ON CONVERT ERROR)
                   18140: #
                   18141: gtnum: #prc                    # entry point
                   18142:        movl    (r9),r6         # load first word of block
                   18143:        cmpl    r6,$b$icl       # jump if integer (no conversion)
                   18144:        bnequ   0f
                   18145:        jmp     gtn34
                   18146: 0:             
                   18147:        cmpl    r6,$b$rcl       # jump if real (no conversion)
                   18148:        bnequ   0f
                   18149:        jmp     gtn34
                   18150: 0:             
                   18151: #
                   18152: #      AT THIS POINT THE ONLY POSSIBILITY IS TO CONVERT A STRING
                   18153: #      TO AN INTEGER OR REAL AS APPROPRIATE.
                   18154: #
                   18155:        movl    r9,-(sp)        # stack argument in case convert err
                   18156:        movl    r9,-(sp)        # stack argument for gtstg
                   18157:        jsb     gtstg           # convert argument to string
                   18158:        .long   gtn36           # jump if unconvertible
                   18159: #
                   18160: #      INITIALIZE NUMERIC CONVERSION
                   18161: #
                   18162:        movl    intv0,r5        # initialize integer result to zero
                   18163:        tstl    r6              # jump to exit with zero if null
                   18164:        bnequ   0f
                   18165:        jmp     gtn32
                   18166: 0:             
                   18167:                                # set bct counter for following loops
                   18168:        clrl    gtnnf           # tentatively indicate result +
                   18169:        movl    r5,gtnex        # initialise exponent to zero
                   18170:        clrl    gtnsc           # zero scale in case real
                   18171:        clrl    gtndf           # reset flag for dec point found
                   18172:        clrl    gtnrd           # reset flag for digits found
                   18173:        movf    reav0,r2        # zero real accum in case real
                   18174:        movab   cfp$f(r9),r9    # point to argument characters
                   18175: #
                   18176: #      MERGE BACK HERE AFTER IGNORING LEADING BLANK
                   18177: #
                   18178: gtn01: movzbl  (r9)+,r7        # load first character
                   18179:        cmpl    r7,$ch$d0       # jump if not digit
                   18180:        blssu   gtn02
                   18181:        cmpl    r7,$ch$d9       # jump if first char is a digit
                   18182:        blequ   gtn06
                   18183:        #page   
                   18184: #
                   18185: #      GTNUM (CONTINUED)
                   18186: #
                   18187: #      HERE IF FIRST DIGIT IS NON-DIGIT
                   18188: #
                   18189: gtn02: cmpl    r7,$ch$bl       # jump if non-blank
                   18190:        bnequ   gtn03
                   18191: gtna2: sobgtr  r6,gtn01        # else decr count and loop back
                   18192:        jmp     gtn07           # jump to return zero if all blanks
                   18193: #
                   18194: #      HERE FOR FIRST CHARACTER NON-BLANK, NON-DIGIT
                   18195: #
                   18196: gtn03: cmpl    r7,$ch$pl       # jump if plus sign
                   18197:        beqlu   gtn04
                   18198:        cmpl    r7,$ch$ht       # horizontal tab equiv to blank
                   18199:        beqlu   gtna2
                   18200:        cmpl    r7,$ch$mn       # jump if not minus (may be real)
                   18201:        beqlu   0f
                   18202:        jmp     gtn12
                   18203: 0:             
                   18204:        movl    sp,gtnnf        # if minus sign, set negative flag
                   18205: #
                   18206: #      MERGE HERE AFTER PROCESSING SIGN
                   18207: #
                   18208: gtn04: sobgtr  r6,gtn05        # jump if chars left
                   18209:        jmp     gtn36           # else error
                   18210: #
                   18211: #      LOOP TO FETCH CHARACTERS OF AN INTEGER
                   18212: #
                   18213: gtn05: movzbl  (r9)+,r7        # load next character
                   18214:        cmpl    r7,$ch$d0       # jump if not a digit
                   18215:        blssu   gtn08
                   18216:        cmpl    r7,$ch$d9       # jump if not a digit
                   18217:        bgtru   gtn08
                   18218: #
                   18219: #      MERGE HERE FOR FIRST DIGIT
                   18220: #
                   18221: gtn06: movl    r5,gtnsi        # save current value
                   18222:        mull2   $10,r5          # current*10-(new dig) jump if ovflow
                   18223:        bvc     0f
                   18224:        jmp     gtn35
                   18225: 0:     bicl2   $0xfffffff0,r7
                   18226:        subl2   r7,r5
                   18227:        bvc     1f
                   18228:        jmp     gtn35
                   18229: 1:             
                   18230:        movl    sp,gtnrd        # set digit read flag
                   18231:        sobgtr  r6,gtn05        # else loop back if more chars
                   18232: #
                   18233: #      HERE TO EXIT WITH CONVERTED INTEGER VALUE
                   18234: #
                   18235: gtn07: tstl    gtnnf           # jump if negative (all set)
                   18236:        beqlu   0f
                   18237:        jmp     gtn32
                   18238: 0:             
                   18239:        mnegl   r5,r5           # else negate
                   18240:        bvs     0f
                   18241:        jmp     gtn32
                   18242: 0:             
                   18243:        jmp     gtn36           # else signal error
                   18244:        #page   
                   18245: #
                   18246: #      GTNUM (CONTINUED)
                   18247: #
                   18248: #      HERE FOR A NON-DIGIT CHARACTER WHILE ATTEMPTING TO
                   18249: #      CONVERT AN INTEGER, CHECK FOR TRAILING BLANKS OR REAL.
                   18250: #
                   18251: gtn08: cmpl    r7,$ch$bl       # jump if a blank
                   18252:        beqlu   gtna9
                   18253:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18254:        beqlu   gtna9
                   18255:        cvtlf   r5,r2           # else convert integer to real
                   18256:        mnegf   r2,r2           # negate to get positive value
                   18257:        jmp     gtn12           # jump to try for real
                   18258: #
                   18259: #      HERE WE SCAN OUT BLANKS TO END OF STRING
                   18260: #
                   18261: gtn09: movzbl  (r9)+,r7        # get next char
                   18262:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18263:        beqlu   gtna9
                   18264:        cmpl    r7,$ch$bl       # error if non-blank
                   18265:        beqlu   0f
                   18266:        jmp     gtn36
                   18267: 0:             
                   18268: gtna9: sobgtr  r6,gtn09        # loop back if more chars to check
                   18269:        jmp     gtn07           # return integer if all blanks
                   18270: #
                   18271: #      LOOP TO COLLECT MANTISSA OF REAL
                   18272: #
                   18273: gtn10: movzbl  (r9)+,r7        # load next character
                   18274:        cmpl    r7,$ch$d0       # jump if non-numeric
                   18275:        bgequ   0f
                   18276:        jmp     gtn12
                   18277: 0:             
                   18278:        cmpl    r7,$ch$d9       # jump if non-numeric
                   18279:        blequ   0f
                   18280:        jmp     gtn12
                   18281: 0:             
                   18282: #
                   18283: #      MERGE HERE TO COLLECT FIRST REAL DIGIT
                   18284: #
                   18285: gtn11: subl2   $ch$d0,r7       # convert digit to number
                   18286:        mulf2   reavt,r2        # multiply real by 10.0
                   18287:        bvc     0f
                   18288:        jmp     gtn36
                   18289: 0:             
                   18290:        movf    r2,gtnsr        # save result
                   18291:        movl    r7,r5           # get new digit as integer
                   18292:        cvtlf   r5,r2           # convert new digit to real
                   18293:        addf2   gtnsr,r2        # add to get new total
                   18294:        addl2   gtndf,gtnsc     # increment scale if after dec point
                   18295:        movl    sp,gtnrd        # set digit found flag
                   18296:        sobgtr  r6,gtn10        # loop back if more chars
                   18297:        jmp     gtn22           # else jump to scale
                   18298:        #page   
                   18299: #
                   18300: #      GTNUM (CONTINUED)
                   18301: #
                   18302: #      HERE IF NON-DIGIT FOUND WHILE COLLECTING A REAL
                   18303: #
                   18304: gtn12: cmpl    r7,$ch$dt       # jump if not dec point
                   18305:        bnequ   gtn13
                   18306:        tstl    gtndf           # if dec point, error if one already
                   18307:        beqlu   0f
                   18308:        jmp     gtn36
                   18309: 0:             
                   18310:        movl    $num01,gtndf    # else set flag for dec point
                   18311:        sobgtr  r6,gtn10        # loop back if more chars
                   18312:        jmp     gtn22           # else jump to scale
                   18313: #
                   18314: #      HERE IF NOT DECIMAL POINT
                   18315: #
                   18316: gtn13: cmpl    r7,$ch$le       # jump if e for exponent
                   18317:        beqlu   gtn15
                   18318:        cmpl    r7,$ch$ld       # jump if d for exponent
                   18319:        beqlu   gtn15
                   18320:        cmpl    r7,$ch$$e       # jump if e for exponent
                   18321:        beqlu   gtn15
                   18322:        cmpl    r7,$ch$$d       # jump if d for exponent
                   18323:        beqlu   gtn15
                   18324: #
                   18325: #      HERE CHECK FOR TRAILING BLANKS
                   18326: #
                   18327: gtn14: cmpl    r7,$ch$bl       # jump if blank
                   18328:        beqlu   gtnb4
                   18329:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18330:        beqlu   gtnb4
                   18331:        jmp     gtn36           # error if non-blank
                   18332: #
                   18333: gtnb4: movzbl  (r9)+,r7        # get next character
                   18334:        sobgtr  r6,gtn14        # loop back to check if more
                   18335:        jmp     gtn22           # else jump to scale
                   18336: #
                   18337: #      HERE TO READ AND PROCESS AN EXPONENT
                   18338: #
                   18339: gtn15: clrl    gtnes           # set exponent sign positive
                   18340:        movl    intv0,r5        # initialize exponent to zero
                   18341:        movl    sp,gtndf        # reset no dec point indication
                   18342:        sobgtr  r6,gtn16        # jump skipping past e or d
                   18343:        jmp     gtn36           # error if null exponent
                   18344: #
                   18345: #      CHECK FOR EXPONENT SIGN
                   18346: #
                   18347: gtn16: movzbl  (r9)+,r7        # load first exponent character
                   18348:        cmpl    r7,$ch$pl       # jump if plus sign
                   18349:        beqlu   gtn17
                   18350:        cmpl    r7,$ch$mn       # else jump if not minus sign
                   18351:        bnequ   gtn19
                   18352:        movl    sp,gtnes        # set sign negative if minus sign
                   18353: #
                   18354: #      MERGE HERE AFTER PROCESSING EXPONENT SIGN
                   18355: #
                   18356: gtn17: sobgtr  r6,gtn18        # jump if chars left
                   18357:        jmp     gtn36           # else error
                   18358: #
                   18359: #      LOOP TO CONVERT EXPONENT DIGITS
                   18360: #
                   18361: gtn18: movzbl  (r9)+,r7        # load next character
                   18362:        #page   
                   18363: #
                   18364: #      GTNUM (CONTINUED)
                   18365: #
                   18366: #      MERGE HERE FOR FIRST EXPONENT DIGIT
                   18367: #
                   18368: gtn19: cmpl    r7,$ch$d0       # jump if not digit
                   18369:        blssu   gtn20
                   18370:        cmpl    r7,$ch$d9       # jump if not digit
                   18371:        bgtru   gtn20
                   18372:        mull2   $10,r5          # else current*10, subtract new digit
                   18373:        bvc     0f
                   18374:        jmp     gtn36
                   18375: 0:     bicl2   $0xfffffff0,r7
                   18376:        subl2   r7,r5
                   18377:        bvc     1f
                   18378:        jmp     gtn36
                   18379: 1:             
                   18380:        sobgtr  r6,gtn18        # loop back if more chars
                   18381:        jmp     gtn21           # jump if exponent field is exhausted
                   18382: #
                   18383: #      HERE TO CHECK FOR TRAILING BLANKS AFTER EXPONENT
                   18384: #
                   18385: gtn20: cmpl    r7,$ch$bl       # jump if blank
                   18386:        beqlu   gtnc0
                   18387:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18388:        beqlu   gtnc0
                   18389:        jmp     gtn36           # error if non-blank
                   18390: #
                   18391: gtnc0: movzbl  (r9)+,r7        # get next character
                   18392:        sobgtr  r6,gtn20        # loop back till all blanks scanned
                   18393: #
                   18394: #      MERGE HERE AFTER COLLECTING EXPONENT
                   18395: #
                   18396: gtn21: movl    r5,gtnex        # save collected exponent
                   18397:        tstl    gtnes           # jump if it was negative
                   18398:        bnequ   gtn22
                   18399:        mnegl   r5,r5           # else complement
                   18400:        bvc     0f
                   18401:        jmp     gtn36
                   18402: 0:             
                   18403:        movl    r5,gtnex        # and store positive exponent
                   18404: #
                   18405: #      MERGE HERE WITH EXPONENT (0 IF NONE GIVEN)
                   18406: #
                   18407: gtn22: tstl    gtnrd           # error if not digits collected
                   18408:        bnequ   0f
                   18409:        jmp     gtn36
                   18410: 0:             
                   18411:        tstl    gtndf           # error if no exponent or dec point
                   18412:        bnequ   0f
                   18413:        jmp     gtn36
                   18414: 0:             
                   18415:        movl    gtnsc,r5        # else load scale as integer
                   18416:        subl2   gtnex,r5        # subtract exponent
                   18417:        bvc     0f
                   18418:        jmp     gtn36
                   18419: 0:             
                   18420:        tstl    r5              # jump if we must scale up
                   18421:        blss    gtn26
                   18422: #
                   18423: #      HERE WE HAVE A NEGATIVE EXPONENT, SO SCALE DOWN
                   18424: #
                   18425:        movl    r5,r6           # load scale factor, err if ovflow
                   18426:        bgeq    0f
                   18427:        jmp     gtn36
                   18428: 0:             
                   18429: #
                   18430: #      LOOP TO SCALE DOWN IN STEPS OF 10**10
                   18431: #
                   18432: gtn23: cmpl    r6,$num10       # jump if 10 or less to go
                   18433:        blequ   gtn24
                   18434:        divf2   reatt,r2        # else divide by 10**10
                   18435:        subl2   $num10,r6       # decrement scale
                   18436:        jmp     gtn23           # and loop back
                   18437:        #page   
                   18438: #
                   18439: #      GTNUM (CONTINUED)
                   18440: #
                   18441: #      HERE SCALE REST OF WAY FROM POWERS OF TEN TABLE
                   18442: #
                   18443: gtn24: tstl    r6              # jump if scaled
                   18444:        beqlu   gtn30
                   18445:        movl    $cfp$r,r7       # else get indexing factor
                   18446:        movl    $reav1,r9       # point to powers of ten table
                   18447:        moval   0[r6],r6        # convert remaining scale to byte ofs
                   18448: #
                   18449: #      LOOP TO POINT TO POWERS OF TEN TABLE ENTRY
                   18450: #
                   18451: gtn25: addl2   r6,r9           # bump pointer
                   18452:        sobgtr  r7,gtn25        # once for each value word
                   18453:        divf2   (r9),r2         # scale down as required
                   18454:        jmp     gtn30           # and jump
                   18455: #
                   18456: #      COME HERE TO SCALE RESULT UP (POSITIVE EXPONENT)
                   18457: #
                   18458: gtn26: mnegl   r5,r5           # get absolute value of exponent
                   18459:        bvc     0f
                   18460:        jmp     gtn36
                   18461: 0:             
                   18462:        movl    r5,r6           # acquire scale, error if ovflow
                   18463:        bgeq    0f
                   18464:        jmp     gtn36
                   18465: 0:             
                   18466: #
                   18467: #      LOOP TO SCALE UP IN STEPS OF 10**10
                   18468: #
                   18469: gtn27: cmpl    r6,$num10       # jump if 10 or less to go
                   18470:        blequ   gtn28
                   18471:        mulf2   reatt,r2        # else multiply by 10**10
                   18472:        bvc     0f
                   18473:        jmp     gtn36
                   18474: 0:             
                   18475:        subl2   $num10,r6       # else decrement scale
                   18476:        jmp     gtn27           # and loop back
                   18477: #
                   18478: #      HERE TO SCALE UP REST OF WAY WITH TABLE
                   18479: #
                   18480: gtn28: tstl    r6              # jump if scaled
                   18481:        beqlu   gtn30
                   18482:        movl    $cfp$r,r7       # else get indexing factor
                   18483:        movl    $reav1,r9       # point to powers of ten table
                   18484:        moval   0[r6],r6        # convert remaining scale to byte ofs
                   18485: #
                   18486: #      LOOP TO POINT TO PROPER ENTRY IN POWERS OF TEN TABLE
                   18487: #
                   18488: gtn29: addl2   r6,r9           # bump pointer
                   18489:        sobgtr  r7,gtn29        # once for each word in value
                   18490:        mulf2   (r9),r2         # scale up
                   18491:        bvc     0f
                   18492:        jmp     gtn36
                   18493: 0:             
                   18494:        #page   
                   18495: #
                   18496: #      GTNUM (CONTINUED)
                   18497: #
                   18498: #      HERE WITH REAL VALUE SCALED AND READY EXCEPT FOR SIGN
                   18499: #
                   18500: gtn30: tstl    gtnnf           # jump if positive
                   18501:        beqlu   gtn31
                   18502:        mnegf   r2,r2           # else negate
                   18503: #
                   18504: #      HERE WITH PROPERLY SIGNED REAL VALUE IN (RA)
                   18505: #
                   18506: gtn31: jsb     rcbld           # build real block
                   18507:        jmp     gtn33           # merge to exit
                   18508: #
                   18509: #      HERE WITH PROPERLY SIGNED INTEGER VALUE IN (IA)
                   18510: #
                   18511: gtn32: jsb     icbld           # build icblk
                   18512: #
                   18513: #      REAL MERGES HERE
                   18514: #
                   18515: gtn33: movl    (r9),r6         # load first word of result block
                   18516:        addl2   $4,sp           # pop argument off stack
                   18517: #
                   18518: #      COMMON EXIT POINT
                   18519: #
                   18520: gtn34: addl2   $4*1,(sp)       # return to gtnum caller
                   18521:        rsb     
                   18522: #
                   18523: #      COME HERE IF OVERFLOW OCCURS DURING COLLECTION OF INTEGER
                   18524: #
                   18525: gtn35: movl    gtnsi,r5        # reload integer so far
                   18526:        cvtlf   r5,r2           # convert to real
                   18527:        mnegf   r2,r2           # make value positive
                   18528:        jmp     gtn11           # merge with real circuit
                   18529: #
                   18530: #      HERE FOR UNCONVERTIBLE TO STRING OR CONVERSION ERROR
                   18531: #
                   18532: gtn36: movl    (sp)+,r9        # reload original argument
                   18533:        movl    (sp)+,r11       # take convert-error exit
                   18534:        jmp     *(r11)+
                   18535:        #enp                    # end procedure gtnum
                   18536:        #page   
                   18537: #
                   18538: #      GTNVR -- CONVERT TO NATURAL VARIABLE
                   18539: #
                   18540: #      GTNVR LOCATES A VARIABLE BLOCK (VRBLK) GIVEN EITHER AN
                   18541: #      APPROPRIATE NAME (NMBLK) OR A NON-NULL STRING (SCBLK).
                   18542: #
                   18543: #      (XR)                  ARGUMENT
                   18544: #      JSR  GTNVR            CALL TO CONVERT TO NATURAL VARIABLE
                   18545: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18546: #      (XR)                  POINTER TO VRBLK
                   18547: #      (WA,WB)               DESTROYED (CONVERSION ERROR ONLY)
                   18548: #      (WC)                  DESTROYED
                   18549: #
                   18550: gtnvr: #prc                    # entry point
                   18551:        cmpl    (r9),$b$nml     # jump if not name
                   18552:        bnequ   gnv02
                   18553:        movl    4*nmbas(r9),r9  # else load name base if name
                   18554:        cmpl    r9,state        # skip if vrblk (in static region)
                   18555:        bgtru   0f
                   18556:        jmp     gnv07
                   18557: 0:             
                   18558: #
                   18559: #      COMMON ERROR EXIT
                   18560: #
                   18561: gnv01: movl    (sp)+,r11       # take convert-error exit
                   18562:        jmp     *(r11)+
                   18563: #
                   18564: #      HERE IF NOT NAME
                   18565: #
                   18566: gnv02: movl    r6,gnvsa        # save wa
                   18567:        movl    r7,gnvsb        # save wb
                   18568:        movl    r9,-(sp)        # stack argument for gtstg
                   18569:        jsb     gtstg           # convert argument to string
                   18570:        .long   gnv01           # jump if conversion error
                   18571:        tstl    r6              # null string is an error
                   18572:        beqlu   gnv01
                   18573:        jsb     flstg           # fold lower case to upper case
                   18574:        movl    r10,-(sp)       # save xl
                   18575:        movl    r9,-(sp)        # stack string ptr for later
                   18576:        movl    r9,r7           # copy string pointer
                   18577:        addl2   $4*schar,r7     # point to characters of string
                   18578:        movl    r7,gnvst        # save pointer to characters
                   18579:        movl    r6,r7           # copy length
                   18580:        movab   3+(4*0)(r7),r7  # get number of words in name
                   18581:        ashl    $-2,r7,r7
                   18582:        movl    r7,gnvnw        # save for later
                   18583:        jsb     hashs           # compute hash index for string
                   18584:        ashq    $-32,r4,r4      # compute hash offset by taking mod
                   18585:        ediv    hshnb,r4,r11,r5
                   18586:        movl    r5,r8           # get as offset
                   18587:        moval   0[r8],r8        # convert offset to bytes
                   18588:        addl2   hshtb,r8        # point to proper hash chain
                   18589:        subl2   $4*vrnxt,r8     # subtract offset to merge into loop
                   18590:        #page   
                   18591: #
                   18592: #      GTNVR (CONTINUED)
                   18593: #
                   18594: #      LOOP TO SEARCH HASH CHAIN
                   18595: #
                   18596: gnv03: movl    r8,r10          # copy hash chain pointer
                   18597:        movl    4*vrnxt(r10),r10# point to next vrblk on chain
                   18598:        tstl    r10             # jump if end of chain
                   18599:        beqlu   gnv08
                   18600:        movl    r10,r8          # save pointer to this vrblk
                   18601:        tstl    4*vrlen(r10)    # jump if not system variable
                   18602:        bnequ   gnv04
                   18603:        movl    4*vrsvp(r10),r10# else point to svblk
                   18604:        subl2   $4*vrsof,r10    # adjust offset for merge
                   18605: #
                   18606: #      MERGE HERE WITH STRING PTR (LIKE VRBLK) IN XL
                   18607: #
                   18608: gnv04: cmpl    r6,4*vrlen(r10) # back for next vrblk if lengths ne
                   18609:        bnequ   gnv03
                   18610:        addl2   $4*vrchs,r10    # else point to chars of chain entry
                   18611:        movl    gnvnw,r7        # get word counter to control loop
                   18612:        movl    gnvst,r9        # point to chars of new name
                   18613: #
                   18614: #      LOOP TO COMPARE CHARACTERS OF THE TWO NAMES
                   18615: #
                   18616: gnv05: cmpl    (r9),(r10)      # jump if no match for next vrblk
                   18617:        bnequ   gnv03
                   18618:        addl2   $4,r9           # bump new name pointer
                   18619:        addl2   $4,r10          # bump vrblk in chain name pointer
                   18620:        sobgtr  r7,gnv05        # else loop till all compared
                   18621:        movl    r8,r9           # we have found a match, get vrblk
                   18622: #
                   18623: #      EXIT POINT AFTER FINDING VRBLK OR BUILDING NEW ONE
                   18624: #
                   18625: gnv06: movl    gnvsa,r6        # restore wa
                   18626:        movl    gnvsb,r7        # restore wb
                   18627:        addl2   $4,sp           # pop string pointer
                   18628:        movl    (sp)+,r10       # restore xl
                   18629: #
                   18630: #      COMMON EXIT POINT
                   18631: #
                   18632: gnv07: addl2   $4*1,(sp)       # return to gtnvr caller
                   18633:        rsb     
                   18634: #
                   18635: #      NOT FOUND, PREPARE TO SEARCH SYSTEM VARIABLE TABLE
                   18636: #
                   18637: gnv08: clrl    r9              # clear garbage xr pointer
                   18638:        movl    r8,gnvhe        # save ptr to end of hash chain
                   18639:        cmpl    r6,$num09       # cannot be system var if length gt 9
                   18640:        bgtru   gnv14
                   18641:        movl    r6,r10          # else copy length
                   18642:        moval   0[r10],r10      # convert to byte offset
                   18643:        movl    l^vsrch(r10),r10# point to first svblk of this length
                   18644:        #page   
                   18645: #
                   18646: #      GTNVR (CONTINUED)
                   18647: #
                   18648: #      LOOP TO SEARCH ENTRIES IN STANDARD VARIABLE TABLE
                   18649: #
                   18650: gnv09: movl    r10,gnvsp       # save table pointer
                   18651:        movl    (r10)+,r8       # load svbit bit string
                   18652:        movl    (r10)+,r7       # load length from table entry
                   18653:        cmpl    r6,r7           # jump if end of right length entires
                   18654:        bnequ   gnv14
                   18655:        movl    gnvnw,r7        # get word counter to control loop
                   18656:        movl    gnvst,r9        # point to chars of new name
                   18657: #
                   18658: #      LOOP TO CHECK FOR MATCHING NAMES
                   18659: #
                   18660: gnv10: cmpl    (r9),(r10)      # jump if name mismatch
                   18661:        bnequ   gnv11
                   18662:        addl2   $4,r9           # else bump new name pointer
                   18663:        addl2   $4,r10          # bump svblk pointer
                   18664:        sobgtr  r7,gnv10        # else loop until all checked
                   18665: #
                   18666: #      HERE WE HAVE A MATCH IN THE STANDARD VARIABLE TABLE
                   18667: #
                   18668:        clrl    r8              # set vrlen value zero
                   18669:        movl    $4*vrsi$,r6     # set standard size
                   18670:        jmp     gnv15           # jump to build vrblk
                   18671: #
                   18672: #      HERE IF NO MATCH WITH TABLE ENTRY IN SVBLKS TABLE
                   18673: #
                   18674: gnv11: addl2   $4,r10          # bump past word of chars
                   18675:        sobgtr  r7,gnv11        # loop back if more to go
                   18676:        ashl    $-svnbt,r8,r8   # remove uninteresting bits
                   18677: #
                   18678: #      LOOP TO BUMP TABLE PTR FOR EACH FLAGGED WORD
                   18679: #
                   18680: gnv12: movl    bits1,r7        # load bit to test
                   18681:        mcoml   r8,r11          # test for word present
                   18682:        bicl2   r11,r7
                   18683:        tstl    r7              # jump if not present
                   18684:        beqlu   gnv13
                   18685:        addl2   $4,r10          # else bump table pointer
                   18686: #
                   18687: #      HERE AFTER DEALING WITH ONE WORD (ONE BIT)
                   18688: #
                   18689: gnv13: ashl    $-1,r8,r8       # remove bit already processed
                   18690:        tstl    r8              # loop back if more bits to test
                   18691:        bnequ   gnv12
                   18692:        jmp     gnv09           # else loop back for next svblk
                   18693: #
                   18694: #      HERE IF NOT SYSTEM VARIABLE
                   18695: #
                   18696: gnv14: movl    r6,r8           # copy vrlen value
                   18697:        movl    $vrchs,r6       # load standard size -chars
                   18698:        addl2   gnvnw,r6        # adjust for chars of name
                   18699:        moval   0[r6],r6        # convert length to bytes
                   18700:        #page   
                   18701: #
                   18702: #      GTNVR (CONTINUED)
                   18703: #
                   18704: #      MERGE HERE TO BUILD VRBLK
                   18705: #
                   18706: gnv15: jsb     alost           # allocate space for vrblk (static)
                   18707:        movl    r9,r7           # save vrblk pointer
                   18708:        movl    $stnvr,r10      # point to model variable block
                   18709:        movl    $4*vrlen,r6     # set length of standard fields
                   18710:        jsb     sbmvw           # set initial fields of new block
                   18711:        movl    gnvhe,r10       # load pointer to end of hash chain
                   18712:        movl    r7,4*vrnxt(r10) # add new block to end of chain
                   18713:        movl    r8,(r9)+        # set vrlen field, bump ptr
                   18714:        movl    gnvnw,r6        # get length in words
                   18715:        moval   0[r6],r6        # convert to length in bytes
                   18716:        tstl    r8              # jump if system variable
                   18717:        beqlu   gnv16
                   18718: #
                   18719: #      HERE FOR NON-SYSTEM VARIABLE -- SET CHARS OF NAME
                   18720: #
                   18721:        movl    (sp),r10        # point back to string name
                   18722:        addl2   $4*schar,r10    # point to chars of name
                   18723:        jsb     sbmvw           # move characters into place
                   18724:        movl    r7,r9           # restore vrblk pointer
                   18725:        jmp     gnv06           # jump back to exit
                   18726: #
                   18727: #      HERE FOR SYSTEM VARIABLE CASE TO FILL IN FIELDS WHERE
                   18728: #      NECESSARY FROM THE FIELDS PRESENT IN THE SVBLK.
                   18729: #
                   18730: gnv16: movl    gnvsp,r10       # load pointer to svblk
                   18731:        movl    r10,(r9)        # set svblk ptr in vrblk
                   18732:        movl    r7,r9           # restore vrblk pointer
                   18733:        movl    4*svbit(r10),r7 # load bit indicators
                   18734:        addl2   $4*svchs,r10    # point to characters of name
                   18735:        addl2   r6,r10          # point past characters
                   18736: #
                   18737: #      SKIP PAST KEYWORD NUMBER (SVKNM) IF PRESENT
                   18738: #
                   18739:        movl    btknm,r8        # load test bit
                   18740:        mcoml   r7,r11          # and to test
                   18741:        bicl2   r11,r8
                   18742:        tstl    r8              # jump if no keyword number
                   18743:        beqlu   gnv17
                   18744:        addl2   $4,r10          # else bump pointer
                   18745:        #page   
                   18746: #
                   18747: #      GTNVR (CONTINUED)
                   18748: #
                   18749: #      HERE TEST FOR FUNCTION (SVFNC AND SVNAR)
                   18750: #
                   18751: gnv17: movl    btfnc,r8        # get test bit
                   18752:        mcoml   r7,r11          # and to test
                   18753:        bicl2   r11,r8
                   18754:        tstl    r8              # skip if no system function
                   18755:        beqlu   gnv18
                   18756:        movl    r10,4*vrfnc(r9) # else point vrfnc to svfnc field
                   18757:        addl2   $4*num02,r10    # and bump past svfnc, svnar fields
                   18758: #
                   18759: #      NOW TEST FOR LABEL (SVLBL)
                   18760: #
                   18761: gnv18: movl    btlbl,r8        # get test bit
                   18762:        mcoml   r7,r11          # and to test
                   18763:        bicl2   r11,r8
                   18764:        tstl    r8              # jump if bit is off (no system labl)
                   18765:        beqlu   gnv19
                   18766:        movl    r10,4*vrlbl(r9) # else point vrlbl to svlbl field
                   18767:        addl2   $4,r10          # bump past svlbl field
                   18768: #
                   18769: #      NOW TEST FOR VALUE (SVVAL)
                   18770: #
                   18771: gnv19: movl    btval,r8        # load test bit
                   18772:        mcoml   r7,r11          # and to test
                   18773:        bicl2   r11,r8
                   18774:        tstl    r8              # all done if no value
                   18775:        bnequ   0f
                   18776:        jmp     gnv06
                   18777: 0:             
                   18778:        movl    (r10),4*vrval(r9)# else set initial value
                   18779:        movl    $b$vre,4*vrsto(r9) # set error store access
                   18780:        jmp     gnv06           # merge back to exit to caller
                   18781:        #enp                    # end procedure gtnvr
                   18782:        #page   
                   18783: #
                   18784: #      GTPAT -- GET PATTERN
                   18785: #
                   18786: #      GTPAT IS PASSED AN OBJECT IN (XR) AND RETURNS A
                   18787: #      PATTERN AFTER PERFORMING ANY NECESSARY CONVERSIONS
                   18788: #
                   18789: #      (XR)                  INPUT ARGUMENT
                   18790: #      JSR  GTPAT            CALL TO CONVERT TO PATTERN
                   18791: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18792: #      (XR)                  RESULTING PATTERN
                   18793: #      (WA)                  DESTROYED
                   18794: #      (WB)                  DESTROYED (ONLY ON CONVERT ERROR)
                   18795: #      (XR)                  UNCHANGED (ONLY ON CONVERT ERROR)
                   18796: #
                   18797: gtpat: #prc                    # entry point
                   18798:        cmpl    (r9),$p$aaa     # jump if pattern already
                   18799:        bgequ   gtpt5
                   18800: #
                   18801: #      HERE IF NOT PATTERN, TRY FOR STRING
                   18802: #
                   18803:        movl    r7,gtpsb        # save wb
                   18804:        movl    r9,-(sp)        # stack argument for gtstg
                   18805:        jsb     gtstg           # convert argument to string
                   18806:        .long   gtpt2           # jump if impossible
                   18807: #
                   18808: #      HERE WE HAVE A STRING
                   18809: #
                   18810:        tstl    r6              # jump if non-null
                   18811:        bnequ   gtpt1
                   18812: #
                   18813: #      HERE FOR NULL STRING. GENERATE POINTER TO NULL PATTERN.
                   18814: #
                   18815:        movl    $ndnth,r9       # point to nothen node
                   18816:        jmp     gtpt4           # jump to exit
                   18817:        #page   
                   18818: #
                   18819: #      GTPAT (CONTINUED)
                   18820: #
                   18821: #      HERE FOR NON-NULL STRING
                   18822: #
                   18823: gtpt1: movl    $p$str,r7       # load pcode for multi-char string
                   18824:        cmpl    r6,$num01       # jump if multi-char string
                   18825:        bnequ   gtpt3
                   18826: #
                   18827: #      HERE FOR ONE CHARACTER STRING, SHARE ONE CHARACTER ANY
                   18828: #
                   18829:        movab   cfp$f(r9),r9    # point to character
                   18830:        movzbl  (r9),r6         # load character
                   18831:        movl    r6,r9           # set as parm1
                   18832:        movl    $p$ans,r7       # point to pcode for 1-char any
                   18833:        jmp     gtpt3           # jump to build node
                   18834: #
                   18835: #      HERE IF ARGUMENT IS NOT CONVERTIBLE TO STRING
                   18836: #
                   18837: gtpt2: movl    $p$exa,r7       # set pcode for expression in case
                   18838:        cmpl    (r9),$b$e$$     # jump to build node if expression
                   18839:        blequ   gtpt3
                   18840: #
                   18841: #      HERE WE HAVE AN ERROR (CONVERSION IMPOSSIBLE)
                   18842: #
                   18843:        movl    (sp)+,r11       # take convert error exit
                   18844:        jmp     *(r11)+
                   18845: #
                   18846: #      MERGE HERE TO BUILD NODE FOR STRING OR EXPRESSION
                   18847: #
                   18848: gtpt3: jsb     pbild           # call routine to build pattern node
                   18849: #
                   18850: #      COMMON EXIT AFTER SUCCESSFUL CONVERSION
                   18851: #
                   18852: gtpt4: movl    gtpsb,r7        # restore wb
                   18853: #
                   18854: #      MERGE HERE TO EXIT OF NO CONVERSION REQUIRED
                   18855: #
                   18856: gtpt5: addl2   $4*1,(sp)       # return to gtpat caller
                   18857:        rsb     
                   18858:        #enp                    # end procedure gtpat
                   18859:        #page   
                   18860: #
                   18861: #      GTREA -- GET REAL VALUE
                   18862: #
                   18863: #      GTREA IS PASSED AN OBJECT AND RETURNS A REAL VALUE
                   18864: #      PERFORMING ANY NECESSARY CONVERSIONS.
                   18865: #
                   18866: #      (XR)                  OBJECT TO BE CONVERTED
                   18867: #      JSR  GTREA            CALL TO CONVERT OBJECT TO REAL
                   18868: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18869: #      (XR)                  POINTER TO RESULTING REAL
                   18870: #      (WA,WB,WC,RA)         DESTROYED
                   18871: #      (XR)                  UNCHANGED (CONVERT ERROR ONLY)
                   18872: #
                   18873: gtrea: #prc                    # entry point
                   18874:        movl    (r9),r6         # get first word of block
                   18875:        cmpl    r6,$b$rcl       # jump if real
                   18876:        beqlu   gtre2
                   18877:        jsb     gtnum           # else convert argument to numeric
                   18878:        .long   gtre3           # jump if unconvertible
                   18879:        cmpl    r6,$b$rcl       # jump if real was returned
                   18880:        beqlu   gtre2
                   18881: #
                   18882: #      HERE FOR CASE OF AN INTEGER TO CONVERT TO REAL
                   18883: #
                   18884: gtre1: movl    4*icval(r9),r5  # load integer
                   18885:        cvtlf   r5,r2           # convert to real
                   18886:        jsb     rcbld           # build rcblk
                   18887: #
                   18888: #      EXIT WITH REAL
                   18889: #
                   18890: gtre2: addl2   $4*1,(sp)       # return to gtrea caller
                   18891:        rsb     
                   18892: #
                   18893: #      HERE ON CONVERSION ERROR
                   18894: #
                   18895: gtre3: movl    (sp)+,r11       # take convert error exit
                   18896:        jmp     *(r11)+
                   18897:        #enp                    # end procedure gtrea
                   18898:        #page   
                   18899: #
                   18900: #      GTSMI -- GET SMALL INTEGER
                   18901: #
                   18902: #      GTSMI IS PASSED A SNOBOL OBJECT AND RETURNS AN ADDRESS
                   18903: #      INTEGER IN THE RANGE (0 LE N LE DNAMB). SUCH A VALUE CAN
                   18904: #      ONLY BE DERIVED FROM AN INTEGER IN THE APPROPRIATE RANGE.
                   18905: #      SMALL INTEGERS NEVER APPEAR AS SNOBOL VALUES. HOWEVER,
                   18906: #      THEY ARE USED INTERNALLY FOR A VARIETY OF PURPOSES.
                   18907: #
                   18908: #      -(XS)                 ARGUMENT TO CONVERT (ON STACK)
                   18909: #      JSR  GTSMI            CALL TO CONVERT TO SMALL INTEGER
                   18910: #      PPM  LOC              TRANSFER LOC FOR NOT INTEGER
                   18911: #      PPM  LOC              TRANSFER LOC FOR LT 0, GT DNAMB
                   18912: #      (XR,WC)               RESULTING SMALL INT (TWO COPIES)
                   18913: #      (XS)                  POPPED
                   18914: #      (RA)                  DESTROYED
                   18915: #      (WA,WB)               DESTROYED (ON CONVERT ERROR ONLY)
                   18916: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   18917: #
                   18918:        .data   1
                   18919: gtsmi_s:       .long   0
                   18920:        .text   0
                   18921: gtsmi: movl    (sp)+,gtsmi_s   # entry point
                   18922:        movl    (sp)+,r9        # load argument
                   18923:        cmpl    (r9),$b$icl     # skip if already an integer
                   18924:        beqlu   gtsm1
                   18925: #
                   18926: #      HERE IF NOT AN INTEGER
                   18927: #
                   18928:        jsb     gtint           # convert argument to integer
                   18929:        .long   gtsm2           # jump if convert is impossible
                   18930: #
                   18931: #      MERGE HERE WITH INTEGER
                   18932: #
                   18933: gtsm1: movl    4*icval(r9),r5  # load integer value
                   18934:        movl    r5,r8           # move as one word, jump if ovflow
                   18935:        bgeq    0f
                   18936:        jmp     gtsm3
                   18937: 0:             
                   18938:        cmpl    r8,mxlen        # or if too small
                   18939:        bgtru   gtsm3
                   18940:        movl    r8,r9           # copy result to xr
                   18941:        addl3   $4*2,gtsmi_s,r11        # return to gtsmi caller
                   18942:        jmp     (r11)
                   18943: #
                   18944: #      HERE IF UNCONVERTIBLE TO INTEGER
                   18945: #
                   18946: gtsm2: movl    gtsmi_s,r11     # take non-integer error exit
                   18947:        jmp     *(r11)+
                   18948: #
                   18949: #      HERE IF OUT OF RANGE
                   18950: #
                   18951: gtsm3: addl3   $4*1,gtsmi_s,r11        # take out-of-range error exit
                   18952:        jmp     *(r11)+
                   18953:        #enp                    # end procedure gtsmi
                   18954:        #page   
                   18955: #
                   18956: #      GTSTG -- GET STRING
                   18957: #
                   18958: #      GTSTG IS PASSED AN OBJECT AND RETURNS A STRING WITH
                   18959: #      ANY NECESSARY CONVERSIONS PERFORMED.
                   18960: #
                   18961: #      -(XS)                 INPUT ARGUMENT (ON STACK)
                   18962: #      JSR  GTSTG            CALL TO CONVERT TO STRING
                   18963: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18964: #      (XR)                  POINTER TO RESULTING STRING
                   18965: #      (WA)                  LENGTH OF STRING IN CHARACTERS
                   18966: #      (XS)                  POPPED
                   18967: #      (RA)                  DESTROYED
                   18968: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   18969: #
                   18970:        .data   1
                   18971: gtstg_s:       .long   0
                   18972:        .text   0
                   18973: gtstg: movl    (sp)+,gtstg_s   # entry point
                   18974:        movl    (sp)+,r9        # load argument, pop stack
                   18975:        cmpl    (r9),$b$scl     # jump if already a string
                   18976:        bnequ   0f
                   18977:        jmp     gts30
                   18978: 0:             
                   18979: #
                   18980: #      HERE IF NOT A STRING ALREADY
                   18981: #
                   18982: gts01: movl    r9,-(sp)        # restack argument in case error
                   18983:        movl    r10,-(sp)       # save xl
                   18984:        movl    r7,gtsvb        # save wb
                   18985:        movl    r8,gtsvc        # save wc
                   18986:        movl    (r9),r6         # load first word of block
                   18987:        cmpl    r6,$b$icl       # jump to convert integer
                   18988:        beqlu   gts05
                   18989:        cmpl    r6,$b$rcl       # jump to convert real
                   18990:        bnequ   0f
                   18991:        jmp     gts10
                   18992: 0:             
                   18993:        cmpl    r6,$b$nml       # jump to convert name
                   18994:        beqlu   gts03
                   18995:        cmpl    r6,$b$bct       # jump to convert buffer
                   18996:        bnequ   0f
                   18997:        jmp     gts32
                   18998: 0:             
                   18999: #
                   19000: #      HERE ON CONVERSION ERROR
                   19001: #
                   19002: gts02: movl    (sp)+,r10       # restore xl
                   19003:        movl    (sp)+,r9        # reload input argument
                   19004:        movl    gtstg_s,r11     # take convert error exit
                   19005:        jmp     *(r11)+
                   19006:        #page   
                   19007: #
                   19008: #      GTSTG (CONTINUED)
                   19009: #
                   19010: #      HERE TO CONVERT A NAME (ONLY POSSIBLE IF NATURAL VAR)
                   19011: #
                   19012: gts03: movl    4*nmbas(r9),r10 # load name base
                   19013:        cmpl    r10,state       # error if not natural var (static)
                   19014:        bgequ   gts02
                   19015:        addl2   $4*vrsof,r10    # else point to possible string name
                   19016:        movl    4*sclen(r10),r6 # load length
                   19017:        tstl    r6              # jump if not system variable
                   19018:        bnequ   gts04
                   19019:        movl    4*vrsvo(r10),r10# else point to svblk
                   19020:        movl    4*svlen(r10),r6 # and load name length
                   19021: #
                   19022: #      MERGE HERE WITH STRING IN XR, LENGTH IN WA
                   19023: #
                   19024: gts04: clrl    r7              # set offset to zero
                   19025:        jsb     sbstr           # use sbstr to copy string
                   19026:        jmp     gts29           # jump to exit
                   19027: #
                   19028: #      COME HERE TO CONVERT AN INTEGER
                   19029: #
                   19030: gts05: movl    4*icval(r9),r5  # load integer value
                   19031:        movl    $num01,gtssf    # set sign flag negative
                   19032:        tstl    r5              # skip if integer is negative
                   19033:        blss    gts06
                   19034:        mnegl   r5,r5           # else negate integer
                   19035:        clrl    gtssf           # and reset negative flag
                   19036:        #page   
                   19037: #
                   19038: #      GTSTG (CONTINUED)
                   19039: #
                   19040: #      HERE WITH SIGN FLAG SET AND SIGN FORCED NEGATIVE AS
                   19041: #      REQUIRED BY THE CVD INSTRUCTION.
                   19042: #
                   19043: gts06: movl    gtswk,r9        # point to result work area
                   19044:        movl    $nstmx,r7       # initialize counter to max length
                   19045:        movab   cfp$f(r9)[r7],r9# prepare to store (right-left)
                   19046: #
                   19047: #      LOOP TO CONVERT DIGITS INTO WORK AREA
                   19048: #
                   19049: gts07: ashq    $-32,r4,r4      # convert one digit into wa
                   19050:        ediv    $10,r4,r5,r6
                   19051:        mnegl   r6,r6
                   19052:        bisb2   $0x30,r6
                   19053:        movb    r6,-(r9)        # store in work area
                   19054:        decl    r7              # decrement counter
                   19055:        tstl    r5              # loop if more digits to go
                   19056:        bneq    gts07
                   19057:        #csc    r9              # complete store characters
                   19058: #
                   19059: #      MERGE HERE AFTER CONVERTING INTEGER OR REAL INTO WORK
                   19060: #      AREA. WB IS SET TO NSTMX - (NUMBER OF CHARS IN RESULT).
                   19061: #
                   19062: gts08: movl    $nstmx,r6       # get max number of characters
                   19063:        subl2   r7,r6           # compute length of result
                   19064:        movl    r6,r10          # remember length for move later on
                   19065:        addl2   gtssf,r6        # add one for negative sign if needed
                   19066:        jsb     alocs           # allocate string for result
                   19067:        movl    r9,r8           # save result pointer for the moment
                   19068:        movab   cfp$f(r9),r9    # point to chars of result block
                   19069:        tstl    gtssf           # skip if positive
                   19070:        beqlu   gts09
                   19071:        movl    $ch$mn,r6       # else load negative sign
                   19072:        movb    r6,(r9)+        # and store it
                   19073:        #csc    r9              # complete store characters
                   19074: #
                   19075: #      HERE AFTER DEALING WITH SIGN
                   19076: #
                   19077: gts09: movl    r10,r6          # recall length to move
                   19078:        movl    gtswk,r10       # point to result work area
                   19079:        movab   cfp$f(r10)[r7],r10 # point to first result character
                   19080:        jsb     sbmvc           # move chars to result string
                   19081:        movl    r8,r9           # restore result pointer
                   19082:        jmp     gts29           # jump to exit
                   19083:        #page   
                   19084: #
                   19085: #      GTSTG (CONTINUED)
                   19086: #
                   19087: #      HERE TO CONVERT A REAL
                   19088: #
                   19089: gts10: movf    4*rcval(r9),r2  # load real
                   19090:        clrl    gtssf           # reset negative flag
                   19091:        tstf    r2              # skip if zero
                   19092:        bneq    0f
                   19093:        jmp     gts31
                   19094: 0:             
                   19095:        tstf    r2              # jump if real is positive
                   19096:        bgeq    gts11
                   19097:        movl    $num01,gtssf    # else set negative flag
                   19098:        mnegf   r2,r2           # and get absolute value of real
                   19099: #
                   19100: #      NOW SCALE THE REAL TO THE RANGE (0.1 LE X LT 1.0)
                   19101: #
                   19102: gts11: movl    intv0,r5        # initialize exponent to zero
                   19103: #
                   19104: #      LOOP TO SCALE UP IN STEPS OF 10**10
                   19105: #
                   19106: gts12: movf    r2,gtsrs        # save real value
                   19107:        subf2   reap1,r2        # subtract 0.1 to compare
                   19108:        tstf    r2              # jump if scale up not required
                   19109:        bgeq    gts13
                   19110:        movf    gtsrs,r2        # else reload value
                   19111:        mulf2   reatt,r2        # multiply by 10**10
                   19112:        subl2   intvt,r5        # decrement exponent by 10
                   19113:        jmp     gts12           # loop back to test again
                   19114: #
                   19115: #      TEST FOR SCALE DOWN REQUIRED
                   19116: #
                   19117: gts13: movf    gtsrs,r2        # reload value
                   19118:        subf2   reav1,r2        # subtract 1.0
                   19119:        tstf    r2              # jump if no scale down required
                   19120:        blss    gts17
                   19121:        movf    gtsrs,r2        # else reload value
                   19122: #
                   19123: #      LOOP TO SCALE DOWN IN STEPS OF 10**10
                   19124: #
                   19125: gts14: subf2   reatt,r2        # subtract 10**10 to compare
                   19126:        tstf    r2              # jump if large step not required
                   19127:        blss    gts15
                   19128:        movf    gtsrs,r2        # else restore value
                   19129:        divf2   reatt,r2        # divide by 10**10
                   19130:        movf    r2,gtsrs        # store new value
                   19131:        addl2   intvt,r5        # increment exponent by 10
                   19132:        jmp     gts14           # loop back
                   19133:        #page   
                   19134: #
                   19135: #      GTSTG (CONTINUED)
                   19136: #
                   19137: #      AT THIS POINT WE HAVE (1.0 LE X LT 10**10)
                   19138: #      COMPLETE SCALING WITH POWERS OF TEN TABLE
                   19139: #
                   19140: gts15: movl    $reav1,r9       # point to powers of ten table
                   19141: #
                   19142: #      LOOP TO LOCATE CORRECT ENTRY IN TABLE
                   19143: #
                   19144: gts16: movf    gtsrs,r2        # reload value
                   19145:        addl2   intv1,r5        # increment exponent
                   19146:        addl2   $4*cfp$r,r9     # point to next entry in table
                   19147:        subf2   (r9),r2         # subtract it to compare
                   19148:        tstf    r2              # loop till we find a larger entry
                   19149:        bgeq    gts16
                   19150:        movf    gtsrs,r2        # then reload the value
                   19151:        divf2   (r9),r2         # and complete scaling
                   19152:        movf    r2,gtsrs        # store value
                   19153: #
                   19154: #      WE ARE NOW SCALED, SO ROUND BY ADDING 0.5 * 10**(-CFP$S)
                   19155: #
                   19156: gts17: movf    gtsrs,r2        # get value again
                   19157:        addf2   gtsrn,r2        # add rounding factor
                   19158:        movf    r2,gtsrs        # store result
                   19159: #
                   19160: #      THE ROUNDING OPERATION MAY HAVE PUSHED US UP PAST
                   19161: #      1.0 AGAIN, SO CHECK ONE MORE TIME.
                   19162: #
                   19163:        subf2   reav1,r2        # subtract 1.0 to compare
                   19164:        tstf    r2              # skip if ok
                   19165:        blss    gts18
                   19166:        addl2   intv1,r5        # else increment exponent
                   19167:        movf    gtsrs,r2        # reload value
                   19168:        divf2   reavt,r2        # divide by 10.0 to rescale
                   19169:        jmp     gts19           # jump to merge
                   19170: #
                   19171: #      HERE IF ROUNDING DID NOT MUCK UP SCALING
                   19172: #
                   19173: gts18: movf    gtsrs,r2        # reload rounded value
                   19174:        #page   
                   19175: #
                   19176: #      GTSTG (CONTINUED)
                   19177: #
                   19178: #      NOW WE HAVE COMPLETED THE SCALING AS FOLLOWS
                   19179: #
                   19180: #      (IA)                  SIGNED EXPONENT
                   19181: #      (RA)                  SCALED REAL (ABSOLUTE VALUE)
                   19182: #
                   19183: #      IF THE EXPONENT IS NEGATIVE OR GREATER THAN CFP$S, THEN
                   19184: #      WE CONVERT THE NUMBER IN THE FORM.
                   19185: #
                   19186: #      (NEG SIGN) 0 . (CPF$S DIGITS) E (EXP SIGN) (EXP DIGITS)
                   19187: #
                   19188: #      IF THE EXPONENT IS POSITIVE AND LESS THAN OR EQUAL TO
                   19189: #      CFP$S, THE NUMBER IS CONVERTED IN THE FORM.
                   19190: #
                   19191: #      (NEG SIGN) (EXPONENT DIGITS) . (CFP$S-EXPONENT DIGITS)
                   19192: #
                   19193: #      IN BOTH CASES, THE FORMATS OBTAINED FROM THE ABOVE
                   19194: #      RULES ARE MODIFIED BY DELETING TRAILING ZEROS AFTER THE
                   19195: #      DECIMAL POINT. THERE ARE NO LEADING ZEROS IN THE EXPONENT
                   19196: #      AND THE EXPONENT SIGN IS ALWAYS PRESENT.
                   19197: #
                   19198: gts19: movl    $cfp$s,r10      # set num dec digits = cfp$s
                   19199:        movl    $ch$mn,gtses    # set exponent sign negative
                   19200:        tstl    r5              # all set if exponent is negative
                   19201:        blss    gts21
                   19202:        movl    r5,r6           # else fetch exponent
                   19203:        cmpl    r6,$cfp$s       # skip if we can use special format
                   19204:        blequ   gts20
                   19205:        movl    r6,r5           # else restore exponent
                   19206:        mnegl   r5,r5           # set negative for cvd
                   19207:        movl    $ch$pl,gtses    # set plus sign for exponent sign
                   19208:        jmp     gts21           # jump to generate exponent
                   19209: #
                   19210: #      HERE IF WE CAN USE THE FORMAT WITHOUT AN EXPONENT
                   19211: #
                   19212: gts20: subl2   r6,r10          # compute digits after decimal point
                   19213:        movl    intv0,r5        # reset exponent to zero
                   19214:        #page   
                   19215: #
                   19216: #      GTSTG (CONTINUED)
                   19217: #
                   19218: #      MERGE HERE AS FOLLOWS
                   19219: #
                   19220: #      (IA)                  EXPONENT ABSOLUTE VALUE
                   19221: #      GTSES                 CHARACTER FOR EXPONENT SIGN
                   19222: #      (RA)                  POSITIVE FRACTION
                   19223: #      (XL)                  NUMBER OF DIGITS AFTER DEC POINT
                   19224: #
                   19225: gts21: movl    gtswk,r9        # point to work area
                   19226:        movl    $nstmx,r7       # set character ctr to max length
                   19227:        movab   cfp$f(r9)[r7],r9# prepare to store (right to left)
                   19228:        tstl    r5              # skip exponent if it is zero
                   19229:        beql    gts23
                   19230: #
                   19231: #      LOOP TO GENERATE DIGITS OF EXPONENT
                   19232: #
                   19233: gts22: ashq    $-32,r4,r4      # convert a digit into wa
                   19234:        ediv    $10,r4,r5,r6
                   19235:        mnegl   r6,r6
                   19236:        bisb2   $0x30,r6
                   19237:        movb    r6,-(r9)        # store in work area
                   19238:        decl    r7              # decrement counter
                   19239:        tstl    r5              # loop back if more digits to go
                   19240:        bneq    gts22
                   19241: #
                   19242: #      HERE GENERATE EXPONENT SIGN AND E
                   19243: #
                   19244:        movl    gtses,r6        # load exponent sign
                   19245:        movb    r6,-(r9)        # store in work area
                   19246:        movl    $ch$le,r6       # get character letter e
                   19247:        movb    r6,-(r9)        # store in work area
                   19248:        subl2   $num02,r7       # decrement counter for sign and e
                   19249: #
                   19250: #      HERE TO GENERATE THE FRACTION
                   19251: #
                   19252: gts23: mulf2   gtssc,r2        # convert real to integer (10**cfp$s)
                   19253:        cvtfl   r2,r5           # get integer (overflow impossible)
                   19254:        mnegl   r5,r5           # negate as required by cvd
                   19255: #
                   19256: #      LOOP TO SUPPRESS TRAILING ZEROS
                   19257: #
                   19258: gts24: tstl    r10             # jump if no digits left to do
                   19259:        beqlu   gts27
                   19260:        ashq    $-32,r4,r4      # else convert one digit
                   19261:        ediv    $10,r4,r5,r6
                   19262:        mnegl   r6,r6
                   19263:        bisb2   $0x30,r6
                   19264:        cmpl    r6,$ch$d0       # jump if not a zero
                   19265:        bnequ   gts26
                   19266:        decl    r10             # decrement counter
                   19267:        jmp     gts24           # loop back for next digit
                   19268:        #page   
                   19269: #
                   19270: #      GTSTG (CONTINUED)
                   19271: #
                   19272: #      LOOP TO GENERATE DIGITS AFTER DECIMAL POINT
                   19273: #
                   19274: gts25: ashq    $-32,r4,r4      # convert a digit into wa
                   19275:        ediv    $10,r4,r5,r6
                   19276:        mnegl   r6,r6
                   19277:        bisb2   $0x30,r6
                   19278: #
                   19279: #      MERGE HERE FIRST TIME
                   19280: #
                   19281: gts26: movb    r6,-(r9)        # store digit
                   19282:        decl    r7              # decrement counter
                   19283:        decl    r10             # decrement counter
                   19284:        tstl    r10             # loop back if more to go
                   19285:        bnequ   gts25
                   19286: #
                   19287: #      HERE GENERATE THE DECIMAL POINT
                   19288: #
                   19289: gts27: movl    $ch$dt,r6       # load decimal point
                   19290:        movb    r6,-(r9)        # store in work area
                   19291:        decl    r7              # decrement counter
                   19292: #
                   19293: #      HERE GENERATE THE DIGITS BEFORE THE DECIMAL POINT
                   19294: #
                   19295: gts28: ashq    $-32,r4,r4      # convert a digit into wa
                   19296:        ediv    $10,r4,r5,r6
                   19297:        mnegl   r6,r6
                   19298:        bisb2   $0x30,r6
                   19299:        movb    r6,-(r9)        # store in work area
                   19300:        decl    r7              # decrement counter
                   19301:        tstl    r5              # loop back if more to go
                   19302:        bneq    gts28
                   19303:        #csc    r9              # complete store characters
                   19304:        jmp     gts08           # else jump back to exit
                   19305: #
                   19306: #      EXIT POINT AFTER SUCCESSFUL CONVERSION
                   19307: #
                   19308: gts29: movl    (sp)+,r10       # restore xl
                   19309:        addl2   $4,sp           # pop argument
                   19310:        movl    gtsvb,r7        # restore wb
                   19311:        movl    gtsvc,r8        # restore wc
                   19312: #
                   19313: #      MERGE HERE IF NO CONVERSION REQUIRED
                   19314: #
                   19315: gts30: movl    4*sclen(r9),r6  # load string length
                   19316:        addl3   $4*1,gtstg_s,r11        # return to caller
                   19317:        jmp     (r11)
                   19318: #
                   19319: #      HERE TO RETURN STRING FOR REAL ZERO
                   19320: #
                   19321: gts31: movl    $scre0,r10      # point to string
                   19322:        movl    $num02,r6       # 2 chars
                   19323:        clrl    r7              # zero offset
                   19324:        jsb     sbstr           # copy string
                   19325:        jmp     gts29           # return
                   19326:        #page   
                   19327: #
                   19328: #      HERE TO CONVERT A BUFFER BLOCK
                   19329: #
                   19330: gts32: movl    r9,r10          # copy arg ptr
                   19331:        movl    4*bclen(r10),r6 # get size to allocate
                   19332:        tstl    r6              # if null then return null
                   19333:        beqlu   gts33
                   19334:        jsb     alocs           # allocate string frame
                   19335:        movl    r9,r7           # save string ptr
                   19336:        movl    4*sclen(r9),r6  # get length to move
                   19337:        movab   3+(4*0)(r6),r6  # get as multiple of word size
                   19338:        bicl2   $3,r6
                   19339:        movl    4*bcbuf(r10),r10# point to bfblk
                   19340:        addl2   $4*scsi$,r9     # point to start of character area
                   19341:        addl2   $4*bfsi$,r10    # point to start of buffer chars
                   19342:        jsb     sbmvw           # copy words
                   19343:        movl    r7,r9           # restore scblk ptr
                   19344:        jmp     gts29           # exit with scblk
                   19345: #
                   19346: #      HERE WHEN NULL BUFFER IS BEING CONVERTED
                   19347: #
                   19348: gts33: movl    $nulls,r9       # point to null
                   19349:        jmp     gts29           # exit with null
                   19350:        #enp                    # end procedure gtstg
                   19351:        #page   
                   19352: #
                   19353: #      GTVAR -- GET VARIABLE FOR I/O/TRACE ASSOCIATION
                   19354: #
                   19355: #      GTVAR IS USED TO POINT TO AN ACTUAL VARIABLE LOCATION
                   19356: #      FOR THE DETACH,INPUT,OUTPUT,TRACE,STOPTR SYSTEM FUNCTIONS
                   19357: #
                   19358: #      (XR)                  ARGUMENT TO FUNCTION
                   19359: #      JSR  GTVAR            CALL TO LOCATE VARIABLE POINTER
                   19360: #      PPM  LOC              TRANSFER LOC IF NOT OK VARIABLE
                   19361: #      (XL,WA)               NAME BASE,OFFSET OF VARIABLE
                   19362: #      (XR,RA)               DESTROYED
                   19363: #      (WB,WC)               DESTROYED (CONVERT ERROR ONLY)
                   19364: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   19365: #
                   19366: gtvar: #prc                    # entry point
                   19367:        cmpl    (r9),$b$nml     # jump if not a name
                   19368:        bnequ   gtvr2
                   19369:        movl    4*nmofs(r9),r6  # else load name offset
                   19370:        movl    4*nmbas(r9),r10 # load name base
                   19371:        cmpl    (r10),$b$evt    # error if expression variable
                   19372:        beqlu   gtvr1
                   19373:        cmpl    (r10),$b$kvt    # all ok if not keyword variable
                   19374:        bnequ   gtvr3
                   19375: #
                   19376: #      HERE ON CONVERSION ERROR
                   19377: #
                   19378: gtvr1: movl    (sp)+,r11       # take convert error exit
                   19379:        jmp     *(r11)+
                   19380: #
                   19381: #      HERE IF NOT A NAME, TRY CONVERT TO NATURAL VARIABLE
                   19382: #
                   19383: gtvr2: movl    r8,gtvrc        # save wc
                   19384:        jsb     gtnvr           # locate vrblk if possible
                   19385:        .long   gtvr1           # jump if convert error
                   19386:        movl    r9,r10          # else copy vrblk name base
                   19387:        movl    $4*vrval,r6     # and set offset
                   19388:        movl    gtvrc,r8        # restore wc
                   19389: #
                   19390: #      HERE FOR NAME OBTAINED
                   19391: #
                   19392: gtvr3: cmpl    r10,state       # all ok if not natural variable
                   19393:        bgequ   gtvr4
                   19394:        cmpl    4*vrsto(r10),$b$vre # error if protected variable
                   19395:        beqlu   gtvr1
                   19396: #
                   19397: #      COMMON EXIT POINT
                   19398: #
                   19399: gtvr4: addl2   $4*1,(sp)       # return to caller
                   19400:        rsb     
                   19401:        #enp                    # end procedure gtvar
                   19402:        #page   
                   19403: #
                   19404: #      HASHS -- COMPUTE HASH INDEX FOR STRING
                   19405: #
                   19406: #      HASHS IS USED TO CONVERT A STRING TO A UNIQUE INTEGER
                   19407: #      VALUE. THE RESULTING HASH VALUE IS A POSITIVE INTEGER
                   19408: #      IN THE RANGE 0 TO CFP$M
                   19409: #
                   19410: #      (XR)                  STRING TO BE HASHED
                   19411: #      JSR  HASHS            CALL TO HASH STRING
                   19412: #      (IA)                  HASH VALUE
                   19413: #      (XR,WB,WC)            DESTROYED
                   19414: #
                   19415: #      THE HASH FUNCTION USED IS AS FOLLOWS.
                   19416: #
                   19417: #      START WITH THE LENGTH OF THE STRING (SGD07)
                   19418: #
                   19419: #      TAKE THE FIRST E$HNW WORDS OF THE CHARACTERS FROM
                   19420: #      THE STRING OR ALL THE WORDS IF FEWER THAN E$HNW.
                   19421: #
                   19422: #      COMPUTE THE EXCLUSIVE OR OF ALL THESE WORDS TREATING
                   19423: #      THEM AS ONE WORD BIT STRING VALUES.
                   19424: #
                   19425: #      MOVE THE RESULT AS AN INTEGER WITH THE MTI INSTRUCTION.
                   19426: #
                   19427: hashs: #prc                    # entry point
                   19428:        movl    4*sclen(r9),r8  # load string length in characters
                   19429:        movl    r8,r7           # initialize with length
                   19430:        tstl    r8              # jump if null string
                   19431:        beqlu   hshs3
                   19432:        movab   3+(4*0)(r8),r8  # else get number of words of chars
                   19433:        ashl    $-2,r8,r8
                   19434:        addl2   $4*schar,r9     # point to characters of string
                   19435:        cmpl    r8,$e$hnw       # use whole string if short
                   19436:        blequ   hshs1
                   19437:        movl    $e$hnw,r8       # else set to involve first e$hnw wds
                   19438: #
                   19439: #      HERE WITH COUNT OF WORDS TO CHECK IN WC
                   19440: #
                   19441: hshs1:                         # set counter to control loop
                   19442: #
                   19443: #      LOOP TO COMPUTE EXCLUSIVE OR
                   19444: #
                   19445: hshs2: xorl2   (r9)+,r7        # exclusive or next word of chars
                   19446:        sobgtr  r8,hshs2        # loop till all processed
                   19447: #
                   19448: #      MERGE HERE WITH EXCLUSIVE OR IN WB
                   19449: #
                   19450: hshs3: #zgb    r7              # zeroise undefined bits
                   19451:        mcoml   bitsm,r11       # ensure in range 0 to cfp$m
                   19452:        bicl2   r11,r7
                   19453:        movl    r7,r5           # move result as integer
                   19454:        clrl    r9              # clear garbage value in xr
                   19455:        rsb                     # return to hashs caller
                   19456:        #enp                    # end procedure hashs
                   19457:        #page   
                   19458: #
                   19459: #      ICBLD -- BUILD INTEGER BLOCK
                   19460: #
                   19461: #      (IA)                  INTEGER VALUE FOR ICBLK
                   19462: #      JSR  ICBLD            CALL TO BUILD INTEGER BLOCK
                   19463: #      (XR)                  POINTER TO RESULT ICBLK
                   19464: #      (WA)                  DESTROYED
                   19465: #
                   19466: icbld: #prc                    # entry point
                   19467:        movl    r5,r9           # copy small integers
                   19468:        bgeq    0f
                   19469:        jmp     icbl1
                   19470: 0:             
                   19471:        cmpl    r9,$num02       # jump if 0,1 or 2
                   19472:        blequ   icbl3
                   19473: #
                   19474: #      CONSTRUCT ICBLK
                   19475: #
                   19476: icbl1: movl    dnamp,r9        # load pointer to next available loc
                   19477:        addl2   $4*icsi$,r9     # point past new icblk
                   19478:        cmpl    r9,dname        # jump if there is room
                   19479:        blequ   icbl2
                   19480:        movl    $4*icsi$,r6     # else load length of icblk
                   19481:        jsb     alloc           # use standard allocator to get block
                   19482:        addl2   r6,r9           # point past block to merge
                   19483: #
                   19484: #      MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED
                   19485: #
                   19486: icbl2: movl    r9,dnamp        # set new pointer
                   19487:        subl2   $4*icsi$,r9     # point back to start of block
                   19488:        movl    $b$icl,(r9)     # store type word
                   19489:        movl    r5,4*icval(r9)  # store integer value in icblk
                   19490:        rsb                     # return to icbld caller
                   19491: #
                   19492: #      OPTIMISE BY NOT BUILDING ICBLKS FOR SMALL INTEGERS
                   19493: #
                   19494: icbl3: moval   0[r9],r9        # convert integer to offset
                   19495:        movl    l^intab(r9),r9  # point to pre-built icblk
                   19496:        rsb                     # return
                   19497:        #enp                    # end procedure icbld
                   19498:        #page   
                   19499: #
                   19500: #      IDENT -- COMPARE TWO VALUES
                   19501: #
                   19502: #      IDENT COMPARES TWO VALUES IN THE SENSE OF THE IDENT
                   19503: #      DIFFER FUNCTIONS AVAILABLE AT THE SNOBOL LEVEL.
                   19504: #
                   19505: #      (XR)                  FIRST ARGUMENT
                   19506: #      (XL)                  SECOND ARGUMENT
                   19507: #      JSR  IDENT            CALL TO COMPARE ARGUMENTS
                   19508: #      PPM  LOC              TRANSFER LOC IF IDENT
                   19509: #      (NORMAL RETURN IF DIFFER)
                   19510: #      (XR,XL,WC,RA)         DESTROYED
                   19511: #
                   19512: ident: #prc                    # entry point
                   19513:        cmpl    r9,r10          # jump if same pointer (ident)
                   19514:        bnequ   0f
                   19515:        jmp     iden7
                   19516: 0:             
                   19517:        movl    (r9),r8         # else load arg 1 type word
                   19518:        cmpl    r8,(r10)        # differ if arg 2 type word differ
                   19519:        bnequ   iden1
                   19520:        cmpl    r8,$b$scl       # jump if strings
                   19521:        beqlu   iden2
                   19522:        cmpl    r8,$b$icl       # jump if integers
                   19523:        beqlu   iden4
                   19524:        cmpl    r8,$b$rcl       # jump if reals
                   19525:        beqlu   iden5
                   19526:        cmpl    r8,$b$nml       # jump if names
                   19527:        beqlu   iden6
                   19528: #
                   19529: #      FOR ALL OTHER DATATYPES, MUST BE DIFFER IF XR NE XL
                   19530: #
                   19531: #      MERGE HERE FOR DIFFER
                   19532: #
                   19533: iden1: addl2   $4*1,(sp)       # take differ exit
                   19534:        rsb     
                   19535: #
                   19536: #      HERE FOR STRINGS, IDENT ONLY IF LENGTHS AND CHARS SAME
                   19537: #
                   19538: iden2: movl    4*sclen(r9),r8  # load arg 1 length
                   19539:        cmpl    r8,4*sclen(r10) # differ if lengths differ
                   19540:        bnequ   iden1
                   19541:        movab   3+(4*0)(r8),r8  # get number of words in strings
                   19542:        ashl    $-2,r8,r8
                   19543:        addl2   $4*schar,r9     # point to chars of arg 1
                   19544:        addl2   $4*schar,r10    # point to chars of arg 2
                   19545:                                # set loop counter
                   19546: #
                   19547: #      LOOP TO COMPARE CHARACTERS. NOTE THAT WA CANNOT BE ZERO
                   19548: #      SINCE ALL NULL STRINGS POINT TO NULLS AND GIVE XL=XR.
                   19549: #
                   19550: iden3: cmpl    (r9),(r10)      # differ if chars do not match
                   19551:        bnequ   iden8
                   19552:        addl2   $4,r9           # else bump arg one pointer
                   19553:        addl2   $4,r10          # bump arg two pointer
                   19554:        sobgtr  r8,iden3        # loop back till all checked
                   19555:        #page   
                   19556: #
                   19557: #      IDENT (CONTINUED)
                   19558: #
                   19559: #      HERE TO EXIT FOR CASE OF TWO IDENT STRINGS
                   19560: #
                   19561:        clrl    r10             # clear garbage value in xl
                   19562:        clrl    r9              # clear garbage value in xr
                   19563:        movl    (sp)+,r11       # take ident exit
                   19564:        jmp     *(r11)+
                   19565: #
                   19566: #      HERE FOR INTEGERS, IDENT IF SAME VALUES
                   19567: #
                   19568: iden4: movl    4*icval(r9),r5  # load arg 1
                   19569:        subl2   4*icval(r10),r5 # subtract arg 2 to compare
                   19570:        bvs     iden1
                   19571:        tstl    r5              # differ if result is not zero
                   19572:        bneq    iden1
                   19573:        movl    (sp)+,r11       # take ident exit
                   19574:        jmp     *(r11)+
                   19575: #
                   19576: #      HERE FOR REALS, IDENT IF SAME VALUES
                   19577: #
                   19578: iden5: movf    4*rcval(r9),r2  # load arg 1
                   19579:        subf2   4*rcval(r10),r2 # subtract arg 2 to compare
                   19580:        bvs     iden1
                   19581:        tstf    r2              # differ if result is not zero
                   19582:        bneq    iden1
                   19583:        movl    (sp)+,r11       # take ident exit
                   19584:        jmp     *(r11)+
                   19585: #
                   19586: #      HERE FOR NAMES, IDENT IF BASES AND OFFSETS SAME
                   19587: #
                   19588: iden6: cmpl    4*nmofs(r9),4*nmofs(r10) # differ if different offset
                   19589:        bnequ   iden1
                   19590:        cmpl    4*nmbas(r9),4*nmbas(r10) # differ if different base
                   19591:        bnequ   iden1
                   19592: #
                   19593: #      MERGE HERE TO SIGNAL IDENT FOR IDENTICAL POINTERS
                   19594: #
                   19595: iden7: movl    (sp)+,r11       # take ident exit
                   19596:        jmp     *(r11)+
                   19597: #
                   19598: #      HERE FOR DIFFER STRINGS
                   19599: #
                   19600: iden8: clrl    r9              # clear garbage ptr in xr
                   19601:        clrl    r10             # clear garbage ptr in xl
                   19602:        addl2   $4*1,(sp)       # return to caller (differ)
                   19603:        rsb     
                   19604:        #enp                    # end procedure ident
                   19605:        #page   
                   19606: #
                   19607: #      INOUT - USED TO INITIALISE INPUT AND OUTPUT VARIABLES
                   19608: #
                   19609: #      (XL)                  POINTER TO VBL NAME STRING
                   19610: #      (WB)                  TRBLK TYPE
                   19611: #      JSR  INOUT            CALL TO PERFORM INITIALISATION
                   19612: #      (XL)                  VRBLK PTR
                   19613: #      (XR)                  TRBLK PTR
                   19614: #      (WA,WC)               DESTROYED
                   19615: #
                   19616: #      NOTE THAT TRTER (= TRTRF) FIELD OF STANDARD I/O VARIABLES
                   19617: #      POINTS TO CORRESPONDING SVBLK NOT TO A TRBLK AS IS THE
                   19618: #      CASE FOR ORDINARY VARIABLES.
                   19619: #
                   19620: inout: #prc                    # entry point
                   19621:        movl    r7,-(sp)        # stack trblk type
                   19622:        movl    4*sclen(r10),r6 # get name length
                   19623:        clrl    r7              # point to start of name
                   19624:        jsb     sbstr           # build a proper scblk
                   19625:        jsb     gtnvr           # build vrblk
                   19626:        .long   invalid$        # no error return
                   19627:        movl    r9,r8           # save vrblk pointer
                   19628:        movl    (sp)+,r7        # get trter field
                   19629:        clrl    r10             # zero trfpt
                   19630:        jsb     trbld           # build trblk
                   19631:        movl    r8,r10          # recall vrblk pointer
                   19632:        movl    4*vrsvp(r10),4*trter(r9) # store svblk pointer
                   19633:        movl    r9,4*vrval(r10) # store trblk ptr in vrblk
                   19634:        movl    $b$vra,4*vrget(r10) # set trapped access
                   19635:        movl    $b$vrv,4*vrsto(r10) # set trapped store
                   19636:        rsb                     # return to caller
                   19637:        #enp                    # end procedure inout
                   19638:        #page   
                   19639: #
                   19640: #      INSBF -- INSERT STRING IN BUFFER
                   19641: #
                   19642: #      THIS ROUTINE WILL REPLACE A SECTION OF A BUFFER WITH THE
                   19643: #      CONTENTS OF A GIVEN STRING.  IF THE LENGTH OF THE
                   19644: #      SECTION TO BE REPLACED IS DIFFERENT THAN THE LENGTH OF
                   19645: #      THE GIVEN STRING, AND THE REPLACEMENT IS NOT AN APPEND,
                   19646: #      THEN THE UPPER SECTION OF THE BUFFER IS SHIFTED UP OR
                   19647: #      DOWN TO CREATE THE PROPER SPACE FOR THE INSERT.
                   19648: #
                   19649: #      (XR)                  POINTER TO BFBLK
                   19650: #      (XL)                  OBJECT WHICH IS STRING CONVERTABLE
                   19651: #      (WA)                  OFFSET OF START OF INSERT IN (XR)
                   19652: #      (WB)                  LENGTH OF SECTION IN (XR) REPLACED
                   19653: #      JSR  INSBF            CALL TO INSERT CHARACTERS IN BUFFER
                   19654: #      PPM  LOC              THREAD IF (XR) NOT CONVERTABLE
                   19655: #      PPM  LOC              THREAD IF INSERT NOT POSSIBLE
                   19656: #
                   19657: #      THE SECOND ALTERNATE EXIT IS TAKEN IF THE INSERT WOULD
                   19658: #      OVERFLOW THE BUFFER, OR IF THE INSERT IS OUT PAST THE
                   19659: #      DEFINED END OF THE BUFFER AS GIVEN.
                   19660: #
                   19661: insbf: #prc                    # entry point
                   19662:        movl    r6,inssa        # save entry wa
                   19663:        movl    r7,inssb        # save entry wb
                   19664:        movl    r8,inssc        # save entry wc
                   19665:        addl2   r7,r6           # add to get offset past replace part
                   19666:        movl    r6,insab        # save wa+wb
                   19667:        movl    4*bclen(r9),r8  # get current defined length
                   19668:        cmpl    inssa,r8        # fail if start offset too big
                   19669:        blequ   0f
                   19670:        jmp     ins07
                   19671: 0:             
                   19672:        cmpl    r6,r8           # fail if final offset too big
                   19673:        blequ   0f
                   19674:        jmp     ins07
                   19675: 0:             
                   19676:        movl    r10,-(sp)       # save entry xl
                   19677:        movl    r9,-(sp)        # save bcblk ptr
                   19678:        movl    r10,-(sp)       # stack again for gtstg
                   19679:        jsb     gtstg           # call to convert to string
                   19680:        .long   ins05           # take string convert err exit
                   19681:        movl    r9,r10          # save string ptr
                   19682:        movl    (sp),r9         # restore bcblk ptr
                   19683:        addl2   r8,r6           # add buffer len to string len
                   19684:        subl2   inssb,r6        # bias out component being replaced
                   19685:        movl    4*bcbuf(r9),r9  # point to bfblk
                   19686:        cmpl    r6,4*bfalc(r9)  # fail if result exceeds allocation
                   19687:        blequ   0f
                   19688:        jmp     ins06
                   19689: 0:             
                   19690:        movl    (sp),r9         # restore bcblk ptr
                   19691:        movl    r8,r6           # get buffer length
                   19692:        subl2   insab,r6        # subtract to get shift length
                   19693:        addl2   4*sclen(r10),r8 # add length of new
                   19694:        subl2   inssb,r8        # subtract old to get total new len
                   19695:        movl    4*bclen(r9),r7  # get old bclen
                   19696:        movl    r8,4*bclen(r9)  # stuff new length
                   19697:        tstl    r6              # skip shift if nothing to do
                   19698:        bnequ   0f
                   19699:        jmp     ins04
                   19700: 0:             
                   19701:        cmpl    inssb,4*sclen(r10) # skip shift if lengths match
                   19702:        bnequ   0f
                   19703:        jmp     ins04
                   19704: 0:             
                   19705:        movl    4*bcbuf(r9),r9  # point to bfblk
                   19706:        movl    r10,-(sp)       # save scblk ptr
                   19707:        cmpl    inssb,4*sclen(r10) # brn if shft is for more room
                   19708:        blequ   ins01
                   19709:        #page   
                   19710: #
                   19711: #      INSBF (CONTINUED)
                   19712: #
                   19713: #      WE ARE SHIFTING THE UPPER SEGMENT DOWN TO COMPACT
                   19714: #      THE BUFFER.  (THE STRING LENGTH IS SMALLER THAN THE
                   19715: #      SEGMENT BEING REPLACED.)  REGISTERS ARE SET AS:
                   19716: #
                   19717: #      (WA)                  MOVE (SHIFT DOWN) LENGTH
                   19718: #      (WB)                  OLD BCLEN
                   19719: #      (WC)                  NEW BCLEN
                   19720: #      (XR)                  BFBLK PTR
                   19721: #      (XL),(XS)             SCBLK PTR
                   19722: #
                   19723:        movl    inssa,r7        # get offset to insert
                   19724:        addl2   4*sclen(r10),r7 # add insert length to get dest off
                   19725:        movl    r9,r10          # make copy
                   19726:        movl    insab,r11       # [get in scratch register]
                   19727:        movab   cfp$f(r10)[r11],r10 # prepare source for move
                   19728:        movab   cfp$f(r9)[r7],r9# prepare destination reg for move
                   19729:        jsb     sbmvc           # move em out
                   19730:        jmp     ins02           # branch to pad
                   19731: #
                   19732: #      WE ARE SHIFTING THE UPPER SEGMENT UP TO EXPAND
                   19733: #      THE BUFFER.  (THE STRING LENGTH IS LARGER THAN THE
                   19734: #      SEGMENT BEING REPLACED.)
                   19735: #
                   19736: ins01: movl    r9,r10          # copy bfblk ptr
                   19737:        movab   cfp$f(r10)[r7],r10 # set source reg for move backwards
                   19738:        movab   cfp$f(r9)[r8],r9# set destination ptr for move
                   19739:        jsb     sbmcb           # move backwards (possible overlap)
                   19740: #
                   19741: #      MERGE HERE AFTER MOVE TO ADJUST PADDING AT NEW BUFFER END
                   19742: #
                   19743: ins02: movl    (sp)+,r10       # restore scblk ptr
                   19744:        movl    r8,r6           # copy new buffer end
                   19745:        movab   3+(4*0)(r6),r6  # round out
                   19746:        bicl2   $3,r6
                   19747:        subl2   r8,r6           # subtract to get remainder
                   19748:        tstl    r6              # no pad if already even boundary
                   19749:        bnequ   0f
                   19750:        jmp     ins04
                   19751: 0:             
                   19752:        movl    (sp),r9         # get bcblk ptr
                   19753:        movl    4*bcbuf(r9),r9  # get bfblk ptr
                   19754:        movab   cfp$f(r9)[r8],r9# prepare to pad
                   19755:        clrl    r7              # clear wb
                   19756:                                # load loop count
                   19757: #
                   19758: #      LOOP HERE TO STUFF PAD CHARACTERS
                   19759: #
                   19760: ins03: movb    r7,(r9)+        # stuff zero pad
                   19761:        sobgtr  r6,ins03        # branch for more
                   19762:        #page   
                   19763: #
                   19764: #      INSBF (CONTINUED)
                   19765: #
                   19766: #      MERGE HERE WHEN PADDING OK.  NOW COPY IN THE INSERT
                   19767: #      STRING TO THE HOLE.
                   19768: #
                   19769: ins04: movl    (sp),r9         # get bcblk ptr
                   19770:        movl    4*bcbuf(r9),r9  # get bfblk ptr
                   19771:        movl    4*sclen(r10),r6 # get move length
                   19772:        movab   cfp$f(r10),r10  # prepare to copy from first char
                   19773:        movl    inssa,r11       # [get in scratch register]
                   19774:        movab   cfp$f(r9)[r11],r9# prepare to store in hole
                   19775:        jsb     sbmvc           # copy the characters
                   19776:        movl    (sp)+,r9        # restore entry xr
                   19777:        movl    (sp)+,r10       # restore entry xl
                   19778:        movl    inssa,r6        # restore entry wa
                   19779:        movl    inssb,r7        # restore entry wb
                   19780:        movl    inssc,r8        # restore entry wc
                   19781:        addl2   $4*2,(sp)       # return to caller
                   19782:        rsb     
                   19783: #
                   19784: #      HERE TO TAKE STRING CONVERT ERROR EXIT
                   19785: #
                   19786: ins05: movl    (sp)+,r9        # restore entry xr
                   19787:        movl    (sp)+,r10       # restore entry xl
                   19788:        movl    inssa,r6        # restore entry wa
                   19789:        movl    inssb,r7        # restore entry wb
                   19790:        movl    inssc,r8        # restore entry wc
                   19791:        movl    (sp)+,r11       # alternate exit
                   19792:        jmp     *(r11)+
                   19793: #
                   19794: #      HERE FOR INVALID OFFSET OR LENGTH
                   19795: #
                   19796: ins06: movl    (sp)+,r9        # restore entry xr
                   19797:        movl    (sp)+,r10       # restore entry xl
                   19798: #
                   19799: #      MERGE FOR LENGTH FAILURE EXIT WITH STACK SET
                   19800: #
                   19801: ins07: movl    inssa,r6        # restore entry wa
                   19802:        movl    inssb,r7        # restore entry wb
                   19803:        movl    inssc,r8        # restore entry wc
                   19804:        addl3   $4*1,(sp)+,r11  # alternate exit
                   19805:        jmp     *(r11)+
                   19806:        #enp                    # end procedure insbf
                   19807:        #page   
                   19808: #
                   19809: #      IOFCB -- GET INPUT/OUTPUT FCBLK POINTER
                   19810: #
                   19811: #      USED BY ENDFILE, EJECT AND REWIND TO FIND THE FCBLK
                   19812: #      (IF ANY) CORRESPONDING TO THEIR ARGUMENT.
                   19813: #
                   19814: #      -(XS)                 ARGUMENT
                   19815: #      JSR  IOFCB            CALL TO FIND FCBLK
                   19816: #      PPM  LOC              ARG IS AN UNSUITABLE NAME
                   19817: #      PPM  LOC              ARG IS NULL STRING
                   19818: #      (XS)                  POPPED
                   19819: #      (XL)                  PTR TO FILEARG1 VRBLK
                   19820: #      (XR)                  ARGUMENT
                   19821: #      (WA)                  FCBLK PTR OR 0
                   19822: #      (WB)                  DESTROYED
                   19823: #
                   19824:        .data   1
                   19825: iofcb_s:       .long   0
                   19826:        .text   0
                   19827: iofcb: movl    (sp)+,iofcb_s   # entry point
                   19828:        jsb     gtstg           # get arg as string
                   19829:        .long   iofc2           # fail
                   19830:        movl    r9,r10          # copy string ptr
                   19831:        jsb     gtnvr           # get as natural variable
                   19832:        .long   iofc3           # fail if null
                   19833:        movl    r10,r7          # copy string pointer again
                   19834:        movl    r9,r10          # copy vrblk ptr for return
                   19835:        clrl    r6              # in case no trblk found
                   19836: #
                   19837: #      LOOP TO FIND FILE ARG1 TRBLK
                   19838: #
                   19839: iofc1: movl    4*vrval(r9),r9  # get possible trblk ptr
                   19840:        cmpl    (r9),$b$trt     # fail if end of chain
                   19841:        bnequ   iofc2
                   19842:        cmpl    4*trtyp(r9),$trtfc # loop if not file arg trblk
                   19843:        bnequ   iofc1
                   19844:        movl    4*trfpt(r9),r6  # get fcblk ptr
                   19845:        movl    r7,r9           # copy arg
                   19846:        addl3   $4*2,iofcb_s,r11        # return
                   19847:        jmp     (r11)
                   19848: #
                   19849: #      FAIL RETURN
                   19850: #
                   19851: iofc2: movl    iofcb_s,r11     # fail
                   19852:        jmp     *(r11)+
                   19853: #
                   19854: #      NULL ARG
                   19855: #
                   19856: iofc3: addl3   $4*1,iofcb_s,r11        # null arg return
                   19857:        jmp     *(r11)+
                   19858:        #enp                    # end procedure iofcb
                   19859:        #page   
                   19860: #
                   19861: #      IOPPF -- PROCESS FILEARG2 FOR IOPUT
                   19862: #
                   19863: #      (R$XSC)               FILEARG2 PTR
                   19864: #      JSR  IOPPF            CALL TO PROCESS FILEARG2
                   19865: #      (XL)                  FILEARG1 PTR
                   19866: #      (XR)                  FILE ARG2 PTR
                   19867: #      -(XS)..-(XS)          FIELDS EXTRACTED FROM FILEARG2
                   19868: #      (WC)                  NO. OF FIELDS EXTRACTED
                   19869: #      (WB)                  INPUT/OUTPUT FLAG
                   19870: #      (WA)                  FCBLK PTR OR 0
                   19871: #
                   19872:        .data   1
                   19873: ioppf_s:       .long   0
                   19874:        .text   0
                   19875: ioppf: movl    (sp)+,ioppf_s   # entry point
                   19876:        clrl    r7              # to count fields extracted
                   19877: #
                   19878: #      LOOP TO EXTRACT FIELDS
                   19879: #
                   19880: iopp1: movl    $iodel,r10      # get delimiter
                   19881:        movl    r10,r8          # copy it
                   19882:        jsb     xscan           # get next field
                   19883:        movl    r9,-(sp)        # stack it
                   19884:        incl    r7              # increment count
                   19885:        tstl    r6              # loop
                   19886:        bnequ   iopp1
                   19887:        movl    r7,r8           # count of fields
                   19888:        movl    ioptt,r7        # i/o marker
                   19889:        movl    r$iof,r6        # fcblk ptr or 0
                   19890:        movl    r$io2,r9        # file arg2 ptr
                   19891:        movl    r$io1,r10       # filearg1
                   19892:        jmp     *ioppf_s        # return
                   19893:        #enp                    # end procedure ioppf
                   19894:        #page   
                   19895: #
                   19896: #      IOPUT -- ROUTINE USED BY INPUT AND OUTPUT
                   19897: #
                   19898: #      IOPUT SETS UP INPUT/OUTPUT  ASSOCIATIONS. IT BUILDS
                   19899: #      SUCH TRACE AND FILE CONTROL BLOCKS AS ARE NECESSARY AND
                   19900: #      CALLS SYSFC,SYSIO TO PERFORM CHECKS ON THE
                   19901: #      ARGUMENTS AND TO OPEN THE FILES.
                   19902: #
                   19903: #         +-----------+   +---------------+       +-----------+
                   19904: #      +-.I           I   I               I------.I   =B$XRT  I
                   19905: #      I  +-----------+   +---------------+       +-----------+
                   19906: #      I  /           /        (R$FCB)            I    *4     I
                   19907: #      I  /           /                           +-----------+
                   19908: #      I  +-----------+   +---------------+       I           I-
                   19909: #      I  I   NAME    +--.I    =B$TRT     I       +-----------+
                   19910: #      I  /           /   +---------------+       I           I
                   19911: #      I   (FIRST ARG)    I =TRTIN/=TRTOU I       +-----------+
                   19912: #      I                  +---------------+             I
                   19913: #      I                  I     VALUE     I             I
                   19914: #      I                  +---------------+             I
                   19915: #      I                  I(TRTRF) 0   OR I--+          I
                   19916: #      I                  +---------------+  I          I
                   19917: #      I                  I(TRFPT) 0   OR I----+        I
                   19918: #      I                  +---------------+  I I        I
                   19919: #      I                     (I/O TRBLK)     I I        I
                   19920: #      I  +-----------+                      I I        I
                   19921: #      I  I           I                      I I        I
                   19922: #      I  +-----------+                      I I        I
                   19923: #      I  I           I                      I I        I
                   19924: #      I  +-----------+   +---------------+  I I        I
                   19925: #      I  I           +--.I    =B$TRT     I.-+ I        I
                   19926: #      I  +-----------+   +---------------+    I        I
                   19927: #      I  /           /   I    =TRTFC     I    I        I
                   19928: #      I  /           /   +---------------+    I        I
                   19929: #      I    (FILEARG1     I     VALUE     I    I        I
                   19930: #      I         VRBLK)   +---------------+    I        I
                   19931: #      I                  I(TRTRF) 0   OR I--+ I        .
                   19932: #      I                  +---------------+  I .  +-----------+
                   19933: #      I                  I(TRFPT) 0   OR I------./   FCBLK   /
                   19934: #      I                  +---------------+  I    +-----------+
                   19935: #      I                       (TRTRF)       I
                   19936: #      I                                     I
                   19937: #      I                                     I
                   19938: #      I                  +---------------+  I
                   19939: #      I                  I    =B$XRT     I.-+
                   19940: #      I                  +---------------+
                   19941: #      I                  I      *5       I
                   19942: #      I                  +---------------+
                   19943: #      +------------------I               I
                   19944: #                         +---------------+       +-----------+
                   19945: #                         I(TRTRF) O   OR I------.I  =B$XRT   I
                   19946: #                         +---------------+       +-----------+
                   19947: #                         I  NAME OFFSET  I       I    ETC    I
                   19948: #                         +---------------+
                   19949: #                           (IOCHN - CHAIN OF NAME POINTERS)
                   19950:        #page   
                   19951: #
                   19952: #      IOPUT (CONTINUED)
                   19953: #
                   19954: #      NO ADDITIONAL TRAP BLOCKS ARE USED FOR STANDARD INPUT/OUT
                   19955: #      FILES. OTHERWISE AN I/O TRAP BLOCK IS ATTACHED TO SECOND
                   19956: #      ARG (FILEARG1) VRBLK. SEE DIAGRAM ABOVE FOR DETAILS OF
                   19957: #      THE STRUCTURE BUILT.
                   19958: #
                   19959: #      -(XS)                 1ST ARG (VBL TO BE ASSOCIATED)
                   19960: #      -(XS)                 2ND ARG (FILE ARG1)
                   19961: #      -(XS)                 3RD ARG (FILE ARG2)
                   19962: #      (WB)                  0 FOR INPUT, 3 FOR OUTPUT ASSOC.
                   19963: #      JSR  IOPUT            CALL FOR INPUT/OUTPUT ASSOCIATION
                   19964: #      PPM  LOC              3RD ARG NOT A STRING
                   19965: #      PPM  LOC              2ND ARG NOT A SUITABLE NAME
                   19966: #      PPM  LOC              1ST ARG NOT A SUITABLE NAME
                   19967: #      PPM  LOC              INAPPROPRIATE FILE SPEC FOR I/O
                   19968: #      PPM  LOC              I/O FILE DOES NOT EXIST
                   19969: #      PPM  LOC              I/O FILE CANNOT BE READ/WRITTEN
                   19970: #      (XS)                  POPPED
                   19971: #      (XL,XR,WA,WB,WC)      DESTROYED
                   19972: #
                   19973:        .data   1
                   19974: ioput_s:       .long   0
                   19975:        .text   0
                   19976: ioput: movl    (sp)+,ioput_s   # entry point
                   19977:        clrl    r$iot           # in case no trtrf block used
                   19978:        clrl    r$iof           # in case no fcblk alocated
                   19979:        movl    r7,ioptt        # store i/o trace type
                   19980:        jsb     xscni           # prepare to scan filearg2
                   19981:        .long   iop13           # fail
                   19982:        .long   iopa0           # null file arg2
                   19983: #
                   19984: iopa0: movl    r9,r$io2        # keep file arg2
                   19985:        movl    r6,r10          # copy length
                   19986:        jsb     gtstg           # convert filearg1 to string
                   19987:        .long   iop14           # fail
                   19988:        movl    r9,r$io1        # keep filearg1 ptr
                   19989:        jsb     gtnvr           # convert to natural variable
                   19990:        .long   iop00           # jump if null
                   19991:        jmp     iop04           # jump to process non-null args
                   19992: #
                   19993: #      NULL FILEARG1
                   19994: #
                   19995: iop00: tstl    r10             # skip if both args null
                   19996:        bnequ   0f
                   19997:        jmp     iop01
                   19998: 0:             
                   19999:        jsb     ioppf           # process filearg2
                   20000:        jsb     sysfc           # call for filearg2 check
                   20001:        .long   iop16           # fail
                   20002:        jmp     iop11           # complete file association
                   20003:        #page   
                   20004: #
                   20005: #      IOPUT (CONTINUED)
                   20006: #
                   20007: #      HERE WITH 0 OR FCBLK PTR IN (XL)
                   20008: #
                   20009: iop01: movl    ioptt,r7        # get trace type
                   20010:        movl    r$iot,r9        # get 0 or trtrf ptr
                   20011:        jsb     trbld           # build trblk
                   20012:        movl    r9,r8           # copy trblk pointer
                   20013:        movl    (sp)+,r9        # get variable from stack
                   20014:        jsb     gtvar           # point to variable
                   20015:        .long   iop15           # fail
                   20016:        movl    r10,r$ion       # save name pointer
                   20017:        movl    r10,r9          # copy name pointer
                   20018:        addl2   r6,r9           # point to variable
                   20019:        subl2   $4*vrval,r9     # subtract offset,merge into loop
                   20020: #
                   20021: #      LOOP TO END OF TRBLK CHAIN IF ANY
                   20022: #
                   20023: iop02: movl    r9,r10          # copy blk ptr
                   20024:        movl    4*vrval(r9),r9  # load ptr to next trblk
                   20025:        cmpl    (r9),$b$trt     # jump if not trapped
                   20026:        bnequ   iop03
                   20027:        cmpl    4*trtyp(r9),ioptt# loop if not same assocn
                   20028:        bnequ   iop02
                   20029:        movl    4*trnxt(r9),r9  # get value and delete old trblk
                   20030: #
                   20031: #      IOPUT (CONTINUED)
                   20032: #
                   20033: #      STORE NEW ASSOCIATION
                   20034: #
                   20035: iop03: movl    r8,4*vrval(r10) # link to this trblk
                   20036:        movl    r8,r10          # copy pointer
                   20037:        movl    r9,4*trnxt(r10) # store value in trblk
                   20038:        movl    r$ion,r9        # restore possible vrblk pointer
                   20039:        movl    r6,r7           # keep offset to name
                   20040:        jsb     setvr           # if vrblk, set vrget,vrsto
                   20041:        movl    r$iot,r9        # get 0 or trtrf ptr
                   20042:        tstl    r9              # jump if trtrf block exists
                   20043:        beqlu   0f
                   20044:        jmp     iop19
                   20045: 0:             
                   20046:        addl3   $4*6,ioput_s,r11        # return to caller
                   20047:        jmp     (r11)
                   20048: #
                   20049: #      NON STANDARD FILE
                   20050: #      SEE IF AN FCBLK HAS ALREADY BEEN ALLOCATED.
                   20051: #
                   20052: iop04: clrl    r6              # in case no fcblk found
                   20053:        #page   
                   20054: #
                   20055: #      IOPUT (CONTINUED)
                   20056: #
                   20057: #      SEARCH POSSIBLE TRBLK CHAIN TO PICK UP THE FCBLK
                   20058: #
                   20059: iop05: movl    r9,r7           # remember blk ptr
                   20060:        movl    4*vrval(r9),r9  # chain along
                   20061:        cmpl    (r9),$b$trt     # jump if end of trblk chain
                   20062:        bnequ   iop06
                   20063:        cmpl    4*trtyp(r9),$trtfc # loop if more to go
                   20064:        bnequ   iop05
                   20065:        movl    r9,r$iot        # point to file arg1 trblk
                   20066:        movl    4*trfpt(r9),r6  # get fcblk ptr from trblk
                   20067: #
                   20068: #      WA = 0 OR FCBLK PTR
                   20069: #      WB = PTR TO PRECEDING BLK TO WHICH ANY TRTRF BLOCK
                   20070: #           FOR FILE ARG1 MUST BE CHAINED.
                   20071: #
                   20072: iop06: movl    r6,r$iof        # keep possible fcblk ptr
                   20073:        movl    r7,r$iop        # keep preceding blk ptr
                   20074:        jsb     ioppf           # process filearg2
                   20075:        jsb     sysfc           # see if fcblk required
                   20076:        .long   iop16           # fail
                   20077:        tstl    r6              # skip if no new fcblk wanted
                   20078:        bnequ   0f
                   20079:        jmp     iop12
                   20080: 0:             
                   20081:        cmpl    r8,$num02       # jump if fcblk in dynamic
                   20082:        blssu   iop6a
                   20083:        jsb     alost           # get it in static
                   20084:        jmp     iop6b           # skip
                   20085: #
                   20086: #      OBTAIN FCBLK IN DYNAMIC
                   20087: #
                   20088: iop6a: jsb     alloc           # get space for fcblk
                   20089: #
                   20090: #      MERGE
                   20091: #
                   20092: iop6b: movl    r9,r10          # point to fcblk
                   20093:        movl    r6,r7           # copy its length
                   20094:        ashl    $-2,r7,r7       # get count as words (sgd apr80)
                   20095:                                # loop counter
                   20096: #
                   20097: #      CLEAR FCBLK
                   20098: #
                   20099: iop07: clrl    (r9)+           # clear a word
                   20100:        sobgtr  r7,iop07        # loop
                   20101:        cmpl    r8,$num02       # skip if in static - dont set fields
                   20102:        bnequ   0f
                   20103:        jmp     iop09
                   20104: 0:             
                   20105:        movl    $b$xnt,(r10)    # store xnblk code in case
                   20106:        movl    r6,4*1(r10)     # store length
                   20107:        tstl    r8              # jump if xnblk wanted
                   20108:        beqlu   0f
                   20109:        jmp     iop09
                   20110: 0:             
                   20111:        movl    $b$xrt,(r10)    # xrblk code requested
                   20112: #
                   20113:        #page   
                   20114: #      IOPUT (CONTINUED)
                   20115: #
                   20116: #      COMPLETE FCBLK INITIALISATION
                   20117: #
                   20118: iop09: movl    r$iot,r9        # get possible trblk ptr
                   20119:        movl    r10,r$iof       # store fcblk ptr
                   20120:        tstl    r9              # jump if trblk already found
                   20121:        bnequ   iop10
                   20122: #
                   20123: #      A NEW TRBLK IS NEEDED
                   20124: #
                   20125:        movl    $trtfc,r7       # trtyp for fcblk trap blk
                   20126:        jsb     trbld           # make the block
                   20127:        movl    r9,r$iot        # copy trtrf ptr
                   20128:        movl    r$iop,r10       # point to preceding blk
                   20129:        movl    4*vrval(r10),4*vrval(r9) # copy value field to trblk
                   20130:        movl    r9,4*vrval(r10) # link new trblk into chain
                   20131:        movl    r10,r9          # point to predecessor blk
                   20132:        jsb     setvr           # set trace intercepts
                   20133:        movl    4*vrval(r9),r9  # recover trblk ptr
                   20134: #
                   20135: #      XR IS PTR TO TRBLK, XL IS FCBLK PTR OR 0
                   20136: #
                   20137: iop10: movl    r$iof,4*trfpt(r9)# store fcblk ptr
                   20138: #
                   20139: #      CALL SYSIO TO COMPLETE FILE ACCESSING
                   20140: #
                   20141: iop11: movl    r$iof,r6        # copy fcblk ptr or 0
                   20142:        movl    ioptt,r7        # get input/output flag
                   20143:        movl    r$io2,r9        # get file arg2
                   20144:        movl    r$io1,r10       # get file arg1
                   20145:        jsb     sysio           # associate to the file
                   20146:        .long   iop17           # fail
                   20147:        .long   iop18           # fail
                   20148:        tstl    r$iot           # not std input if non-null trtrf blk
                   20149:        beqlu   0f
                   20150:        jmp     iop01
                   20151: 0:             
                   20152:        tstl    ioptt           # jump if output
                   20153:        beqlu   0f
                   20154:        jmp     iop01
                   20155: 0:             
                   20156:        tstl    r8              # no change to standard read length
                   20157:        bnequ   0f
                   20158:        jmp     iop01
                   20159: 0:             
                   20160:        movl    r8,cswin        # store new read length for std file
                   20161:        jmp     iop01           # merge to finish the task
                   20162: #
                   20163: #      SYSFC MAY HAVE RETURNED A POINTER TO A PRIVATE FCBLK
                   20164: #
                   20165: iop12: tstl    r10             # jump if private fcblk
                   20166:        beqlu   0f
                   20167:        jmp     iop09
                   20168: 0:             
                   20169:        jmp     iop11           # finish the association
                   20170: #
                   20171: #      FAILURE RETURNS
                   20172: #
                   20173: iop13: movl    ioput_s,r11     # 3rd arg not a string
                   20174:        jmp     *(r11)+
                   20175: iop14: addl3   $4*1,ioput_s,r11        # 2nd arg unsuitable
                   20176:        jmp     *(r11)+
                   20177: iop15: addl3   $4*2,ioput_s,r11        # 1st arg unsuitable
                   20178:        jmp     *(r11)+
                   20179: iop16: addl3   $4*3,ioput_s,r11        # file spec wrong
                   20180:        jmp     *(r11)+
                   20181: iop17: addl3   $4*4,ioput_s,r11        # i/o file does not exist
                   20182:        jmp     *(r11)+
                   20183: iop18: addl3   $4*5,ioput_s,r11        # i/o file cannot be read/written
                   20184:        jmp     *(r11)+
                   20185:        #page   
                   20186: #
                   20187: #      IOPUT (CONTINUED)
                   20188: #
                   20189: #      ADD TO IOCHN CHAIN OF ASSSOCIATED VARIABLES UNLESS ALREAD
                   20190: #      PRESENT.
                   20191: #
                   20192: iop19: movl    r$ion,r8        # wc = name base, wb = name offset
                   20193: #
                   20194: #      SEARCH LOOP
                   20195: #
                   20196: iop20: movl    4*trtrf(r9),r9  # next link of chain
                   20197:        tstl    r9              # not found
                   20198:        beqlu   iop21
                   20199:        cmpl    r8,4*ionmb(r9)  # no match
                   20200:        bnequ   iop20
                   20201:        cmpl    r7,4*ionmo(r9)  # exit if matched
                   20202:        beqlu   iop22
                   20203:        jmp     iop20           # loop
                   20204: #
                   20205: #      NOT FOUND
                   20206: #
                   20207: iop21: movl    $4*num05,r6     # space needed
                   20208:        jsb     alloc           # get it
                   20209:        movl    $b$xrt,(r9)     # store xrblk code
                   20210:        movl    r6,4*1(r9)      # store length
                   20211:        movl    r8,4*ionmb(r9)  # store name base
                   20212:        movl    r7,4*ionmo(r9)  # store name offset
                   20213:        movl    r$iot,r10       # point to trtrf blk
                   20214:        movl    4*trtrf(r10),r6 # get ptr field contents
                   20215:        movl    r9,4*trtrf(r10) # store ptr to new block
                   20216:        movl    r6,4*trtrf(r9)  # complete the linking
                   20217: #
                   20218: #      INSERT FCBLK ON FCBLK CHAIN FOR SYSEJ, SYSXI
                   20219: #
                   20220: iop22: tstl    r$iof           # skip if no fcblk
                   20221:        beqlu   iop25
                   20222:        movl    r$fcb,r10       # ptr to head of existing chain
                   20223: #
                   20224: #      SEE IF FCBLK ALREADY ON CHAIN
                   20225: #
                   20226: iop23: tstl    r10             # not on if end of chain
                   20227:        beqlu   iop24
                   20228:        cmpl    4*3(r10),r$iof  # dont duplicate if find it
                   20229:        beqlu   iop25
                   20230:        movl    4*2(r10),r10    # get next link
                   20231:        jmp     iop23           # loop
                   20232: #
                   20233: #      NOT FOUND SO ADD AN ENTRY FOR THIS FCBLK
                   20234: #
                   20235: iop24: movl    $4*num04,r6     # space needed
                   20236:        jsb     alloc           # get it
                   20237:        movl    $b$xrt,(r9)     # store block code
                   20238:        movl    r6,4*1(r9)      # store length
                   20239:        movl    r$fcb,4*2(r9)   # store previous link in this node
                   20240:        movl    r$iof,4*3(r9)   # store fcblk ptr
                   20241:        movl    r9,r$fcb        # insert node into fcblk chain
                   20242: #
                   20243: #      RETURN
                   20244: #
                   20245: iop25: addl3   $4*6,ioput_s,r11        # return to caller
                   20246:        jmp     (r11)
                   20247:        #enp                    # end procedure ioput
                   20248:        #page   
                   20249: #
                   20250: #      KTREX -- EXECUTE KEYWORD TRACE
                   20251: #
                   20252: #      KTREX IS USED TO EXECUTE A POSSIBLE KEYWORD TRACE. IT
                   20253: #      INCLUDES THE TEST ON TRACE AND TESTS FOR TRACE ACTIVE.
                   20254: #
                   20255: #      (XL)                  PTR TO TRBLK (OR 0 IF UNTRACED)
                   20256: #      JSR  KTREX            CALL TO EXECUTE KEYWORD TRACE
                   20257: #      (XL,WA,WB,WC)         DESTROYED
                   20258: #      (RA)                  DESTROYED
                   20259: #
                   20260: ktrex: #prc                    # entry point (recursive)
                   20261:        tstl    r10             # immediate exit if keyword untraced
                   20262:        beqlu   ktrx3
                   20263:        tstl    kvtra           # immediate exit if trace = 0
                   20264:        beqlu   ktrx3
                   20265:        decl    kvtra           # else decrement trace
                   20266:        movl    r9,-(sp)        # save xr
                   20267:        movl    r10,r9          # copy trblk pointer
                   20268:        movl    4*trkvr(r9),r10 # load vrblk pointer (nmbas)
                   20269:        movl    $4*vrval,r6     # set name offset
                   20270:        tstl    4*trfnc(r9)     # jump if print trace
                   20271:        beqlu   ktrx1
                   20272:        jsb     trxeq           # else execute full trace
                   20273:        jmp     ktrx2           # and jump to exit
                   20274: #
                   20275: #      HERE FOR PRINT TRACE
                   20276: #
                   20277: ktrx1: movl    r10,-(sp)       # stack vrblk ptr for kwnam
                   20278:        movl    r6,-(sp)        # stack offset for kwnam
                   20279:        jsb     prtsn           # print statement number
                   20280:        movl    $ch$am,r6       # load ampersand
                   20281:        jsb     prtch           # print ampersand
                   20282:        jsb     prtnm           # print keyword name
                   20283:        movl    $tmbeb,r9       # point to blank-equal-blank
                   20284:        jsb     prtst           # print blank-equal-blank
                   20285:        jsb     kwnam           # get keyword pseudo-variable name
                   20286:        movl    r9,dnamp        # reset ptr to delete kvblk
                   20287:        jsb     acess           # get keyword value
                   20288:        .long   invalid$        # failure is impossible
                   20289:        jsb     prtvl           # print keyword value
                   20290:        jsb     prtnl           # terminate print line
                   20291: #
                   20292: #      HERE TO EXIT AFTER COMPLETING TRACE
                   20293: #
                   20294: ktrx2: movl    (sp)+,r9        # restore entry xr
                   20295: #
                   20296: #      MERGE HERE TO EXIT IF NO TRACE REQUIRED
                   20297: #
                   20298: ktrx3: rsb                     # return to ktrex caller
                   20299:        #enp                    # end procedure ktrex
                   20300:        #page   
                   20301: #
                   20302: #      KWNAM -- GET PSEUDO-VARIABLE NAME FOR KEYWORD
                   20303: #
                   20304: #      1(XS)                 NAME BASE FOR VRBLK
                   20305: #      0(XS)                 OFFSET (SHOULD BE *VRVAL)
                   20306: #      JSR  KWNAM            CALL TO GET PSEUDO-VARIABLE NAME
                   20307: #      (XS)                  POPPED TWICE
                   20308: #      (XL,WA)               RESULTING PSEUDO-VARIABLE NAME
                   20309: #      (XR,WA,WB)            DESTROYED
                   20310: #
                   20311:        .data   1
                   20312: kwnam_s:       .long   0
                   20313:        .text   0
                   20314: kwnam: movl    (sp)+,kwnam_s   # entry point
                   20315:        addl2   $4,sp           # ignore name offset
                   20316:        movl    (sp)+,r9        # load name base
                   20317:        cmpl    r9,state        # jump if not natural variable name
                   20318:        bgequ   kwnm1
                   20319:        tstl    4*vrlen(r9)     # error if not system variable
                   20320:        bnequ   kwnm1
                   20321:        movl    4*vrsvp(r9),r9  # else point to svblk
                   20322:        movl    4*svbit(r9),r6  # load bit mask
                   20323:        mcoml   btknm,r11       # and with keyword bit
                   20324:        bicl2   r11,r6
                   20325:        tstl    r6              # error if no keyword association
                   20326:        beqlu   kwnm1
                   20327:        movl    4*svlen(r9),r6  # else load name length in characters
                   20328:        movab   3+(4*svchs)(r6),r6 # compute offset to field we want
                   20329:        bicl2   $3,r6
                   20330:        addl2   r6,r9           # point to svknm field
                   20331:        movl    (r9),r7         # load svknm value
                   20332:        movl    $4*kvsi$,r6     # set size of kvblk
                   20333:        jsb     alloc           # allocate kvblk
                   20334:        movl    $b$kvt,(r9)     # store type word
                   20335:        movl    r7,4*kvnum(r9)  # store keyword number
                   20336:        movl    $trbkv,4*kvvar(r9) # set dummy trblk pointer
                   20337:        movl    r9,r10          # copy kvblk pointer
                   20338:        movl    $4*kvvar,r6     # set proper offset
                   20339:        jmp     *kwnam_s        # return to kvnam caller
                   20340: #
                   20341: #      HERE IF NOT KEYWORD NAME
                   20342: #
                   20343: kwnm1: jmp     er_251          # keyword operand is not name of defined keyword
                   20344:        #enp                    # end procedure kwnam
                   20345:        #page   
                   20346: #
                   20347: #      LCOMP-- COMPARE TWO STRINGS LEXICALLY
                   20348: #
                   20349: #      1(XS)                 FIRST ARGUMENT
                   20350: #      0(XS)                 SECOND ARGUMENT
                   20351: #      JSR  LCOMP            CALL TO COMPARE ARUMENTS
                   20352: #      PPM  LOC              TRANSFER LOC FOR ARG1 NOT STRING
                   20353: #      PPM  LOC              TRANSFER LOC FOR ARG2 NOT STRING
                   20354: #      PPM  LOC              TRANSFER LOC IF ARG1 LLT ARG2
                   20355: #      PPM  LOC              TRANSFER LOC IF ARG1 LEQ ARG2
                   20356: #      PPM  LOC              TRANSFER LOC IF ARG1 LGT ARG2
                   20357: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   20358: #      (XS)                  POPPED TWICE
                   20359: #      (XR,XL)               DESTROYED
                   20360: #      (WA,WB,WC,RA)         DESTROYED
                   20361: #
                   20362:        .data   1
                   20363: lcomp_s:       .long   0
                   20364:        .text   0
                   20365: lcomp: movl    (sp)+,lcomp_s   # entry point
                   20366:        jsb     gtstg           # convert second arg to string
                   20367:        .long   lcmp6           # jump if second arg not string
                   20368:        movl    r9,r10          # else save pointer
                   20369:        movl    r6,r7           # and length
                   20370:        jsb     gtstg           # convert first argument to string
                   20371:        .long   lcmp5           # jump if not string
                   20372:        movl    r6,r8           # save arg 1 length
                   20373:        movab   cfp$f(r9),r9    # point to chars of arg 1
                   20374:        movab   cfp$f(r10),r10  # point to chars of arg 2
                   20375:        cmpl    r6,r7           # jump if arg 1 length is smaller
                   20376:        blequ   lcmp1
                   20377:        movl    r7,r6           # else set arg 2 length as smaller
                   20378: #
                   20379: #      HERE WITH SMALLER LENGTH IN (WA)
                   20380: #
                   20381: lcmp1: jsb     sbcmc           # compare strings, jump if unequal
                   20382:        .long   lcmp4
                   20383:        .long   lcmp3
                   20384:        cmpl    r7,r8           # if equal, jump if lengths unequal
                   20385:        bnequ   lcmp2
                   20386:        addl3   $4*3,lcomp_s,r11        # else identical strings, leq exit
                   20387:        jmp     *(r11)+
                   20388:        #page   
                   20389: #
                   20390: #      LCOMP (CONTINUED)
                   20391: #
                   20392: #      HERE IF INITIAL STRINGS IDENTICAL, BUT LENGTHS UNEQUAL
                   20393: #
                   20394: lcmp2: cmpl    r8,r7           # jump if arg 1 length gt arg 2 leng
                   20395:        bgequ   lcmp4
                   20396: #
                   20397: #      HERE IF FIRST ARG LLT SECOND ARG
                   20398: #
                   20399: lcmp3: addl3   $4*2,lcomp_s,r11        # take llt exit
                   20400:        jmp     *(r11)+
                   20401: #
                   20402: #      HERE IF FIRST ARG LGT SECOND ARG
                   20403: #
                   20404: lcmp4: addl3   $4*4,lcomp_s,r11        # take lgt exit
                   20405:        jmp     *(r11)+
                   20406: #
                   20407: #      HERE IF FIRST ARG IS NOT A STRING
                   20408: #
                   20409: lcmp5: movl    lcomp_s,r11     # take bad first arg exit
                   20410:        jmp     *(r11)+
                   20411: #
                   20412: #      HERE FOR SECOND ARG NOT A STRING
                   20413: #
                   20414: lcmp6: addl3   $4*1,lcomp_s,r11        # take bad second arg error exit
                   20415:        jmp     *(r11)+
                   20416:        #enp                    # end procedure lcomp
                   20417:        #page   
                   20418: #
                   20419: #      LISTR -- LIST SOURCE LINE
                   20420: #
                   20421: #      LISTR IS USED TO LIST A SOURCE LINE DURING THE INITIAL
                   20422: #      COMPILATION. IT IS CALLED FROM SCANE AND SCANL.
                   20423: #
                   20424: #      JSR  LISTR            CALL TO LIST LINE
                   20425: #      (XR,XL,WA,WB,WC)      DESTROYED
                   20426: #
                   20427: #      GLOBAL LOCATIONS USED BY LISTR
                   20428: #
                   20429: #      ERLST                 IF LISTING ON ACCOUNT OF AN ERROR
                   20430: #
                   20431: #      LSTLC                 COUNT LINES ON CURRENT PAGE
                   20432: #
                   20433: #      LSTNP                 MAX NUMBER OF LINES/PAGE
                   20434: #
                   20435: #      LSTPF                 SET NON-ZERO IF THE CURRENT SOURCE
                   20436: #                            LINE HAS BEEN LISTED, ELSE ZERO.
                   20437: #
                   20438: #      LSTPG                 COMPILER LISTING PAGE NUMBER
                   20439: #
                   20440: #      LSTSN                 SET IF STMNT NUM TO BE LISTED
                   20441: #
                   20442: #      R$CIM                 POINTER TO CURRENT INPUT LINE.
                   20443: #
                   20444: #      R$TTL                 TITLE FOR SOURCE LISTING
                   20445: #
                   20446: #      R$STL                 PTR TO SUB-TITLE STRING
                   20447: #
                   20448: #      ENTRY POINT
                   20449: #
                   20450: listr: #prc                    # entry point
                   20451:        tstl    cnttl           # jump if -title or -stitl
                   20452:        beqlu   0f
                   20453:        jmp     list5
                   20454: 0:             
                   20455:        tstl    lstpf           # immediate exit if already listed
                   20456:        beqlu   0f
                   20457:        jmp     list4
                   20458: 0:             
                   20459:        cmpl    lstlc,lstnp     # jump if no room
                   20460:        blssu   0f
                   20461:        jmp     list6
                   20462: 0:             
                   20463: #
                   20464: #      HERE AFTER PRINTING TITLE (IF NEEDED)
                   20465: #
                   20466: list0: movl    r$cim,r9        # load pointer to current image
                   20467:        movab   cfp$f(r9),r9    # point to characters
                   20468:        movzbl  (r9),r6         # load first character
                   20469:        movl    lstsn,r9        # load statement number
                   20470:        tstl    r9              # jump if no statement number
                   20471:        beqlu   list2
                   20472:        movl    r9,r5           # else get stmnt number as integer
                   20473:        cmpl    stage,$stgic    # skip if execute time
                   20474:        bnequ   list1
                   20475:        cmpl    r6,$ch$as       # no stmnt number list if comment
                   20476:        beqlu   list2
                   20477:        cmpl    r6,$ch$mn       # no stmnt no. if control card
                   20478:        beqlu   list2
                   20479: #
                   20480: #      PRINT STATEMENT NUMBER
                   20481: #
                   20482: list1: jsb     prtin           # else print statement number
                   20483:        clrl    lstsn           # and clear for next time in
                   20484:        #page   
                   20485: #
                   20486: #      LISTR (CONTINUED)
                   20487: #
                   20488: #      MERGE HERE AFTER PRINTING STATEMENT NUMBER (IF REQUIRED)
                   20489: #
                   20490: list2: movl    $stnpd,profs    # point past statement number
                   20491:        movl    r$cim,r9        # load pointer to current image
                   20492:        jsb     prtst           # print it
                   20493:        incl    lstlc           # bump line counter
                   20494:        tstl    erlst           # jump if error copy to int.ch.
                   20495:        bnequ   list3
                   20496:        jsb     prtnl           # terminate line
                   20497:        tstl    cswdb           # jump if -single mode
                   20498:        beqlu   list3
                   20499:        jsb     prtnl           # else add a blank line
                   20500:        incl    lstlc           # and bump line counter
                   20501: #
                   20502: #      HERE AFTER PRINTING SOURCE IMAGE
                   20503: #
                   20504: list3: movl    sp,lstpf        # set flag for line printed
                   20505: #
                   20506: #      MERGE HERE TO EXIT
                   20507: #
                   20508: list4: rsb                     # return to listr caller
                   20509: #
                   20510: #      PRINT TITLE AFTER -TITLE OR -STITL CARD
                   20511: #
                   20512: list5: clrl    cnttl           # clear flag
                   20513: #
                   20514: #      EJECT TO NEW PAGE AND LIST TITLE
                   20515: #
                   20516: list6: jsb     prtps           # eject
                   20517:        tstl    prich           # skip if listing to regular printer
                   20518:        beqlu   list7
                   20519:        cmpl    r$ttl,$nulls    # terminal listing omits null title
                   20520:        bnequ   0f
                   20521:        jmp     list0
                   20522: 0:             
                   20523: #
                   20524: #      LIST TITLE
                   20525: #
                   20526: list7: jsb     listt           # list title
                   20527:        jmp     list0           # merge
                   20528:        #enp                    # end procedure listr
                   20529:        #page   
                   20530: #
                   20531: #      LISTT -- LIST TITLE AND SUBTITLE
                   20532: #
                   20533: #      USED DURING COMPILATION TO PRINT PAGE HEADING
                   20534: #
                   20535: #      JSR  LISTT            CALL TO LIST TITLE
                   20536: #      (XR,WA)               DESTROYED
                   20537: #
                   20538: listt: #prc                    # entry point
                   20539:        movl    r$ttl,r9        # point to source listing title
                   20540:        jsb     prtst           # print title
                   20541:        movl    lstpo,profs     # set offset
                   20542:        movl    $lstms,r9       # set page message
                   20543:        jsb     prtst           # print page message
                   20544:        incl    lstpg           # bump page number
                   20545:        movl    lstpg,r5        # load page number as integer
                   20546:        jsb     prtin           # print page number
                   20547:        jsb     prtnl           # terminate title line
                   20548:        addl2   $num02,lstlc    # count title line and blank line
                   20549: #
                   20550: #      PRINT SUB-TITLE (IF ANY)
                   20551: #
                   20552:        movl    r$stl,r9        # load pointer to sub-title
                   20553:        tstl    r9              # jump if no sub-title
                   20554:        beqlu   lstt1
                   20555:        jsb     prtst           # else print sub-title
                   20556:        jsb     prtnl           # terminate line
                   20557:        incl    lstlc           # bump line count
                   20558: #
                   20559: #      RETURN POINT
                   20560: #
                   20561: lstt1: jsb     prtnl           # print a blank line
                   20562:        rsb                     # return to caller
                   20563:        #enp                    # end procedure listt
                   20564:        #page   
                   20565: #
                   20566: #      NEXTS -- ACQUIRE NEXT SOURCE IMAGE
                   20567: #
                   20568: #      NEXTS IS USED TO ACQUIRE THE NEXT SOURCE IMAGE AT COMPILE
                   20569: #      TIME. IT ASSUMES THAT A PRIOR CALL TO READR HAS INPUT
                   20570: #      A LINE IMAGE (SEE PROCEDURE READR). BEFORE THE CURRENT
                   20571: #      IMAGE IS FINALLY LOST IT MAY BE LISTED HERE.
                   20572: #
                   20573: #      JSR  NEXTS            CALL TO ACQUIRE NEXT INPUT LINE
                   20574: #      (XR,XL,WA,WB,WC)      DESTROYED
                   20575: #
                   20576: #      GLOBAL VALUES AFFECTED
                   20577: #
                   20578: #      R$CNI                 ON INPUT, NEXT IMAGE. ON
                   20579: #                            EXIT RESET TO ZERO
                   20580: #
                   20581: #      R$CIM                 ON EXIT, SET TO POINT TO IMAGE
                   20582: #
                   20583: #      SCNIL                 INPUT IMAGE LENGTH ON EXIT
                   20584: #
                   20585: #      SCNSE                 RESET TO ZERO ON EXIT
                   20586: #
                   20587: #      LSTPF                 SET ON EXIT IF LINE IS LISTED
                   20588: #
                   20589: nexts: #prc                    # entry point
                   20590:        tstl    cswls           # jump if -nolist
                   20591:        beqlu   nxts2
                   20592:        movl    r$cim,r9        # point to image
                   20593:        tstl    r9              # jump if no image
                   20594:        beqlu   nxts2
                   20595:        movab   cfp$f(r9),r9    # get char ptr
                   20596:        movzbl  (r9),r6         # get first char
                   20597:        cmpl    r6,$ch$mn       # jump if not ctrl card
                   20598:        bnequ   nxts1
                   20599:        tstl    cswpr           # jump if -noprint
                   20600:        beqlu   nxts2
                   20601: #
                   20602: #      HERE TO CALL LISTER
                   20603: #
                   20604: nxts1: jsb     listr           # list line
                   20605: #
                   20606: #      HERE AFTER POSSIBLE LISTING
                   20607: #
                   20608: nxts2: movl    r$cni,r9        # point to next image
                   20609:        movl    r9,r$cim        # set as next image
                   20610:        clrl    r$cni           # clear next image pointer
                   20611:        movl    4*sclen(r9),r6  # get input image length
                   20612:        movl    cswin,r7        # get max allowable length
                   20613:        cmpl    r6,r7           # skip if not too long
                   20614:        blequ   nxts3
                   20615:        movl    r7,r6           # else truncate
                   20616: #
                   20617: #      HERE WITH LENGTH IN (WA)
                   20618: #
                   20619: nxts3: movl    r6,scnil        # use as record length
                   20620:        clrl    scnse           # reset scnse
                   20621:        clrl    lstpf           # set line not listed yet
                   20622:        rsb                     # return to nexts caller
                   20623:        #enp                    # end procedure nexts
                   20624:        #page   
                   20625: #
                   20626: #      PATIN -- PATTERN CONSTRUCTION FOR LEN,POS,RPOS,TAB,RTAB
                   20627: #
                   20628: #      THESE PATTERN TYPES ALL GENERATE A SIMILAR NODE TYPE. SO
                   20629: #      THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION
                   20630: #      FOR ACTUAL ENTRY POINTS FOR THESE FIVE FUNCTIONS.
                   20631: #
                   20632: #      (WA)                  PCODE FOR EXPRESSION ARG CASE
                   20633: #      (WB)                  PCODE FOR INTEGER ARG CASE
                   20634: #      JSR  PATIN            CALL TO BUILD PATTERN NODE
                   20635: #      PPM  LOC              TRANSFER LOC FOR NOT INTEGER OR EXP
                   20636: #      PPM  LOC              TRANSFER LOC FOR INT OUT OF RANGE
                   20637: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20638: #      (XL,WA,WB,WC,IA)      DESTROYED
                   20639: #
                   20640:        .data   1
                   20641: patin_s:       .long   0
                   20642:        .text   0
                   20643: patin: movl    (sp)+,patin_s   # entry point
                   20644:        movl    r6,r10          # preserve expression arg pcode
                   20645:        jsb     gtsmi           # try to convert arg as small integer
                   20646:        .long   ptin2           # jump if not integer
                   20647:        .long   ptin3           # jump if out of range
                   20648: #
                   20649: #      COMMON SUCCESSFUL EXIT POINT
                   20650: #
                   20651: ptin1: jsb     pbild           # build pattern node
                   20652:        addl3   $4*2,patin_s,r11        # return to caller
                   20653:        jmp     (r11)
                   20654: #
                   20655: #      HERE IF ARGUMENT IS NOT AN INTEGER
                   20656: #
                   20657: ptin2: movl    r10,r7          # copy expr arg case pcode
                   20658:        cmpl    (r9),$b$e$$     # all ok if expression arg
                   20659:        blequ   ptin1
                   20660:        movl    patin_s,r11     # else take error exit for wrong type
                   20661:        jmp     *(r11)+
                   20662: #
                   20663: #      HERE FOR ERROR OF OUT OF RANGE INTEGER ARGUMENT
                   20664: #
                   20665: ptin3: addl3   $4*1,patin_s,r11        # take out-of-range error exit
                   20666:        jmp     *(r11)+
                   20667:        #enp                    # end procedure patin
                   20668:        #page   
                   20669: #
                   20670: #      PATST -- PATTERN CONSTRUCTION FOR ANY,NOTANY,
                   20671: #               BREAK,SPAN AND BREAKX PATTERN FUNCTIONS.
                   20672: #
                   20673: #      THESE PATTERN FUNCTIONS BUILD SIMILAR TYPES OF NODES AND
                   20674: #      THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION
                   20675: #      FOR ACTUAL ENTRY POINTS FOR THESE FIVE PATTERN FUNCTIONS.
                   20676: #
                   20677: #      0(XS)                 STRING ARGUMENT
                   20678: #      (WB)                  PCODE FOR ONE CHAR ARGUMENT
                   20679: #      (XL)                  PCODE FOR MULTI-CHAR ARGUMENT
                   20680: #      (WC)                  PCODE FOR EXPRESSION ARGUMENT
                   20681: #      JSR  PATST            CALL TO BUILD NODE
                   20682: #      PPM  LOC              TRANSFER LOC IF NOT STRING OR EXPR
                   20683: #      (XS)                  POPPED PAST STRING ARGUMENT
                   20684: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20685: #      (XL)                  DESTROYED
                   20686: #      (WA,WB,WC,RA)         DESTROYED
                   20687: #
                   20688: #      NOTE THAT THERE IS A SPECIAL CALL TO PATST IN THE EVALS
                   20689: #      PROCEDURE WITH A SLIGHTLY DIFFERENT FORM. SEE EVALS
                   20690: #      FOR DETAILS OF THE FORM OF THIS CALL.
                   20691: #
                   20692:        .data   1
                   20693: patst_s:       .long   0
                   20694:        .text   0
                   20695: patst: movl    (sp)+,patst_s   # entry point
                   20696:        jsb     gtstg           # convert argument as string
                   20697:        .long   pats7           # jump if not string
                   20698:        cmpl    r6,$num01       # jump if not one char string
                   20699:        bnequ   pats2
                   20700: #
                   20701: #      HERE FOR ONE CHAR STRING CASE
                   20702: #
                   20703:        tstl    r7              # treat as multi-char if evals call
                   20704:        beqlu   pats2
                   20705:        movab   cfp$f(r9),r9    # point to character
                   20706:        movzbl  (r9),r9         # load character
                   20707: #
                   20708: #      COMMON EXIT POINT AFTER SUCCESSFUL CONSTRUCTION
                   20709: #
                   20710: pats1: jsb     pbild           # call routine to build node
                   20711:        addl3   $4*1,patst_s,r11        # return to patst caller
                   20712:        jmp     (r11)
                   20713:        #page   
                   20714: #
                   20715: #      PATST (CONTINUED)
                   20716: #
                   20717: #      HERE FOR MULTI-CHARACTER STRING CASE
                   20718: #
                   20719: pats2: movl    r10,-(sp)       # save multi-char pcode
                   20720:        movl    r9,-(sp)        # save string pointer
                   20721:        movl    ctmsk,r8        # load current mask bit
                   20722:        ashl    $1,r8,r8                # shift to next position
                   20723:        tstl    r8              # skip if position left in this tbl
                   20724:        bnequ   pats4
                   20725: #
                   20726: #      HERE WE MUST ALLOCATE A NEW CHARACTER TABLE
                   20727: #
                   20728:        movl    $4*ctsi$,r6     # set size of ctblk
                   20729:        jsb     alloc           # allocate ctblk
                   20730:        movl    r9,r$ctp        # store ptr to new ctblk
                   20731:        movl    $b$ctt,(r9)+    # store type code, bump ptr
                   20732:        movl    $cfp$a,r7       # set number of words to clear
                   20733:        movl    bits0,r8        # load all zero bits
                   20734: #
                   20735: #      LOOP TO CLEAR ALL BITS IN TABLE TO ZEROS
                   20736: #
                   20737: pats3: movl    r8,(r9)+        # move word of zero bits
                   20738:        sobgtr  r7,pats3        # loop till all cleared
                   20739:        movl    bits1,r8        # set initial bit position
                   20740: #
                   20741: #      MERGE HERE WITH BIT POSITION AVAILABLE
                   20742: #
                   20743: pats4: movl    r8,ctmsk        # save parm2 (new bit position)
                   20744:        movl    (sp)+,r10       # restore pointer to argument string
                   20745:        movl    4*sclen(r10),r7 # load string length
                   20746:        tstl    r7              # jump if null string case
                   20747:        beqlu   pats6
                   20748:                                # else set loop counter
                   20749:        movab   cfp$f(r10),r10  # point to characters in argument
                   20750:        #page   
                   20751: #
                   20752: #      PATST (CONTINUED)
                   20753: #
                   20754: #      LOOP TO SET BITS IN COLUMN OF TABLE
                   20755: #
                   20756: pats5: movzbl  (r10)+,r6       # load next character
                   20757:        moval   0[r6],r6        # convert to byte offset
                   20758:        movl    r$ctp,r9        # point to ctblk
                   20759:        addl2   r6,r9           # point to ctblk entry
                   20760:        movl    r8,r6           # copy bit mask
                   20761:        bisl2   4*ctchs(r9),r6  # or in bits already set
                   20762:        movl    r6,4*ctchs(r9)  # store resulting bit string
                   20763:        sobgtr  r7,pats5        # loop till all bits set
                   20764: #
                   20765: #      COMPLETE PROCESSING FOR MUTI-CHAR STRING CASE
                   20766: #
                   20767: pats6: movl    r$ctp,r9        # load ctblk ptr as parm1 for pbild
                   20768:        clrl    r10             # clear garbage ptr in xl
                   20769:        movl    (sp)+,r7        # load pcode for multi-char str case
                   20770:        jmp     pats1           # back to exit (wc=bitstring=parm2)
                   20771: #
                   20772: #      HERE IF ARGUMENT IS NOT A STRING
                   20773: #
                   20774: #      NOTE THAT THE CALL FROM EVALS CANNOT PASS AN EXPRESSION
                   20775: #      SINCE EVALP ALWAYS REEVALUATES EXPRESSIONS.
                   20776: #
                   20777: pats7: movl    r8,r7           # set pcode for expression argument
                   20778:        cmpl    (r9),$b$e$$     # jump to exit if expression arg
                   20779:        bgtru   0f
                   20780:        jmp     pats1
                   20781: 0:             
                   20782:        movl    patst_s,r11     # else take wrong type error exit
                   20783:        jmp     *(r11)+
                   20784:        #enp                    # end procedure patst
                   20785:        #page   
                   20786: #
                   20787: #      PBILD -- BUILD PATTERN NODE
                   20788: #
                   20789: #      (XR)                  PARM1 (ONLY IF REQUIRED)
                   20790: #      (WB)                  PCODE FOR NODE
                   20791: #      (WC)                  PARM2 (ONLY IF REQUIRED)
                   20792: #      JSR  PBILD            CALL TO BUILD NODE
                   20793: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20794: #      (WA)                  DESTROYED
                   20795: #
                   20796: pbild: #prc                    # entry point
                   20797:        movl    r9,-(sp)        # stack possible parm1
                   20798:        movl    r7,r9           # copy pcode
                   20799:        movzwl  -2(r9),r9       # load entry point id (bl$px)
                   20800:        cmpl    r9,$bl$p1       # jump if one parameter
                   20801:        beqlu   pbld1
                   20802:        cmpl    r9,$bl$p0       # jump if no parameters
                   20803:        beqlu   pbld3
                   20804: #
                   20805: #      HERE FOR TWO PARAMETER CASE
                   20806: #
                   20807:        movl    $4*pcsi$,r6     # set size of p2blk
                   20808:        jsb     alloc           # allocate block
                   20809:        movl    r8,4*parm2(r9)  # store second parameter
                   20810:        jmp     pbld2           # merge with one parm case
                   20811: #
                   20812: #      HERE FOR ONE PARAMETER CASE
                   20813: #
                   20814: pbld1: movl    $4*pbsi$,r6     # set size of p1blk
                   20815:        jsb     alloc           # allocate node
                   20816: #
                   20817: #      MERGE HERE FROM TWO PARM CASE
                   20818: #
                   20819: pbld2: movl    (sp),4*parm1(r9)# store first parameter
                   20820:        jmp     pbld4           # merge with no parameter case
                   20821: #
                   20822: #      HERE FOR CASE OF NO PARAMETERS
                   20823: #
                   20824: pbld3: movl    $4*pasi$,r6     # set size of p0blk
                   20825:        jsb     alloc           # allocate node
                   20826: #
                   20827: #      MERGE HERE FROM OTHER CASES
                   20828: #
                   20829: pbld4: movl    r7,(r9)         # store pcode
                   20830:        addl2   $4,sp           # pop first parameter
                   20831:        movl    $ndnth,4*pthen(r9) # set nothen successor pointer
                   20832:        rsb                     # return to pbild caller
                   20833:        #enp                    # end procedure pbild
                   20834:        #page   
                   20835: #
                   20836: #      PCONC -- CONCATENATE TWO PATTERNS
                   20837: #
                   20838: #      (XL)                  PTR TO RIGHT PATTERN
                   20839: #      (XR)                  PTR TO LEFT PATTERN
                   20840: #      JSR  PCONC            CALL TO CONCATENATE PATTERNS
                   20841: #      (XR)                  PTR TO CONCATENATED PATTERN
                   20842: #      (XL,WA,WB,WC)         DESTROYED
                   20843: #
                   20844: #
                   20845: #      TO CONCATENATE TWO PATTERNS, ALL SUCCESSORS IN THE LEFT
                   20846: #      PATTERN WHICH POINT TO THE NOTHEN NODE MUST BE CHANGED TO
                   20847: #      POINT TO THE RIGHT PATTERN. HOWEVER, THIS MODIFICATION
                   20848: #      MUST BE PERFORMED ON A COPY OF THE LEFT ARGUMENT RATHER
                   20849: #      THAN THE LEFT ARGUMENT ITSELF, SINCE THE LEFT ARGUMENT
                   20850: #      MAY BE POINTED TO BY SOME OTHER VARIABLE VALUE.
                   20851: #
                   20852: #      ACCORDINGLY, IT IS NECESSARY TO COPY THE LEFT ARGUMENT.
                   20853: #      THIS IS NOT A TRIVIAL PROCESS SINCE WE MUST AVOID COPYING
                   20854: #      NODES MORE THAN ONCE AND THE PATTERN IS A GRAPH STRUCTURE
                   20855: #      THE FOLLOWING ALGORITHM IS EMPLOYED.
                   20856: #
                   20857: #      THE STACK IS USED TO STORE A LIST OF NODES WHICH
                   20858: #      HAVE ALREADY BEEN COPIED. THE FORMAT OF THE ENTRIES ON
                   20859: #      THIS LIST CONSISTS OF A TWO WORD BLOCK. THE FIRST WORD
                   20860: #      IS THE OLD ADDRESS AND THE SECOND WORD IS THE ADDRESS
                   20861: #      OF THE COPY. THIS LIST IS SEARCHED BY THE PCOPY
                   20862: #      ROUTINE TO AVOID MAKING DUPLICATE COPIES. A TRICK IS
                   20863: #      USED TO ACCOMPLISH THE CONCATENATION AT THE SAME TIME.
                   20864: #      A SPECIAL ENTRY IS MADE TO START WITH ON THE STACK. THIS
                   20865: #      ENTRY RECORDS THAT THE NOTHEN NODE HAS BEEN COPIED
                   20866: #      ALREADY AND THE ADDRESS OF ITS COPY IS THE RIGHT PATTERN.
                   20867: #      THIS AUTOMATICALLY PERFORMS THE CORRECT REPLACEMENTS.
                   20868: #
                   20869: pconc: #prc                    # entry point
                   20870:        clrl    -(sp)           # make room for one entry at bottom
                   20871:        movl    sp,r8           # store pointer to start of list
                   20872:        movl    $ndnth,-(sp)    # stack nothen node as old node
                   20873:        movl    r10,-(sp)       # store right arg as copy of nothen
                   20874:        movl    sp,r10          # initialize pointer to stack entries
                   20875:        jsb     pcopy           # copy first node of left arg
                   20876:        movl    r6,4*2(r10)     # store as result under list
                   20877:        #page   
                   20878: #
                   20879: #      PCONC (CONTINUED)
                   20880: #
                   20881: #      THE FOLLOWING LOOP SCANS ENTRIES IN THE LIST AND MAKES
                   20882: #      SURE THAT THEIR SUCCESSORS HAVE BEEN COPIED.
                   20883: #
                   20884: pcnc1: cmpl    r10,sp          # jump if all entries processed
                   20885:        beqlu   pcnc2
                   20886:        movl    -(r10),r9       # else load next old address
                   20887:        movl    4*pthen(r9),r9  # load pointer to successor
                   20888:        jsb     pcopy           # copy successor node
                   20889:        movl    -(r10),r9       # load pointer to new node (copy)
                   20890:        movl    r6,4*pthen(r9)  # store ptr to new successor
                   20891: #
                   20892: #      NOW CHECK FOR SPECIAL CASE OF ALTERNATION NODE WHERE
                   20893: #      PARM1 POINTS TO A NODE AND MUST BE COPIED LIKE PTHEN.
                   20894: #
                   20895:        cmpl    (r9),$p$alt     # loop back if not
                   20896:        bnequ   pcnc1
                   20897:        movl    4*parm1(r9),r9  # else load pointer to alternative
                   20898:        jsb     pcopy           # copy it
                   20899:        movl    (r10),r9        # restore ptr to new node
                   20900:        movl    r6,4*parm1(r9)  # store ptr to copied alternative
                   20901:        jmp     pcnc1           # loop back for next entry
                   20902: #
                   20903: #      HERE AT END OF COPY PROCESS
                   20904: #
                   20905: pcnc2: movl    r8,sp           # restore stack pointer
                   20906:        movl    (sp)+,r9        # load pointer to copy
                   20907:        rsb                     # return to pconc caller
                   20908:        #enp                    # end procedure pconc
                   20909:        #page   
                   20910: #
                   20911: #      PCOPY -- COPY A PATTERN NODE
                   20912: #
                   20913: #      PCOPY IS CALLED FROM THE PCONC PROCEDURE TO COPY A SINGLE
                   20914: #      PATTERN NODE. THE COPY IS ONLY CARRIED OUT IF THE NODE
                   20915: #      HAS NOT BEEN COPIED ALREADY.
                   20916: #
                   20917: #      (XR)                  POINTER TO NODE TO BE COPIED
                   20918: #      (XT)                  PTR TO CURRENT LOC IN COPY LIST
                   20919: #      (WC)                  POINTER TO LIST OF COPIED NODES
                   20920: #      JSR  PCOPY            CALL TO COPY A NODE
                   20921: #      (WA)                  POINTER TO COPY
                   20922: #      (WB,XR)               DESTROYED
                   20923: #
                   20924:        .data   1
                   20925: pcopy_s:       .long   0
                   20926:        .text   0
                   20927: pcopy: movl    (sp)+,pcopy_s   # entry point
                   20928:        movl    r10,r7          # save xt
                   20929:        movl    r8,r10          # point to start of list
                   20930: #
                   20931: #      LOOP TO SEARCH LIST OF NODES COPIED ALREADY
                   20932: #
                   20933: pcop1: subl2   $4,r10          # point to next entry on list
                   20934:        cmpl    r9,(r10)        # jump if match
                   20935:        beqlu   pcop2
                   20936:        subl2   $4,r10          # else skip over copied address
                   20937:        cmpl    r10,sp          # loop back if more to test
                   20938:        bnequ   pcop1
                   20939: #
                   20940: #      HERE IF NOT IN LIST, PERFORM COPY
                   20941: #
                   20942:        movl    (r9),r6         # load first word of block
                   20943:        jsb     blkln           # get length of block
                   20944:        movl    r9,r10          # save pointer to old node
                   20945:        jsb     alloc           # allocate space for copy
                   20946:        movl    r10,-(sp)       # store old address on list
                   20947:        movl    r9,-(sp)        # store new address on list
                   20948:        jsb     sbchk           # check for stack overflow
                   20949:        jsb     sbmvw           # move words from old block to copy
                   20950:        movl    (sp),r6         # load pointer to copy
                   20951:        jmp     pcop3           # jump to exit
                   20952: #
                   20953: #      HERE IF WE FIND ENTRY IN LIST
                   20954: #
                   20955: pcop2: movl    -(r10),r6       # load address of copy from list
                   20956: #
                   20957: #      COMMON EXIT POINT
                   20958: #
                   20959: pcop3: movl    r7,r10          # restore xt
                   20960:        jmp     *pcopy_s        # return to pcopy caller
                   20961:        #enp                    # end procedure pcopy
                   20962:        #page   
                   20963: #
                   20964: #      PRFLR -- PRINT PROFILE
                   20965: #      PRFLR IS CALLED TO PRINT THE CONTENTS OF THE PROFILE
                   20966: #      TABLE IN A FAIRLY READABLE TABULAR FORMAT.
                   20967: #
                   20968: #      JSR  PRFLR            CALL TO PRINT PROFILE
                   20969: #      (WA,IA)               DESTROYED
                   20970: #
                   20971: prflr: #prc    
                   20972:        tstl    pfdmp           # no printing if no profiling done
                   20973:        bnequ   0f
                   20974:        jmp     prfl4
                   20975: 0:             
                   20976:        movl    r9,-(sp)        # preserve entry xr
                   20977:        movl    r7,pfsvw        # and also wb
                   20978:        jsb     prtpg           # eject
                   20979:        movl    $pfms1,r9       # load msg /program profile/
                   20980:        jsb     prtst           # and print it
                   20981:        jsb     prtnl           # followed by newline
                   20982:        jsb     prtnl           # and another
                   20983:        movl    $pfms2,r9       # point to first hdr
                   20984:        jsb     prtst           # print it
                   20985:        jsb     prtnl           # new line
                   20986:        movl    $pfms3,r9       # second hdr
                   20987:        jsb     prtst           # print it
                   20988:        jsb     prtnl           # new line
                   20989:        jsb     prtnl           # and another blank line
                   20990:        clrl    r7              # initial stmt count
                   20991:        movl    pftbl,r9        # point to table origin
                   20992:        addl2   $4*num02,r9     # bias past xnblk header (sgd07)
                   20993: #
                   20994: #      LOOP HERE TO PRINT SUCCESSIVE ENTRIES
                   20995: #
                   20996: prfl1: incl    r7              # bump stmt nr
                   20997:        movl    (r9),r5         # load nr of executions
                   20998:        tstl    r5              # no printing if zero
                   20999:        beql    prfl3
                   21000:        movl    $pfpd1,profs    # point where to print
                   21001:        jsb     prtin           # and print it
                   21002:        clrl    profs           # back to start of line
                   21003:        movl    r7,r5           # load stmt nr
                   21004:        jsb     prtin           # print it there
                   21005:        movl    $pfpd2,profs    # and pad past count
                   21006:        movl    4*cfp$i(r9),r5  # load total exec time
                   21007:        jsb     prtin           # print that too
                   21008:        movl    4*cfp$i(r9),r5  # reload time
                   21009:        mull2   intth,r5        # convert to microsec
                   21010:        bvs     prfl2
                   21011:        divl2   (r9),r5         # divide by executions
                   21012:        movl    $pfpd3,profs    # pad last print
                   21013:        jsb     prtin           # and print mcsec/execn
                   21014: #
                   21015: #      MERGE AFTER PRINTING TIME
                   21016: #
                   21017: prfl2: jsb     prtnl           # thats another line
                   21018: #
                   21019: #      HERE TO GO TO NEXT ENTRY
                   21020: #
                   21021: prfl3: addl2   $4*pf$i2,r9     # bump index ptr (sgd07)
                   21022:        cmpl    r7,pfnte        # loop if more stmts
                   21023:        blssu   prfl1
                   21024:        movl    (sp)+,r9        # restore callers xr
                   21025:        movl    pfsvw,r7        # and wb too
                   21026: #
                   21027: #      HERE TO EXIT
                   21028: #
                   21029: prfl4: rsb                     # return
                   21030:        #enp                    # end of prflr
                   21031:        #page   
                   21032: #
                   21033: #      PRFLU -- UPDATE AN ENTRY IN THE PROFILE TABLE
                   21034: #
                   21035: #      ON ENTRY, KVSTN CONTAINS NR OF STMT TO PROFILE
                   21036: #
                   21037: #      JSR  PRFLU            CALL TO UPDATE ENTRY
                   21038: #      (IA)                  DESTROYED
                   21039: #
                   21040: prflu: #prc    
                   21041:        tstl    pffnc           # skip if just entered function
                   21042:        beqlu   0f
                   21043:        jmp     pflu4
                   21044: 0:             
                   21045:        movl    r9,-(sp)        # preserve entry xr
                   21046:        movl    r6,pfsvw        # save wa (sgd07)
                   21047:        tstl    pftbl           # branch if table allocated
                   21048:        bnequ   pflu2
                   21049: #
                   21050: #      HERE IF SPACE FOR PROFILE TABLE NOT YET ALLOCATED.
                   21051: #      CALCULATE SIZE NEEDED, ALLOCATE A STATIC XNBLK, AND
                   21052: #      INITIALIZE IT ALL TO ZERO.
                   21053: #      THE TIME TAKEN FOR THIS WILL BE ATTRIBUTED TO THE CURRENT
                   21054: #      STATEMENT (ASSIGNMENT TO KEYWD PROFILE), BUT SINCE THE
                   21055: #      TIMING FOR THIS STATEMENT IS UP THE POLE ANYWAY, THIS
                   21056: #      DOESNT REALLY MATTER...
                   21057: #
                   21058:        subl2   $num01,pfnte    # adjust for extra count (sgd07)
                   21059:        movl    pfi2a,r5        # convrt entry size to int
                   21060:        movl    r5,pfste        # and store safely for later
                   21061:        movl    pfnte,r5        # load table length as integer
                   21062:        mull2   pfste,r5        # multiply by entry size
                   21063:        movl    r5,r6           # get back address-style
                   21064:        addl2   $num02,r6       # add on 2 word overhead
                   21065:        moval   0[r6],r6        # convert the whole lot to bytes
                   21066:        jsb     alost           # gimme the space
                   21067:        movl    r9,pftbl        # save block pointer
                   21068:        movl    $b$xnt,(r9)+    # put block type and ...
                   21069:        movl    r6,(r9)+        # ... length into header
                   21070:        movl    r5,r6           # get back nr of wds in data area
                   21071:                                # load the counter
                   21072: #
                   21073: #      LOOP HERE TO ZERO THE BLOCK DATA
                   21074: #
                   21075: pflu1: clrl    (r9)+           # blank a word
                   21076:        sobgtr  r6,pflu1        # and alllllll the rest
                   21077: #
                   21078: #      END OF ALLOCATION. MERGE BACK INTO ROUTINE
                   21079: #
                   21080: pflu2: movl    kvstn,r5        # load nr of stmt just ended
                   21081:        subl2   intv1,r5        # make into index offset
                   21082:        mull2   pfste,r5        # make offset of table entry
                   21083:        movl    r5,r6           # convert to address
                   21084:        moval   0[r6],r6        # get as baus
                   21085:        addl2   $4*num02,r6     # offset includes table header
                   21086:        movl    pftbl,r9        # get table start
                   21087:        cmpl    r6,4*num01(r9)  # if out of table, skip it
                   21088:        bgequ   pflu3
                   21089:        addl2   r6,r9           # else point to entry
                   21090:        movl    (r9),r5         # get nr of executions so far
                   21091:        addl2   intv1,r5        # nudge up one
                   21092:        movl    r5,(r9)         # and put back
                   21093:        jsb     systm           # get time now
                   21094:        movl    r5,pfetm        # stash ending time
                   21095:        subl2   pfstm,r5        # subtract start time
                   21096:        addl2   4*cfp$i(r9),r5  # add cumulative time so far
                   21097:        movl    r5,4*cfp$i(r9)  # and put back new total
                   21098:        movl    pfetm,r5        # load end time of this stmt ...
                   21099:        movl    r5,pfstm        # ... which is start time of next
                   21100: #
                   21101: #      MERGE HERE TO EXIT
                   21102: #
                   21103: pflu3: movl    (sp)+,r9        # restore callers xr
                   21104:        movl    pfsvw,r6        # restore saved reg
                   21105:        rsb                     # and return
                   21106: #
                   21107: #      HERE IF PROFILE IS SUPPRESSED BECAUSE A PROGRAM DEFINED
                   21108: #      FUNCTION IS ABOUT TO BE ENTERED, AND SO THE CURRENT STMT
                   21109: #      HAS NOT YET FINISHED
                   21110: #
                   21111: pflu4: clrl    pffnc           # reset the condition flag
                   21112:        rsb                     # and immediate return
                   21113:        #enp                    # end of procedure prflu
                   21114:        #page   
                   21115: #
                   21116: #      PRPAR - PROCESS PRINT PARAMETERS
                   21117: #
                   21118: #      (WC)                  IF NONZERO ASSOCIATE TERMINAL ONLY
                   21119: #      JSR  PRPAR            CALL TO PROCESS PRINT PARAMETERS
                   21120: #      (XL,XR,WA,WB,WC)      DESTROYED
                   21121: #
                   21122: #      SINCE MEMORY ALLOCATION IS UNDECIDED ON INITIAL CALL,
                   21123: #      TERMINAL CANNOT BE ASSOCIATED. THE ENTRY WITH WC NON-ZERO
                   21124: #      IS PROVIDED SO A LATER CALL CAN BE MADE TO COMPLETE THIS.
                   21125: #
                   21126: prpar: #prc                    # entry point
                   21127:        tstl    r8              # jump to associate terminal
                   21128:        beqlu   0f
                   21129:        jmp     prpa7
                   21130: 0:             
                   21131:        jsb     syspp           # get print parameters
                   21132:        tstl    r7              # jump if lines/page specified
                   21133:        bnequ   prpa1
                   21134:        movl    $cfp$m,r7       # else use a large value
                   21135:        ashl    $-1,r7,r7       # but not too large
                   21136: #
                   21137: #      STORE LINE COUNT/PAGE
                   21138: #
                   21139: prpa1: movl    r7,lstnp        # store number of lines/page
                   21140:        movl    r7,lstlc        # pretend page is full initially
                   21141:        clrl    lstpg           # clear page number
                   21142:        movl    prlen,r7        # get prior length if any
                   21143:        tstl    r7              # skip if no length
                   21144:        beqlu   prpa2
                   21145:        cmpl    r6,r7           # skip storing if too big
                   21146:        bgtru   prpa3
                   21147: #
                   21148: #      STORE PRINT BUFFER LENGTH
                   21149: #
                   21150: prpa2: movl    r6,prlen        # store value
                   21151: #
                   21152: #      PROCESS BITS OPTIONS
                   21153: #
                   21154: prpa3: movl    bits3,r7        # bit 3 mask
                   21155:        mcoml   r8,r11          # get -nolist bit
                   21156:        bicl2   r11,r7
                   21157:        tstl    r7              # skip if clear
                   21158:        beqlu   prpa4
                   21159:        clrl    cswls           # set -nolist
                   21160: #
                   21161: #      CHECK IF FAIL REPORTS GOTO INTERACTIVE CHANNEL
                   21162: #
                   21163: prpa4: movl    bits1,r7        # bit 1 mask
                   21164:        mcoml   r8,r11          # get bit
                   21165:        bicl2   r11,r7
                   21166:        movl    r7,erich        # store int. chan. error flag
                   21167:        movl    bits2,r7        # bit 2 mask
                   21168:        mcoml   r8,r11          # get bit
                   21169:        bicl2   r11,r7
                   21170:        movl    r7,prich        # flag for std printer on int. chan.
                   21171:        movl    bits4,r7        # bit 4 mask
                   21172:        mcoml   r8,r11          # get bit
                   21173:        bicl2   r11,r7
                   21174:        movl    r7,cpsts        # flag for compile stats suppressn.
                   21175:        movl    bits5,r7        # bit 5 mask
                   21176:        mcoml   r8,r11          # get bit
                   21177:        bicl2   r11,r7
                   21178:        movl    r7,exsts        # flag for exec stats suppression
                   21179:        #page   
                   21180: #
                   21181: #      PRPAR (CONTINUED)
                   21182: #
                   21183:        movl    bits6,r7        # bit 6 mask
                   21184:        mcoml   r8,r11          # get bit
                   21185:        bicl2   r11,r7
                   21186:        movl    r7,precl        # extended/compact listing flag
                   21187:        subl2   $num08,r6       # point 8 chars from line end
                   21188:        tstl    r7              # jump if not extended
                   21189:        beqlu   prpa5
                   21190:        movl    r6,lstpo        # store for listing page headings
                   21191: #
                   21192: #       CONTINUE OPTION PROCESSING
                   21193: #
                   21194: prpa5: movl    bits7,r7        # bit 7 mask
                   21195:        mcoml   r8,r11          # get bit 7
                   21196:        bicl2   r11,r7
                   21197:        movl    r7,cswex        # set -noexecute if non-zero
                   21198:        movl    bit10,r7        # bit 10 mask
                   21199:        mcoml   r8,r11          # get bit 10
                   21200:        bicl2   r11,r7
                   21201:        movl    r7,headp        # pretend printed to omit headers
                   21202:        movl    bits9,r7        # bit 9 mask
                   21203:        mcoml   r8,r11          # get bit 9
                   21204:        bicl2   r11,r7
                   21205:        movl    r7,prsto        # keep it as std listing option
                   21206:        tstl    r7              # skip if clear
                   21207:        beqlu   prpa6
                   21208:        movl    prlen,r6        # get print buffer length
                   21209:        subl2   $num08,r6       # point 8 chars from line end
                   21210:        movl    r6,lstpo        # store page offset
                   21211: #
                   21212: #      CHECK FOR TERMINAL
                   21213: #
                   21214: prpa6: mcoml   bits8,r11       # see if terminal to be activated
                   21215:        bicl2   r11,r8
                   21216:        tstl    r8              # jump if terminal required
                   21217:        beqlu   0f
                   21218:        jmp     prpa7
                   21219: 0:             
                   21220:        tstl    initr           # jump if no terminal to detach
                   21221:        beqlu   prpa8
                   21222:        movl    $v$ter,r10      # ptr to /terminal/
                   21223:        jsb     gtnvr           # get vrblk pointer
                   21224:        .long   invalid$        # cant fail
                   21225:        movl    $nulls,4*vrval(r9) # clear value of terminal
                   21226:        jsb     setvr           # remove association
                   21227:        jmp     prpa8           # return
                   21228: #
                   21229: #      ASSOCIATE TERMINAL
                   21230: #
                   21231: prpa7: movl    sp,initr        # note terminal associated
                   21232:        tstl    dnamb           # cant if memory not organised
                   21233:        beqlu   prpa8
                   21234:        movl    $v$ter,r10      # point to terminal string
                   21235:        movl    $trtou,r7       # output trace type
                   21236:        jsb     inout           # attach output trblk to vrblk
                   21237:        movl    r9,-(sp)        # stack trblk ptr
                   21238:        movl    $v$ter,r10      # point to terminal string
                   21239:        movl    $trtin,r7       # input trace type
                   21240:        jsb     inout           # attach input trace blk
                   21241:        movl    (sp)+,4*vrval(r9)# add output trblk to chain
                   21242: #
                   21243: #      RETURN POINT
                   21244: #
                   21245: prpa8: rsb                     # return
                   21246:        #enp                    # end procedure prpar
                   21247:        #page   
                   21248: #
                   21249: #      PRTCH -- PRINT A CHARACTER
                   21250: #
                   21251: #      PRTCH IS USED TO PRINT A SINGLE CHARACTER
                   21252: #
                   21253: #      (WA)                  CHARACTER TO BE PRINTED
                   21254: #      JSR  PRTCH            CALL TO PRINT CHARACTER
                   21255: #
                   21256: prtch: #prc                    # entry point
                   21257:        movl    r9,-(sp)        # save xr
                   21258:        cmpl    profs,prlen     # jump if room in buffer
                   21259:        bnequ   prch1
                   21260:        jsb     prtnl           # else print this line
                   21261: #
                   21262: #      HERE AFTER MAKING SURE WE HAVE ROOM
                   21263: #
                   21264: prch1: movl    prbuf,r9        # point to print buffer
                   21265:        movl    profs,r11       # [get in scratch register]
                   21266:        movab   cfp$f(r9)[r11],r9# point to next character location
                   21267:        movb    r6,(r9)         # store new character
                   21268:        #csc    r9              # complete store characters
                   21269:        incl    profs           # bump pointer
                   21270:        movl    (sp)+,r9        # restore entry xr
                   21271:        rsb                     # return to prtch caller
                   21272:        #enp                    # end procedure prtch
                   21273:        #page   
                   21274: #
                   21275: #      PRTIC -- PRINT TO INTERACTIVE CHANNEL
                   21276: #
                   21277: #      PRTIC IS CALLED TO PRINT THE CONTENTS OF THE STANDARD
                   21278: #      PRINT BUFFER TO THE INTERACTIVE CHANNEL. IT IS ONLY
                   21279: #      CALLED AFTER PRTST HAS SET UP THE STRING FOR PRINTING.
                   21280: #      IT DOES NOT CLEAR THE BUFFER.
                   21281: #
                   21282: #      JSR  PRTIC            CALL FOR PRINT
                   21283: #      (WA,WB)               DESTROYED
                   21284: #
                   21285: prtic: #prc                    # entry point
                   21286:        movl    r9,-(sp)        # save xr
                   21287:        movl    prbuf,r9        # point to buffer
                   21288:        movl    profs,r6        # no of chars
                   21289:        jsb     syspi           # print
                   21290:        .long   prtc2           # fail return
                   21291: #
                   21292: #      RETURN
                   21293: #
                   21294: prtc1: movl    (sp)+,r9        # restore xr
                   21295:        rsb                     # return
                   21296: #
                   21297: #      ERROR OCCURED
                   21298: #
                   21299: prtc2: clrl    erich           # prevent looping
                   21300:        jmp     er_252          # error on printing to interactive channel
                   21301:        jmp     prtc1           # return
                   21302:        #enp                    # procedure prtic
                   21303:        #page   
                   21304: #
                   21305: #      PRTIS -- PRINT TO INTERACTIVE AND STANDARD PRINTER
                   21306: #
                   21307: #      PRTIS PUTS A LINE FROM THE PRINT BUFFER ONTO THE
                   21308: #      INTERACTIVE CHANNEL (IF ANY) AND THE STANDARD PRINTER.
                   21309: #      IT ALWAYS PRINTS TO THE STANDARD PRINTER BUT DOES
                   21310: #      NOT DUPLICATE LINES IF THE STANDARD PRINTER IS
                   21311: #      INTERACTIVE.  IT CLEARS DOWN THE PRINT BUFFER.
                   21312: #
                   21313: #      JSR  PRTIS            CALL FOR PRINTING
                   21314: #      (WA,WB)               DESTROYED
                   21315: #
                   21316: prtis: #prc                    # entry point
                   21317:        tstl    prich           # jump if standard printer is int.ch.
                   21318:        bnequ   prts1
                   21319:        tstl    erich           # skip if not doing int. error reps.
                   21320:        beqlu   prts1
                   21321:        jsb     prtic           # print to interactive channel
                   21322: #
                   21323: #      MERGE AND EXIT
                   21324: #
                   21325: prts1: jsb     prtnl           # print to standard printer
                   21326:        rsb                     # return
                   21327:        #enp                    # end procedure prtis
                   21328:        #page   
                   21329: #
                   21330: #      PRTIN -- PRINT AN INTEGER
                   21331: #
                   21332: #      PRTIN PRINTS THE INTEGER VALUE WHICH IS IN THE INTEGER
                   21333: #      ACCUMULATOR. BLOCKS BUILT IN DYNAMIC STORAGE
                   21334: #      DURING THIS PROCESS ARE IMMEDIATELY DELETED.
                   21335: #
                   21336: #      (IA)                  INTEGER VALUE TO BE PRINTED
                   21337: #      JSR  PRTIN            CALL TO PRINT INTEGER
                   21338: #      (IA,RA)               DESTROYED
                   21339: #
                   21340: prtin: #prc                    # entry point
                   21341:        movl    r9,-(sp)        # save xr
                   21342:        jsb     icbld           # build integer block
                   21343:        cmpl    r9,dnamb        # jump if icblk below dynamic
                   21344:        blequ   prti1
                   21345:        cmpl    r9,dnamp        # jump if above dynamic
                   21346:        bgequ   prti1
                   21347:        movl    r9,dnamp        # immediately delete it
                   21348: #
                   21349: #      DELETE ICBLK FROM DYNAMIC STORE
                   21350: #
                   21351: prti1: movl    r9,-(sp)        # stack ptr for gtstg
                   21352:        jsb     gtstg           # convert to string
                   21353:        .long   invalid$        # convert error is impossible
                   21354:        movl    r9,dnamp        # reset pointer to delete scblk
                   21355:        jsb     prtst           # print integer string
                   21356:        movl    (sp)+,r9        # restore entry xr
                   21357:        rsb                     # return to prtin caller
                   21358:        #enp                    # end procedure prtin
                   21359:        #page   
                   21360: #
                   21361: #      PRTMI -- PRINT MESSAGE AND INTEGER
                   21362: #
                   21363: #      PRTMI IS USED TO PRINT MESSAGES TOGETHER WITH AN INTEGER
                   21364: #      VALUE STARTING IN COLUMN 15 (USED BY THE ROUTINES AT
                   21365: #      THE END OF COMPILATION).
                   21366: #
                   21367: #      JSR  PRTMI            CALL TO PRINT MESSAGE AND INTEGER
                   21368: #
                   21369: prtmi: #prc                    # entry point
                   21370:        jsb     prtst           # print string message
                   21371:        movl    $prtmf,profs    # set offset to col 15
                   21372:        jsb     prtin           # print integer
                   21373:        jsb     prtnl           # print line
                   21374:        rsb                     # return to prtmi caller
                   21375:        #enp                    # end procedure prtmi
                   21376:        #page   
                   21377: #
                   21378: #      PRTMX  -- AS PRTMI WITH EXTRA COPY TO INTERACTIVE CHAN.
                   21379: #
                   21380: #      JSR  PRTMX            CALL FOR PRINTING
                   21381: #      (WA,WB)               DESTROYED
                   21382: #
                   21383: prtmx: #prc                    # entry point
                   21384:        jsb     prtst           # print string message
                   21385:        movl    $prtmf,profs    # set ptr to column 15
                   21386:        jsb     prtin           # print integer
                   21387:        jsb     prtis           # print line
                   21388:        rsb                     # return
                   21389:        #enp                    # end procedure prtmx
                   21390:        #page   
                   21391: #
                   21392: #      PRTNL -- PRINT NEW LINE (END PRINT LINE)
                   21393: #
                   21394: #      PRTNL PRINTS THE CONTENTS OF THE PRINT BUFFER, RESETS
                   21395: #      THE BUFFER TO ALL BLANKS AND RESETS THE PRINT POINTER.
                   21396: #
                   21397: #      JSR  PRTNL            CALL TO PRINT LINE
                   21398: #
                   21399: prtnl: #prc                    # entry point
                   21400:        tstl    headp           # were headers printed
                   21401:        bnequ   prnl0
                   21402:        jsb     prtps           # no - print them
                   21403: #
                   21404: #      CALL SYSPR
                   21405: #
                   21406: prnl0: movl    r9,-(sp)        # save entry xr
                   21407:        movl    r6,prtsa        # save wa
                   21408:        movl    r7,prtsb        # save wb
                   21409:        movl    prbuf,r9        # load pointer to buffer
                   21410:        movl    profs,r6        # load number of chars in buffer
                   21411:        jsb     syspr           # call system print routine
                   21412:        .long   prnl2           # jump if failed
                   21413:        movl    prlnw,r6        # load length of buffer in words
                   21414:        addl2   $4*schar,r9     # point to chars of buffer
                   21415:        movl    nullw,r7        # get word of blanks
                   21416: #
                   21417: #      LOOP TO BLANK BUFFER
                   21418: #
                   21419: prnl1: movl    r7,(r9)+        # store word of blanks, bump ptr
                   21420:        sobgtr  r6,prnl1        # loop till all blanked
                   21421: #
                   21422: #      EXIT POINT
                   21423: #
                   21424:        movl    prtsb,r7        # restore wb
                   21425:        movl    prtsa,r6        # restore wa
                   21426:        movl    (sp)+,r9        # restore entry xr
                   21427:        clrl    profs           # reset print buffer pointer
                   21428:        rsb                     # return to prtnl caller
                   21429: #
                   21430: #      FILE FULL OR NO OUTPUT FILE FOR LOAD MODULE
                   21431: #
                   21432: prnl2: tstl    prtef           # jump if not first time
                   21433:        bnequ   prnl3
                   21434:        movl    sp,prtef        # mark first occurrence
                   21435:        jmp     er_253          # print limit exceeded on standard output channel
                   21436: #
                   21437: #      STOP AT ONCE
                   21438: #
                   21439: prnl3: movl    $nini8,r7       # ending code
                   21440:        movl    kvstn,r6        # statement number
                   21441:        jsb     sysej           # stop
                   21442:        #enp                    # end procedure prtnl
                   21443:        #page   
                   21444: #
                   21445: #      PRTNM -- PRINT VARIABLE NAME
                   21446: #
                   21447: #      PRTNM IS USED TO PRINT A CHARACTER REPRESENTATION OF THE
                   21448: #      NAME OF A VARIABLE (NOT A VALUE OF DATATYPE NAME)
                   21449: #      NAMES OF PSEUDO-VARIABLES MAY NOT BE PASSED TO PRTNM.
                   21450: #
                   21451: #      (XL)                  NAME BASE
                   21452: #      (WA)                  NAME OFFSET
                   21453: #      JSR  PRTNM            CALL TO PRINT NAME
                   21454: #      (WB,WC,RA)            DESTROYED
                   21455: #
                   21456: prtnm: #prc                    # entry point (recursive, see prtvl)
                   21457:        movl    r6,-(sp)        # save wa (offset is collectable)
                   21458:        movl    r9,-(sp)        # save entry xr
                   21459:        movl    r10,-(sp)       # save name base
                   21460:        cmpl    r10,state       # jump if not natural variable
                   21461:        bgequ   prn02
                   21462: #
                   21463: #      HERE FOR NATURAL VARIABLE NAME, RECOGNIZED BY THE FACT
                   21464: #      THAT THE NAME BASE POINTS INTO THE STATIC AREA.
                   21465: #
                   21466:        movl    r10,r9          # point to vrblk
                   21467:        jsb     prtvn           # print name of variable
                   21468: #
                   21469: #      COMMON EXIT POINT
                   21470: #
                   21471: prn01: movl    (sp)+,r10       # restore name base
                   21472:        movl    (sp)+,r9        # restore entry value of xr
                   21473:        movl    (sp)+,r6        # restore wa
                   21474:        rsb                     # return to prtnm caller
                   21475: #
                   21476: #      HERE FOR CASE OF NON-NATURAL VARIABLE
                   21477: #
                   21478: prn02: movl    r6,r7           # copy name offset
                   21479:        cmpl    (r10),$b$pdt    # jump if array or table
                   21480:        bnequ   prn03
                   21481: #
                   21482: #      FOR PROGRAM DEFINED DATATYPE, PRT FLD NAME, LEFT PAREN
                   21483: #
                   21484:        movl    4*pddfp(r10),r9 # load pointer to dfblk
                   21485:        addl2   r6,r9           # add name offset
                   21486:        movl    4*pdfof(r9),r9  # load vrblk pointer for field
                   21487:        jsb     prtvn           # print field name
                   21488:        movl    $ch$pp,r6       # load left paren
                   21489:        jsb     prtch           # print character
                   21490:        #page   
                   21491: #
                   21492: #      PRTNM (CONTINUED)
                   21493: #
                   21494: #      NOW WE PRINT AN IDENTIFYING NAME FOR THE OBJECT IF ONE
                   21495: #      CAN BE FOUND. THE FOLLOWING CODE SEARCHES FOR A NATURAL
                   21496: #      VARIABLE WHICH CONTAINS THIS OBJECT AS VALUE. IF SUCH A
                   21497: #      VARIABLE IS FOUND, ITS NAME IS PRINTED, ELSE THE VALUE
                   21498: #      OF THE OBJECT (AS PRINTED BY PRTVL) IS USED INSTEAD.
                   21499: #
                   21500: #      FIRST WE POINT TO THE PARENT TBBLK IF THIS IS THE CASE OF
                   21501: #      A TABLE ELEMENT. TO DO THIS, CHASE DOWN THE TRNXT CHAIN.
                   21502: #
                   21503: prn03: cmpl    (r10),$b$tet    # jump if we got there (or not te)
                   21504:        bnequ   prn04
                   21505:        movl    4*tenxt(r10),r10# else move out on chain
                   21506:        jmp     prn03           # and loop back
                   21507: #
                   21508: #      NOW WE ARE READY FOR THE SEARCH. TO SPEED THINGS UP IN
                   21509: #      THE CASE OF CALLS FROM DUMP WHERE THE SAME NAME BASE
                   21510: #      WILL OCCUR REPEATEDLY WHILE DUMPING AN ARRAY OR TABLE,
                   21511: #      WE REMEMBER THE LAST VRBLK POINTER FOUND IN PRNMV. SO
                   21512: #      FIRST CHECK TO SEE IF WE HAVE THIS ONE AGAIN.
                   21513: #
                   21514: prn04: movl    prnmv,r9        # point to vrblk we found last time
                   21515:        movl    hshtb,r6        # point to hash table in case not
                   21516:        jmp     prn07           # jump into search for special check
                   21517: #
                   21518: #      LOOP THROUGH HASH SLOTS
                   21519: #
                   21520: prn05: movl    r6,r9           # copy slot pointer
                   21521:        addl2   $4,r6           # bump slot pointer
                   21522:        subl2   $4*vrnxt,r9     # introduce standard vrblk offset
                   21523: #
                   21524: #      LOOP THROUGH VRBLKS ON ONE HASH CHAIN
                   21525: #
                   21526: prn06: movl    4*vrnxt(r9),r9  # point to next vrblk on hash chain
                   21527: #
                   21528: #      MERGE HERE FIRST TIME TO CHECK BLOCK WE FOUND LAST TIME
                   21529: #
                   21530: prn07: movl    r9,r8           # copy vrblk pointer
                   21531:        tstl    r8              # jump if chain end (or prnmv zero)
                   21532:        beqlu   prn09
                   21533:        #page   
                   21534: #
                   21535: #      PRTNM (CONTINUED)
                   21536: #
                   21537: #      LOOP TO FIND VALUE (CHASE DOWN POSSIBLE TRBLK CHAIN)
                   21538: #
                   21539: prn08: movl    4*vrval(r9),r9  # load value
                   21540:        cmpl    (r9),$b$trt     # loop if that was a trblk
                   21541:        beqlu   prn08
                   21542: #
                   21543: #      NOW WE HAVE THE VALUE, IS THIS THE BLOCK WE WANT
                   21544: #
                   21545:        cmpl    r9,r10          # jump if this matches the name base
                   21546:        beqlu   prn10
                   21547:        movl    r8,r9           # else point back to that vrblk
                   21548:        jmp     prn06           # and loop back
                   21549: #
                   21550: #      HERE TO MOVE TO NEXT HASH SLOT
                   21551: #
                   21552: prn09: cmpl    r6,hshte        # loop back if more to go
                   21553:        blssu   prn05
                   21554:        movl    r10,r9          # else not found, copy value pointer
                   21555:        jsb     prtvl           # print value
                   21556:        jmp     prn11           # and merge ahead
                   21557: #
                   21558: #      HERE WHEN WE FIND A MATCHING ENTRY
                   21559: #
                   21560: prn10: movl    r8,r9           # copy vrblk pointer
                   21561:        movl    r9,prnmv        # save for next time in
                   21562:        jsb     prtvn           # print variable name
                   21563: #
                   21564: #      MERGE HERE IF NO ENTRY FOUND
                   21565: #
                   21566: prn11: movl    (r10),r8        # load first word of name base
                   21567:        cmpl    r8,$b$pdt       # jump if not program defined
                   21568:        bnequ   prn13
                   21569: #
                   21570: #      FOR PROGRAM DEFINED DATATYPE, ADD RIGHT PAREN AND EXIT
                   21571: #
                   21572:        movl    $ch$rp,r6       # load right paren, merge
                   21573: #
                   21574: #      MERGE HERE TO PRINT FINAL RIGHT PAREN OR BRACKET
                   21575: #
                   21576: prn12: jsb     prtch           # print final character
                   21577:        movl    r7,r6           # restore name offset
                   21578:        jmp     prn01           # merge back to exit
                   21579:        #page   
                   21580: #
                   21581: #      PRTNM (CONTINUED)
                   21582: #
                   21583: #      HERE FOR ARRAY OR TABLE
                   21584: #
                   21585: prn13: movl    $ch$bb,r6       # load left bracket
                   21586:        jsb     prtch           # and print it
                   21587:        movl    (sp),r10        # restore block pointer
                   21588:        movl    (r10),r8        # load type word again
                   21589:        cmpl    r8,$b$tet       # jump if not table
                   21590:        bnequ   prn15
                   21591: #
                   21592: #      HERE FOR TABLE, PRINT SUBSCRIPT VALUE
                   21593: #
                   21594:        movl    4*tesub(r10),r9 # load subscript value
                   21595:        movl    r7,r10          # save name offset
                   21596:        jsb     prtvl           # print subscript value
                   21597:        movl    r10,r7          # restore name offset
                   21598: #
                   21599: #      MERGE HERE FROM ARRAY CASE TO PRINT RIGHT BRACKET
                   21600: #
                   21601: prn14: movl    $ch$rb,r6       # load right bracket
                   21602:        jmp     prn12           # merge back to print it
                   21603: #
                   21604: #      HERE FOR ARRAY OR VECTOR, TO PRINT SUBSCRIPT(S)
                   21605: #
                   21606: prn15: movl    r7,r6           # copy name offset
                   21607:        ashl    $-2,r6,r6       # convert to words
                   21608:        cmpl    r8,$b$art       # jump if arblk
                   21609:        beqlu   prn16
                   21610: #
                   21611: #      HERE FOR VECTOR
                   21612: #
                   21613:        subl2   $vcvlb,r6       # adjust for standard fields
                   21614:        movl    r6,r5           # move to integer accum
                   21615:        jsb     prtin           # print linear subscript
                   21616:        jmp     prn14           # merge back for right bracket
                   21617:        #page   
                   21618: #
                   21619: #      PRTNM (CONTINUED)
                   21620: #
                   21621: #      HERE FOR ARRAY. FIRST CALCULATE ABSOLUTE SUBSCRIPT
                   21622: #      OFFSETS BY SUCCESSIVE DIVISIONS BY THE DIMENSION VALUES.
                   21623: #      THIS MUST BE DONE RIGHT TO LEFT SINCE THE ELEMENTS ARE
                   21624: #      STORED ROW-WISE. THE SUBSCRIPTS ARE STACKED AS INTEGERS.
                   21625: #
                   21626: prn16: movl    4*arofs(r10),r8 # load length of bounds info
                   21627:        addl2   $4,r8           # adjust for arpro field
                   21628:        ashl    $-2,r8,r8       # convert to words
                   21629:        subl2   r8,r6           # get linear zero-origin subscript
                   21630:        movl    r6,r5           # get integer value
                   21631:        movl    4*arndm(r10),r6 # set num of dimensions as loop count
                   21632:        addl2   4*arofs(r10),r10# point past bounds information
                   21633:        subl2   $4*arlbd,r10    # set ok offset for proper ptr later
                   21634: #
                   21635: #      LOOP TO STACK SUBSCRIPT OFFSETS
                   21636: #
                   21637: prn17: subl2   $4*ardms,r10    # point to next set of bounds
                   21638:        movl    r5,prnsi        # save current offset
                   21639:        ashq    $-32,r4,r4      # get remainder on dividing by dimens
                   21640:        ediv    4*ardim(r10),r4,r11,r5
                   21641:        movl    r5,-(sp)        # store on stack (one word)
                   21642:        movl    prnsi,r5        # reload argument
                   21643:        divl2   4*ardim(r10),r5 # divide to get quotient
                   21644:        sobgtr  r6,prn17        # loop till all stacked
                   21645:        clrl    r9              # set offset to first set of bounds
                   21646:        movl    4*arndm(r10),r7 # load count of dims to control loop
                   21647:        jmp     prn19           # jump into print loop
                   21648: #
                   21649: #      LOOP TO PRINT SUBSCRIPTS FROM STACK ADJUSTING BY ADDING
                   21650: #      THE APPROPRIATE LOW BOUND VALUE FROM THE ARBLK
                   21651: #
                   21652: prn18: movl    $ch$cm,r6       # load a comma
                   21653:        jsb     prtch           # print it
                   21654: #
                   21655: #      MERGE HERE FIRST TIME IN (NO COMMA REQUIRED)
                   21656: #
                   21657: prn19: movl    (sp)+,r5        # load subscript offset as integer
                   21658:        addl2   r9,r10          # point to current lbd
                   21659:        addl2   4*arlbd(r10),r5 # add lbd to get signed subscript
                   21660:        subl2   r9,r10          # point back to start of arblk
                   21661:        jsb     prtin           # print subscript
                   21662:        addl2   $4*ardms,r9     # bump offset to next bounds
                   21663:        sobgtr  r7,prn18        # loop back till all printed
                   21664:        jmp     prn14           # merge back to print right bracket
                   21665:        #enp                    # end procedure prtnm
                   21666:        #page   
                   21667: #
                   21668: #      PRTNV -- PRINT NAME VALUE
                   21669: #
                   21670: #      PRTNV IS USED BY THE TRACE AND DUMP ROUTINES TO PRINT
                   21671: #      A LINE OF THE FORM
                   21672: #
                   21673: #      NAME = VALUE
                   21674: #
                   21675: #      NOTE THAT THE NAME INVOLVED CAN NEVER BE A PSEUDO-VAR
                   21676: #
                   21677: #      (XL)                  NAME BASE
                   21678: #      (WA)                  NAME OFFSET
                   21679: #      JSR  PRTNV            CALL TO PRINT NAME = VALUE
                   21680: #      (WB,WC,RA)            DESTROYED
                   21681: #
                   21682: prtnv: #prc                    # entry point
                   21683:        jsb     prtnm           # print argument name
                   21684:        movl    r9,-(sp)        # save entry xr
                   21685:        movl    r6,-(sp)        # save name offset (collectable)
                   21686:        movl    $tmbeb,r9       # point to blank equal blank
                   21687:        jsb     prtst           # print it
                   21688:        movl    r10,r9          # copy name base
                   21689:        addl2   r6,r9           # point to value
                   21690:        movl    (r9),r9         # load value pointer
                   21691:        jsb     prtvl           # print value
                   21692:        jsb     prtnl           # terminate line
                   21693:        movl    (sp)+,r6        # restore name offset
                   21694:        movl    (sp)+,r9        # restore entry xr
                   21695:        rsb                     # return to caller
                   21696:        #enp                    # end procedure prtnv
                   21697:        #page   
                   21698: #
                   21699: #      PRTPG  -- PRINT A PAGE THROW
                   21700: #
                   21701: #      PRINTS A PAGE THROW OR A FEW BLANK LINES ON THE STANDARD
                   21702: #      LISTING CHANNEL DEPENDING ON THE LISTING OPTIONS CHOSEN.
                   21703: #
                   21704: #      JSR  PRTPG            CALL FOR PAGE EJECT
                   21705: #
                   21706: prtpg: #prc                    # entry point
                   21707:        cmpl    stage,$stgxt    # jump if execution time
                   21708:        beqlu   prp01
                   21709:        tstl    lstlc           # return if top of page already
                   21710:        bnequ   0f
                   21711:        jmp     prp06
                   21712: 0:             
                   21713:        clrl    lstlc           # clear line count
                   21714: #
                   21715: #      CHECK TYPE OF LISTING
                   21716: #
                   21717: prp01: movl    r9,-(sp)        # preserve xr
                   21718:        tstl    prstd           # eject if flag set
                   21719:        bnequ   prp02
                   21720:        tstl    prich           # jump if interactive listing channel
                   21721:        bnequ   prp03
                   21722:        tstl    precl           # jump if compact listing
                   21723:        beqlu   prp03
                   21724: #
                   21725: #      PERFORM AN EJECT
                   21726: #
                   21727: prp02: jsb     sysep           # eject
                   21728:        jmp     prp04           # merge
                   21729: #
                   21730: #      COMPACT OR INTERACTIVE CHANNEL LISTING. CANT PRINT
                   21731: #      BLANKS UNTIL CHECK MADE FOR HEADERS PRINTED AND FLAG SET.
                   21732: #
                   21733: #
                   21734: prp03: movl    headp,r9        # remember headp
                   21735:        movl    sp,headp        # set to avoid repeated prtpg calls
                   21736:        jsb     prtnl           # print blank line
                   21737:        jsb     prtnl           # print blank line
                   21738:        jsb     prtnl           # print blank line
                   21739:        movl    $num03,lstlc    # count blank lines
                   21740:        movl    r9,headp        # restore header flag
                   21741:        #page   
                   21742: #
                   21743: #      PRPTG (CONTINUED)
                   21744: #
                   21745: #      PRINT THE HEADING
                   21746: #
                   21747: prp04: tstl    headp           # jump if header listed
                   21748:        bnequ   prp05
                   21749:        movl    sp,headp        # mark headers printed
                   21750:        movl    r10,-(sp)       # keep xl
                   21751:        movl    $headr,r9       # point to listing header
                   21752:        jsb     prtst           # place it
                   21753:        jsb     sysid           # get system identification
                   21754:        jsb     prtst           # append extra chars
                   21755:        jsb     prtnl           # print it
                   21756:        movl    r10,r9          # extra header line
                   21757:        jsb     prtst           # place it
                   21758:        jsb     prtnl           # print it
                   21759:        jsb     prtnl           # print a blank
                   21760:        jsb     prtnl           # and another
                   21761:        addl2   $num04,lstlc    # four header lines printed
                   21762:        movl    (sp)+,r10       # restore xl
                   21763: #
                   21764: #      MERGE IF HEADER NOT PRINTED
                   21765: #
                   21766: prp05: movl    (sp)+,r9        # restore xr
                   21767: #
                   21768: #      RETURN
                   21769: #
                   21770: prp06: rsb                     # return
                   21771:        #enp                    # end procedure prtpg
                   21772:        #page   
                   21773: #
                   21774: #      PRTPS - PRINT PAGE WITH TEST FOR STANDARD LISTING OPTION
                   21775: #
                   21776: #      IF THE STANDARD LISTING OPTION IS SELECTED, INSIST THAT
                   21777: #      AN EJECT BE DONE
                   21778: #
                   21779: #      JSR  PRTPS            CALL FOR EJECT
                   21780: #
                   21781: prtps: #prc                    # entry point
                   21782:        movl    prsto,prstd     # copy option flag
                   21783:        jsb     prtpg           # print page
                   21784:        clrl    prstd           # clear flag
                   21785:        rsb                     # return
                   21786:        #enp                    # end procedure prtps
                   21787:        #page   
                   21788: #
                   21789: #      PRTSN -- PRINT STATEMENT NUMBER
                   21790: #
                   21791: #      PRTSN IS USED TO INITIATE A PRINT TRACE LINE BY PRINTING
                   21792: #      ASTERISKS AND THE CURRENT STATEMENT NUMBER. THE ACTUAL
                   21793: #      FORMAT OF THE OUTPUT GENERATED IS.
                   21794: #
                   21795: #      ***NNNNN**** III.....IIII
                   21796: #
                   21797: #      NNNNN IS THE STATEMENT NUMBER WITH LEADING ZEROS REPLACED
                   21798: #      BY ASTERISKS (E.G. *******9****)
                   21799: #
                   21800: #      III...III REPRESENTS A VARIABLE LENGTH OUTPUT CONSISTING
                   21801: #      OF A NUMBER OF LETTER I CHARACTERS EQUAL TO FNCLEVEL.
                   21802: #
                   21803: #      JSR  PRTSN            CALL TO PRINT STATEMENT NUMBER
                   21804: #      (WC)                  DESTROYED
                   21805: #
                   21806: prtsn: #prc                    # entry point
                   21807:        movl    r9,-(sp)        # save entry xr
                   21808:        movl    r6,prsna        # save entry wa
                   21809:        movl    $tmasb,r9       # point to asterisks
                   21810:        jsb     prtst           # print asterisks
                   21811:        movl    $num04,profs    # point into middle of asterisks
                   21812:        movl    kvstn,r5        # load statement number as integer
                   21813:        jsb     prtin           # print integer statement number
                   21814:        movl    $prsnf,profs    # point past asterisks plus blank
                   21815:        movl    kvfnc,r9        # get fnclevel
                   21816:        movl    $ch$li,r6       # set letter i
                   21817: #
                   21818: #      LOOP TO GENERATE LETTER I FNCLEVEL TIMES
                   21819: #
                   21820: prsn1: tstl    r9              # jump if all set
                   21821:        beqlu   prsn2
                   21822:        jsb     prtch           # else print an i
                   21823:        decl    r9              # decrement counter
                   21824:        jmp     prsn1           # loop back
                   21825: #
                   21826: #      MERRE WITH ALL LETTER I CHARACTERS GENERATED
                   21827: #
                   21828: prsn2: movl    $ch$bl,r6       # get blank
                   21829:        jsb     prtch           # print blank
                   21830:        movl    prsna,r6        # restore entry wa
                   21831:        movl    (sp)+,r9        # restore entry xr
                   21832:        rsb                     # return to prtsn caller
                   21833:        #enp                    # end procedure prtsn
                   21834:        #page   
                   21835: #
                   21836: #      PRTST -- PRINT STRING
                   21837: #
                   21838: #      PRTST PLACES A STRING OF CHARACTERS IN THE PRINT BUFFER
                   21839: #
                   21840: #      SEE PRTNL FOR GLOBAL LOCATIONS USED
                   21841: #
                   21842: #      NOTE THAT THE FIRST WORD OF THE BLOCK (NORMALLY B$SCL)
                   21843: #      IS NOT USED AND NEED NOT BE SET CORRECTLY (SEE PRTVN)
                   21844: #
                   21845: #      (XR)                  STRING TO BE PRINTED
                   21846: #      JSR  PRTST            CALL TO PRINT STRING
                   21847: #      (PROFS)               UPDATED PAST CHARS PLACED
                   21848: #
                   21849: prtst: #prc                    # entry point
                   21850:        tstl    headp           # were headers printed
                   21851:        bnequ   prst0
                   21852:        jsb     prtps           # no - print them
                   21853: #
                   21854: #      CALL SYSPR
                   21855: #
                   21856: prst0: movl    r6,prsva        # save wa
                   21857:        movl    r7,prsvb        # save wb
                   21858:        clrl    r7              # set chars printed count to zero
                   21859: #
                   21860: #      LOOP TO PRINT SUCCESSIVE LINES FOR LONG STRING
                   21861: #
                   21862: prst1: movl    4*sclen(r9),r6  # load string length
                   21863:        subl2   r7,r6           # subtract count of chars already out
                   21864:        tstl    r6              # jump to exit if none left
                   21865:        bnequ   0f
                   21866:        jmp     prst4
                   21867: 0:             
                   21868:        movl    r10,-(sp)       # else stack entry xl
                   21869:        movl    r9,-(sp)        # save argument
                   21870:        movl    r9,r10          # copy for eventual move
                   21871:        movl    prlen,r9        # load print buffer length
                   21872:        subl2   profs,r9        # get chars left in print buffer
                   21873:        tstl    r9              # skip if room left on this line
                   21874:        bnequ   prst2
                   21875:        jsb     prtnl           # else print this line
                   21876:        movl    prlen,r9        # and set full width available
                   21877:        #page   
                   21878: #
                   21879: #      PRTST (CONTINUED)
                   21880: #
                   21881: #      HERE WITH CHARS TO PRINT AND SOME ROOM IN BUFFER
                   21882: #
                   21883: prst2: cmpl    r6,r9           # jump if room for rest of string
                   21884:        blequ   prst3
                   21885:        movl    r9,r6           # else set to fill line
                   21886: #
                   21887: #      MERGE HERE WITH CHARACTER COUNT IN WA
                   21888: #
                   21889: prst3: movl    prbuf,r9        # point to print buffer
                   21890:        movab   cfp$f(r10)[r7],r10 # point to location in string
                   21891:        movl    profs,r11       # [get in scratch register]
                   21892:        movab   cfp$f(r9)[r11],r9# point to location in buffer
                   21893:        addl2   r6,r7           # bump string chars count
                   21894:        addl2   r6,profs        # bump buffer pointer
                   21895:        movl    r7,prsvc        # preserve char counter
                   21896:        jsb     sbmvc           # move characters to buffer
                   21897:        movl    prsvc,r7        # recover char counter
                   21898:        movl    (sp)+,r9        # restore argument pointer
                   21899:        movl    (sp)+,r10       # restore entry xl
                   21900:        jmp     prst1           # loop back to test for more
                   21901: #
                   21902: #      HERE TO EXIT AFTER PRINTING STRING
                   21903: #
                   21904: prst4: movl    prsvb,r7        # restore entry wb
                   21905:        movl    prsva,r6        # restore entry wa
                   21906:        rsb                     # return to prtst caller
                   21907:        #enp                    # end procedure prtst
                   21908:        #page   
                   21909: #
                   21910: #      PRTTR -- PRINT TO TERMINAL
                   21911: #
                   21912: #      CALLED TO PRINT CONTENTS OF STANDARD PRINT BUFFER TO
                   21913: #      ONLINE TERMINAL. CLEARS BUFFER DOWN AND RESETS PROFS.
                   21914: #
                   21915: #      JSR  PRTTR            CALL FOR PRINT
                   21916: #      (WA,WB)               DESTROYED
                   21917: #
                   21918: prttr: #prc                    # entry point
                   21919:        movl    r9,-(sp)        # save xr
                   21920:        jsb     prtic           # print buffer contents
                   21921:        movl    prbuf,r9        # point to print bfr to clear it
                   21922:        movl    prlnw,r6        # get buffer length
                   21923:        addl2   $4*schar,r9     # point past scblk header
                   21924:        movl    nullw,r7        # get blanks
                   21925: #
                   21926: #      LOOP TO CLEAR BUFFER
                   21927: #
                   21928: prtt1: movl    r7,(r9)+        # clear a word
                   21929:        sobgtr  r6,prtt1        # loop
                   21930:        clrl    profs           # reset profs
                   21931:        movl    (sp)+,r9        # restore xr
                   21932:        rsb                     # return
                   21933:        #enp                    # end procedure prttr
                   21934:        #page   
                   21935: #
                   21936: #      PRTVL -- PRINT A VALUE
                   21937: #
                   21938: #      PRTVL PLACES AN APPROPRIATE CHARACTER REPRESENTATION OF
                   21939: #      A DATA VALUE IN THE PRINT BUFFER FOR DUMP/TRACE USE.
                   21940: #
                   21941: #      (XR)                  VALUE TO BE PRINTED
                   21942: #      JSR  PRTVL            CALL TO PRINT VALUE
                   21943: #      (WA,WB,WC,RA)         DESTROYED
                   21944: #
                   21945: prtvl: #prc                    # entry point, recursive
                   21946:        movl    r10,-(sp)       # save entry xl
                   21947:        movl    r9,-(sp)        # save argument
                   21948:        jsb     sbchk           # check for stack overflow
                   21949: #
                   21950: #      LOOP BACK HERE AFTER FINDING A TRAP BLOCK (TRBLK)
                   21951: #
                   21952: prv01: movl    4*idval(r9),prvsi# copy idval (if any)
                   21953:        movl    (r9),r10        # load first word of block
                   21954:        movzwl  -2(r10),r10     # load entry point id
                   21955:        casel   r10,$0,$bl$$t   # switch on block type
                   21956: 5:             
                   21957:        .word   prv05-5b        # arblk
                   21958:        .word   prv15-5b        # bcblk
                   21959:        .word   prv02-5b
                   21960:        .word   prv02-5b
                   21961:        .word   prv08-5b        # icblk
                   21962:        .word   prv09-5b        # nmblk
                   21963:        .word   prv02-5b
                   21964:        .word   prv02-5b
                   21965:        .word   prv02-5b
                   21966:        .word   prv08-5b        # rcblk
                   21967:        .word   prv11-5b        # scblk
                   21968:        .word   prv12-5b        # seblk
                   21969:        .word   prv13-5b        # tbblk
                   21970:        .word   prv13-5b        # vcblk
                   21971:        .word   prv02-5b
                   21972:        .word   prv02-5b
                   21973:        .word   prv10-5b        # pdblk
                   21974:        .word   prv04-5b        # trblk
                   21975:        #esw                    # end of switch on block type
                   21976: #
                   21977: #      HERE FOR BLOCKS FOR WHICH WE JUST PRINT DATATYPE NAME
                   21978: #
                   21979: prv02: jsb     dtype           # get datatype name
                   21980:        jsb     prtst           # print datatype name
                   21981: #
                   21982: #      COMMON EXIT POINT
                   21983: #
                   21984: prv03: movl    (sp)+,r9        # reload argument
                   21985:        movl    (sp)+,r10       # restore xl
                   21986:        rsb                     # return to prtvl caller
                   21987: #
                   21988: #      HERE FOR TRBLK
                   21989: #
                   21990: prv04: movl    4*trval(r9),r9  # load real value
                   21991:        jmp     prv01           # and loop back
                   21992:        #page   
                   21993: #
                   21994: #      PRTVL (CONTINUED)
                   21995: #
                   21996: #      HERE FOR ARRAY (ARBLK)
                   21997: #
                   21998: #      PRINT ARRAY ( PROTOTYPE ) BLANK NUMBER IDVAL
                   21999: #
                   22000: prv05: movl    r9,r10          # preserve argument
                   22001:        movl    $scarr,r9       # point to datatype name (array)
                   22002:        jsb     prtst           # print it
                   22003:        movl    $ch$pp,r6       # load left paren
                   22004:        jsb     prtch           # print left paren
                   22005:        addl2   4*arofs(r10),r10# point to prototype
                   22006:        movl    (r10),r9        # load prototype
                   22007:        jsb     prtst           # print prototype
                   22008: #
                   22009: #      VCBLK, TBBLK, BCBLK MERGE HERE FOR ) BLANK NUMBER IDVAL
                   22010: #
                   22011: prv06: movl    $ch$rp,r6       # load right paren
                   22012:        jsb     prtch           # print right paren
                   22013: #
                   22014: #      PDBLK MERGES HERE TO PRINT BLANK NUMBER IDVAL
                   22015: #
                   22016: prv07: movl    $ch$bl,r6       # load blank
                   22017:        jsb     prtch           # print it
                   22018:        movl    $ch$nm,r6       # load number sign
                   22019:        jsb     prtch           # print it
                   22020:        movl    prvsi,r5        # get idval
                   22021:        jsb     prtin           # print id number
                   22022:        jmp     prv03           # back to exit
                   22023: #
                   22024: #      HERE FOR INTEGER (ICBLK), REAL (RCBLK)
                   22025: #
                   22026: #      PRINT CHARACTER REPRESENTATION OF VALUE
                   22027: #
                   22028: prv08: movl    r9,-(sp)        # stack argument for gtstg
                   22029:        jsb     gtstg           # convert to string
                   22030:        .long   invalid$        # error return is impossible
                   22031:        jsb     prtst           # print the string
                   22032:        movl    r9,dnamp        # delete garbage string from storage
                   22033:        jmp     prv03           # back to exit
                   22034:        #page   
                   22035: #
                   22036: #      PRTVL (CONTINUED)
                   22037: #
                   22038: #      NAME (NMBLK)
                   22039: #
                   22040: #      FOR PSEUDO-VARIABLE, JUST PRINT DATATYPE NAME (NAME)
                   22041: #      FOR ALL OTHER NAMES, PRINT DOT FOLLOWED BY NAME REP
                   22042: #
                   22043: prv09: movl    4*nmbas(r9),r10 # load name base
                   22044:        movl    (r10),r6        # load first word of block
                   22045:        cmpl    r6,$b$kvt       # just print name if keyword
                   22046:        bnequ   0f
                   22047:        jmp     prv02
                   22048: 0:             
                   22049:        cmpl    r6,$b$evt       # just print name if expression var
                   22050:        bnequ   0f
                   22051:        jmp     prv02
                   22052: 0:             
                   22053:        movl    $ch$dt,r6       # else get dot
                   22054:        jsb     prtch           # and print it
                   22055:        movl    4*nmofs(r9),r6  # load name offset
                   22056:        jsb     prtnm           # print name
                   22057:        jmp     prv03           # back to exit
                   22058: #
                   22059: #      PROGRAM DATATYPE (PDBLK)
                   22060: #
                   22061: #      PRINT DATATYPE NAME CH$BL CH$NM IDVAL
                   22062: #
                   22063: prv10: jsb     dtype           # get datatype name
                   22064:        jsb     prtst           # print datatype name
                   22065:        jmp     prv07           # merge back to print id
                   22066: #
                   22067: #      HERE FOR STRING (SCBLK)
                   22068: #
                   22069: #      PRINT QUOTE STRING-CHARACTERS QUOTE
                   22070: #
                   22071: prv11: movl    $ch$sq,r6       # load single quote
                   22072:        jsb     prtch           # print quote
                   22073:        jsb     prtst           # print string value
                   22074:        jsb     prtch           # print another quote
                   22075:        jmp     prv03           # back to exit
                   22076:        #page   
                   22077: #
                   22078: #      PRTVL (CONTINUED)
                   22079: #
                   22080: #      HERE FOR SIMPLE EXPRESSION (SEBLK)
                   22081: #
                   22082: #      PRINT ASTERISK VARIABLE-NAME
                   22083: #
                   22084: prv12: movl    $ch$as,r6       # load asterisk
                   22085:        jsb     prtch           # print asterisk
                   22086:        movl    4*sevar(r9),r9  # load variable pointer
                   22087:        jsb     prtvn           # print variable name
                   22088:        jmp     prv03           # jump back to exit
                   22089: #
                   22090: #      HERE FOR TABLE (TBBLK) AND ARRAY (VCBLK)
                   22091: #
                   22092: #      PRINT DATATYPE ( PROTOTYPE ) BLANK NUMBER IDVAL
                   22093: #
                   22094: prv13: movl    r9,r10          # preserve argument
                   22095:        jsb     dtype           # get datatype name
                   22096:        jsb     prtst           # print datatype name
                   22097:        movl    $ch$pp,r6       # load left paren
                   22098:        jsb     prtch           # print left paren
                   22099:        movl    4*tblen(r10),r6 # load length of block (=vclen)
                   22100:        ashl    $-2,r6,r6       # convert to word count
                   22101:        subl2   $tbsi$,r6       # allow for standard fields
                   22102:        cmpl    (r10),$b$tbt    # jump if table
                   22103:        beqlu   prv14
                   22104:        addl2   $vctbd,r6       # for vcblk, adjust size
                   22105: #
                   22106: #      PRINT PROTOTYPE
                   22107: #
                   22108: prv14: movl    r6,r5           # move as integer
                   22109:        jsb     prtin           # print integer prototype
                   22110:        jmp     prv06           # merge back for rest
                   22111:        #page   
                   22112: #
                   22113: #      PRTVL (CONTINUED)
                   22114: #
                   22115: #      HERE FOR BUFFER (BCBLK)
                   22116: #
                   22117: prv15: movl    r9,r10          # preserve argument
                   22118:        movl    $scbuf,r9       # point to datatype name (buffer)
                   22119:        jsb     prtst           # print it
                   22120:        movl    $ch$pp,r6       # load left paren
                   22121:        jsb     prtch           # print left paren
                   22122:        movl    4*bcbuf(r10),r9 # point to bfblk
                   22123:        movl    4*bfalc(r9),r5  # load allocation size
                   22124:        jsb     prtin           # print it
                   22125:        movl    $ch$cm,r6       # load comma
                   22126:        jsb     prtch           # print it
                   22127:        movl    4*bclen(r10),r5 # load defined length
                   22128:        jsb     prtin           # print it
                   22129:        jmp     prv06           # merge to finish up
                   22130:        #enp                    # end procedure prtvl
                   22131:        #page   
                   22132: #
                   22133: #      PRTVN -- PRINT NATURAL VARIABLE NAME
                   22134: #
                   22135: #      PRTVN PRINTS THE NAME OF A NATURAL VARIABLE
                   22136: #
                   22137: #      (XR)                  POINTER TO VRBLK
                   22138: #      JSR  PRTVN            CALL TO PRINT VARIABLE NAME
                   22139: #
                   22140: prtvn: #prc                    # entry point
                   22141:        movl    r9,-(sp)        # stack vrblk pointer
                   22142:        addl2   $4*vrsof,r9     # point to possible string name
                   22143:        tstl    4*sclen(r9)     # jump if not system variable
                   22144:        bnequ   prvn1
                   22145:        movl    4*vrsvo(r9),r9  # point to svblk with name
                   22146: #
                   22147: #      MERGE HERE WITH DUMMY SCBLK POINTER IN XR
                   22148: #
                   22149: prvn1: jsb     prtst           # print string name of variable
                   22150:        movl    (sp)+,r9        # restore vrblk pointer
                   22151:        rsb                     # return to prtvn caller
                   22152:        #enp                    # end procedure prtvn
                   22153:        #page   
                   22154: #
                   22155: #      RCBLD -- BUILD A REAL BLOCK
                   22156: #
                   22157: #      (RA)                  REAL VALUE FOR RCBLK
                   22158: #      JSR  RCBLD            CALL TO BUILD REAL BLOCK
                   22159: #      (XR)                  POINTER TO RESULT RCBLK
                   22160: #      (WA)                  DESTROYED
                   22161: #
                   22162: rcbld: #prc                    # entry point
                   22163:        movl    dnamp,r9        # load pointer to next available loc
                   22164:        addl2   $4*rcsi$,r9     # point past new rcblk
                   22165:        cmpl    r9,dname        # jump if there is room
                   22166:        blequ   rcbl1
                   22167:        movl    $4*rcsi$,r6     # else load rcblk length
                   22168:        jsb     alloc           # use standard allocator to get block
                   22169:        addl2   r6,r9           # point past block to merge
                   22170: #
                   22171: #      MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED
                   22172: #
                   22173: rcbl1: movl    r9,dnamp        # set new pointer
                   22174:        subl2   $4*rcsi$,r9     # point back to start of block
                   22175:        movl    $b$rcl,(r9)     # store type word
                   22176:        movf    r2,4*rcval(r9)  # store real value in rcblk
                   22177:        rsb                     # return to rcbld caller
                   22178:        #enp                    # end procedure rcbld
                   22179:        #page   
                   22180: #
                   22181: #      READR -- READ NEXT SOURCE IMAGE AT COMPILE TIME
                   22182: #
                   22183: #      READR IS USED TO READ THE NEXT SOURCE IMAGE. TO PROCESS
                   22184: #      CONTINUATION CARDS PROPERLY, THE COMPILER MUST READ ONE
                   22185: #      LINE AHEAD. THUS READR DOES NOT DESTROY THE CURRENT IMAGE
                   22186: #      SEE ALSO THE NEXTS ROUTINE WHICH ACTUALLY GETS THE IMAGE.
                   22187: #
                   22188: #      JSR  READR            CALL TO READ NEXT IMAGE
                   22189: #      (XR)                  PTR TO NEXT IMAGE (0 IF NONE)
                   22190: #      (R$CNI)               COPY OF POINTER
                   22191: #      (WA,WB,WC,XL)         DESTROYED
                   22192: #
                   22193: readr: #prc                    # entry point
                   22194:        movl    r$cni,r9        # get ptr to next image
                   22195:        tstl    r9              # exit if already read
                   22196:        bnequ   read3
                   22197:        cmpl    stage,$stgic    # exit if not initial compile
                   22198:        bnequ   read3
                   22199:        movl    cswin,r6        # max read length
                   22200:        jsb     alocs           # allocate buffer
                   22201:        jsb     sysrd           # read input image
                   22202:        .long   read4           # jump if end of file
                   22203:        movl    sp,r7           # set trimr to perform trim
                   22204:        cmpl    4*sclen(r9),cswin# use smaller of string lnth ..
                   22205:        blequ   read1
                   22206:        movl    cswin,4*sclen(r9)# ... and xxx of -inxxx
                   22207: #
                   22208: #      PERFORM THE TRIM
                   22209: #
                   22210: read1: jsb     trimr           # trim trailing blanks
                   22211: #
                   22212: #      MERGE HERE AFTER READ
                   22213: #
                   22214: read2: movl    r9,r$cni        # store copy of pointer
                   22215: #
                   22216: #      MERGE HERE IF NO READ ATTEMPTED
                   22217: #
                   22218: read3: rsb                     # return to readr caller
                   22219: #
                   22220: #      HERE ON END OF FILE
                   22221: #
                   22222: read4: movl    r9,dnamp        # pop unused scblk
                   22223:        clrl    r9              # zero ptr as result
                   22224:        jmp     read2           # merge
                   22225:        #enp                    # end procedure readr
                   22226:        #page   
                   22227: #
                   22228: #      SBSTR -- BUILD A SUBSTRING
                   22229: #
                   22230: #      (XL)                  PTR TO SCBLK/BFBLK WITH CHARS
                   22231: #      (WA)                  NUMBER OF CHARS IN SUBSTRING
                   22232: #      (WB)                  OFFSET TO FIRST CHAR IN SCBLK
                   22233: #      JSR  SBSTR            CALL TO BUILD SUBSTRING
                   22234: #      (XR)                  PTR TO NEW SCBLK WITH SUBSTRING
                   22235: #      (XL)                  ZERO
                   22236: #      (WA,WB,WC,XL,IA)      DESTROYED
                   22237: #
                   22238: #      NOTE THAT SBSTR IS CALLED WITH A DUMMY STRING POINTER
                   22239: #      (POINTING INTO A VRBLK OR SVBLK) TO COPY THE NAME OF A
                   22240: #      VARIABLE AS A STANDARD STRING VALUE.
                   22241: #
                   22242: sbstr: #prc                    # entry point
                   22243:        tstl    r6              # jump if null substring
                   22244:        beqlu   sbst2
                   22245:        jsb     alocs           # else allocate scblk
                   22246:        movl    r8,r6           # move number of characters
                   22247:        movl    r9,r8           # save ptr to new scblk
                   22248:        movab   cfp$f(r10)[r7],r10 # prepare to load chars from old blk
                   22249:        movab   cfp$f(r9),r9    # prepare to store chars in new blk
                   22250:        jsb     sbmvc           # move characters to new string
                   22251:        movl    r8,r9           # then restore scblk pointer
                   22252: #
                   22253: #      RETURN POINT
                   22254: #
                   22255: sbst1: clrl    r10             # clear garbage pointer in xl
                   22256:        rsb                     # return to sbstr caller
                   22257: #
                   22258: #      HERE FOR NULL SUBSTRING
                   22259: #
                   22260: sbst2: movl    $nulls,r9       # set null string as result
                   22261:        jmp     sbst1           # return
                   22262:        #enp                    # end procedure sbstr
                   22263:        #page   
                   22264: #
                   22265: #      SCANE -- SCAN AN ELEMENT
                   22266: #
                   22267: #      SCANE IS CALLED AT COMPILE TIME (BY EXPAN ,CMPIL,CNCRD)
                   22268: #      TO SCAN ONE ELEMENT FROM THE INPUT IMAGE.
                   22269: #
                   22270: #      (SCNCC)               NON-ZERO IF CALLED FROM CNCRD
                   22271: #      JSR  SCANE            CALL TO SCAN ELEMENT
                   22272: #      (XR)                  RESULT POINTER (SEE BELOW)
                   22273: #      (XL)                  SYNTAX TYPE CODE (T$XXX)
                   22274: #
                   22275: #      THE FOLLOWING GLOBAL LOCATIONS ARE USED.
                   22276: #
                   22277: #      R$CIM                 POINTER TO STRING BLOCK (SCBLK)
                   22278: #                            FOR CURRENT INPUT IMAGE.
                   22279: #
                   22280: #      R$CNI                 POINTER TO NEXT INPUT IMAGE STRING
                   22281: #                            POINTER (ZERO IF NONE).
                   22282: #
                   22283: #      R$SCP                 SAVE POINTER (EXIT XR) FROM LAST
                   22284: #                            CALL IN CASE RESCAN IS SET.
                   22285: #
                   22286: #      SCNBL                 THIS LOCATION IS SET NON-ZERO ON
                   22287: #                            EXIT IF SCANE SCANNED PAST BLANKS
                   22288: #                            BEFORE LOCATING THE CURRENT ELEMENT
                   22289: #                            THE END OF A LINE COUNTS AS BLANKS.
                   22290: #
                   22291: #      SCNCC                 CNCRD SETS THIS NON-ZERO TO SCAN
                   22292: #                            CONTROL CARD NAMES AND CLEARS IT
                   22293: #                            ON RETURN
                   22294: #
                   22295: #      SCNIL                 LENGTH OF CURRENT INPUT IMAGE
                   22296: #
                   22297: #      SCNGO                 IF SET NON-ZERO ON ENTRY, F AND S
                   22298: #                            ARE RETURNED AS SEPARATE SYNTAX
                   22299: #                            TYPES (NOT LETTERS) (GOTO PRO-
                   22300: #                            CESSING). SCNGO IS RESET ON EXIT.
                   22301: #
                   22302: #      SCNPT                 OFFSET TO CURRENT LOC IN R$CIM
                   22303: #
                   22304: #      SCNRS                 IF SET NON-ZERO ON ENTRY, SCANE
                   22305: #                            RETURNS THE SAME RESULT AS ON THE
                   22306: #                            LAST CALL (RESCAN). SCNRS IS RESET
                   22307: #                            ON EXIT FROM ANY CALL TO SCANE.
                   22308: #
                   22309: #      SCNTP                 SAVE SYNTAX TYPE FROM LAST
                   22310: #                            CALL (IN CASE RESCAN IS SET).
                   22311:        #page   
                   22312: #
                   22313: #      SCANE (CONTINUED)
                   22314: #
                   22315: #
                   22316: #
                   22317: #      ELEMENT SCANNED       XL        XR
                   22318: #      ---------------       --        --
                   22319: #
                   22320: #      CONTROL CARD NAME     0         POINTER TO SCBLK FOR NAME
                   22321: #
                   22322: #      UNARY OPERATOR        T$UOP     PTR TO OPERATOR DVBLK
                   22323: #
                   22324: #      LEFT PAREN            T$LPR     T$LPR
                   22325: #
                   22326: #      LEFT BRACKET          T$LBR     T$LBR
                   22327: #
                   22328: #      COMMA                 T$CMA     T$CMA
                   22329: #
                   22330: #      FUNCTION CALL         T$FNC     PTR TO FUNCTION VRBLK
                   22331: #
                   22332: #      VARIABLE              T$VAR     PTR TO VRBLK
                   22333: #
                   22334: #      STRING CONSTANT       T$CON     PTR TO SCBLK
                   22335: #
                   22336: #      INTEGER CONSTANT      T$CON     PTR TO ICBLK
                   22337: #
                   22338: #      REAL CONSTANT         T$CON     PTR TO RCBLK
                   22339: #
                   22340: #      BINARY OPERATOR       T$BOP     PTR TO OPERATOR DVBLK
                   22341: #
                   22342: #      RIGHT PAREN           T$RPR     T$RPR
                   22343: #
                   22344: #      RIGHT BRACKET         T$RBR     T$RBR
                   22345: #
                   22346: #      COLON                 T$COL     T$COL
                   22347: #
                   22348: #      SEMI-COLON            T$SMC     T$SMC
                   22349: #
                   22350: #      F (SCNGO NE 0)        T$FGO     T$FGO
                   22351: #
                   22352: #      S (SCNGO NE 0)        T$SGO     T$SGO
                   22353:        #page   
                   22354: #
                   22355: #      SCANE (CONTINUED)
                   22356: #
                   22357: #      ENTRY POINT
                   22358: #
                   22359: scane: #prc                    # entry point
                   22360:        clrl    scnbl           # reset blanks flag
                   22361:        movl    r6,scnsa        # save wa
                   22362:        movl    r7,scnsb        # save wb
                   22363:        movl    r8,scnsc        # save wc
                   22364:        tstl    scnrs           # jump if no rescan
                   22365:        beqlu   scn03
                   22366: #
                   22367: #      HERE FOR RESCAN REQUEST
                   22368: #
                   22369:        movl    scntp,r10       # set previous returned scan type
                   22370:        movl    r$scp,r9        # set previous returned pointer
                   22371:        clrl    scnrs           # reset rescan switch
                   22372:        jmp     scn13           # jump to exit
                   22373: #
                   22374: #      COME HERE TO READ NEW IMAGE TO TEST FOR CONTINUATION
                   22375: #
                   22376: scn01: jsb     readr           # read next image
                   22377:        movl    $4*dvubs,r7     # set wb for not reading name
                   22378:        tstl    r9              # treat as semi-colon if none
                   22379:        bnequ   0f
                   22380:        jmp     scn30
                   22381: 0:             
                   22382:        movab   cfp$f(r9),r9    # else point to first character
                   22383:        movzbl  (r9),r8         # load first character
                   22384:        cmpl    r8,$ch$dt       # jump if dot for continuation
                   22385:        beqlu   scn02
                   22386:        cmpl    r8,$ch$pl       # else treat as semicolon unless plus
                   22387:        beqlu   0f
                   22388:        jmp     scn30
                   22389: 0:             
                   22390: #
                   22391: #      HERE FOR CONTINUATION LINE
                   22392: #
                   22393: scn02: jsb     nexts           # acquire next source image
                   22394:        movl    $num01,scnpt    # set scan pointer past continuation
                   22395:        movl    sp,scnbl        # set blanks flag
                   22396:        #page   
                   22397: #
                   22398: #      SCANE (CONTINUED)
                   22399: #
                   22400: #      MERGE HERE TO SCAN NEXT ELEMENT ON CURRENT LINE
                   22401: #
                   22402: scn03: movl    scnpt,r6        # load current offset
                   22403:        cmpl    r6,scnil        # check continuation if end
                   22404:        bnequ   0f
                   22405:        jmp     scn01
                   22406: 0:             
                   22407:        movl    r$cim,r10       # point to current line
                   22408:        movab   cfp$f(r10)[r6],r10 # point to current character
                   22409:        movl    r6,scnse        # set start of element location
                   22410:        movl    $opdvs,r8       # point to operator dv list
                   22411:        movl    $4*dvubs,r7     # set constant for operator circuit
                   22412:        jmp     scn06           # start scanning
                   22413: #
                   22414: #      LOOP HERE TO IGNORE LEADING BLANKS AND TABS
                   22415: #
                   22416: scn05: tstl    r7              # jump if trailing
                   22417:        bnequ   0f
                   22418:        jmp     scn10
                   22419: 0:             
                   22420:        incl    scnse           # increment start of element
                   22421:        cmpl    r6,scnil        # jump if end of image
                   22422:        bnequ   0f
                   22423:        jmp     scn01
                   22424: 0:             
                   22425:        movl    sp,scnbl        # note blanks seen
                   22426: #
                   22427: #      THE FOLLOWING JUMP IS USED REPEATEDLY FOR SCANNING OUT
                   22428: #      THE CHARACTERS OF A NUMERIC CONSTANT OR VARIABLE NAME.
                   22429: #      THE REGISTERS ARE USED AS FOLLOWS.
                   22430: #
                   22431: #      (XR)                  SCRATCH
                   22432: #      (XL)                  PTR TO NEXT CHARACTER
                   22433: #      (WA)                  CURRENT SCAN OFFSET
                   22434: #      (WB)                  *DVUBS (0 IF SCANNING NAME,CONST)
                   22435: #      (WC)                  =OPDVS (0 IF SCANNING CONSTANT)
                   22436: #
                   22437: scn06: movzbl  (r10)+,r9       # get next character
                   22438:        incl    r6              # bump scan offset
                   22439:        movl    r6,scnpt        # store offset past char scanned
                   22440:        cmpl    $cfp$u,r9       # quick check for other char
                   22441:        bgtru   0f
                   22442:        jmp     scn07
                   22443: 0:             
                   22444:        casel   r9,$0,$cfp$u    # switch on scanned character
                   22445: 5:             
                   22446: #
                   22447: #      SWITCH TABLE FOR SWITCH ON CHARACTER
                   22448: #
                   22449:        #page   
                   22450: #
                   22451: #      SCANE (CONTINUED)
                   22452: #
                   22453:        #page   
                   22454: #
                   22455: #      SCANE (CONTINUED)
                   22456: #
                   22457:        .word   scn07-5b
                   22458:        .word   scn07-5b
                   22459:        .word   scn07-5b
                   22460:        .word   scn07-5b
                   22461:        .word   scn07-5b
                   22462:        .word   scn07-5b
                   22463:        .word   scn07-5b
                   22464:        .word   scn07-5b
                   22465:        .word   scn07-5b
                   22466:        .word   scn05-5b        # horizontal tab
                   22467:        .word   scn07-5b
                   22468:        .word   scn07-5b
                   22469:        .word   scn07-5b
                   22470:        .word   scn07-5b
                   22471:        .word   scn07-5b
                   22472:        .word   scn07-5b
                   22473:        .word   scn07-5b
                   22474:        .word   scn07-5b
                   22475:        .word   scn07-5b
                   22476:        .word   scn07-5b
                   22477:        .word   scn07-5b
                   22478:        .word   scn07-5b
                   22479:        .word   scn07-5b
                   22480:        .word   scn07-5b
                   22481:        .word   scn07-5b
                   22482:        .word   scn07-5b
                   22483:        .word   scn07-5b
                   22484:        .word   scn07-5b
                   22485:        .word   scn07-5b
                   22486:        .word   scn07-5b
                   22487:        .word   scn07-5b
                   22488:        .word   scn07-5b
                   22489:        .word   scn05-5b        # blank
                   22490:        .word   scn37-5b        # exclamation mark
                   22491:        .word   scn17-5b        # double quote
                   22492:        .word   scn41-5b        # number sign
                   22493:        .word   scn36-5b        # dollar
                   22494:        .word   scn38-5b        # percent
                   22495:        .word   scn44-5b        # ampersand
                   22496:        .word   scn16-5b        # single quote
                   22497:        .word   scn25-5b        # left paren
                   22498:        .word   scn26-5b        # right paren
                   22499:        .word   scn49-5b        # asterisk
                   22500:        .word   scn33-5b        # plus
                   22501:        .word   scn31-5b        # comma
                   22502:        .word   scn34-5b        # minus
                   22503:        .word   scn32-5b        # dot
                   22504:        .word   scn40-5b        # slash
                   22505:        .word   scn08-5b        # digit 0
                   22506:        .word   scn08-5b        # digit 1
                   22507:        .word   scn08-5b        # digit 2
                   22508:        .word   scn08-5b        # digit 3
                   22509:        .word   scn08-5b        # digit 4
                   22510:        .word   scn08-5b        # digit 5
                   22511:        .word   scn08-5b        # digit 6
                   22512:        .word   scn08-5b        # digit 7
                   22513:        .word   scn08-5b        # digit 8
                   22514:        .word   scn08-5b        # digit 9
                   22515:        .word   scn29-5b        # colon
                   22516:        .word   scn30-5b        # semi-colon
                   22517:        .word   scn28-5b        # left bracket
                   22518:        .word   scn46-5b        # equal
                   22519:        .word   scn27-5b        # right bracket
                   22520:        .word   scn45-5b        # question mark
                   22521:        .word   scn42-5b        # at
                   22522:        .word   scn09-5b        # letter a
                   22523:        .word   scn09-5b        # letter b
                   22524:        .word   scn09-5b        # letter c
                   22525:        .word   scn09-5b        # letter d
                   22526:        .word   scn09-5b        # letter e
                   22527:        .word   scn20-5b        # letter f
                   22528:        .word   scn09-5b        # letter g
                   22529:        .word   scn09-5b        # letter h
                   22530:        .word   scn09-5b        # letter i
                   22531:        .word   scn09-5b        # letter j
                   22532:        .word   scn09-5b        # letter k
                   22533:        .word   scn09-5b        # letter l
                   22534:        .word   scn09-5b        # letter m
                   22535:        .word   scn09-5b        # letter n
                   22536:        .word   scn09-5b        # letter o
                   22537:        .word   scn09-5b        # letter p
                   22538:        .word   scn09-5b        # letter q
                   22539:        .word   scn09-5b        # letter r
                   22540:        .word   scn21-5b        # letter s
                   22541:        .word   scn09-5b        # letter t
                   22542:        .word   scn09-5b        # letter u
                   22543:        .word   scn09-5b        # letter v
                   22544:        .word   scn09-5b        # letter w
                   22545:        .word   scn09-5b        # letter x
                   22546:        .word   scn09-5b        # letter y
                   22547:        .word   scn09-5b        # letter z
                   22548:        .word   scn28-5b        # left bracket
                   22549:        .word   scn07-5b
                   22550:        .word   scn27-5b        # right bracket
                   22551:        .word   scn07-5b
                   22552:        .word   scn24-5b        # underline
                   22553:        .word   scn07-5b
                   22554:        .word   scn09-5b        # shifted a
                   22555:        .word   scn09-5b        # shifted b
                   22556:        .word   scn09-5b        # shifted c
                   22557:        .word   scn09-5b        # shifted d
                   22558:        .word   scn09-5b        # shifted e
                   22559:        .word   scn20-5b        # shifted f
                   22560:        .word   scn09-5b        # shifted g
                   22561:        .word   scn09-5b        # shifted h
                   22562:        .word   scn09-5b        # shifted i
                   22563:        .word   scn09-5b        # shifted j
                   22564:        .word   scn09-5b        # shifted k
                   22565:        .word   scn09-5b        # shifted l
                   22566:        .word   scn09-5b        # shifted m
                   22567:        .word   scn09-5b        # shifted n
                   22568:        .word   scn09-5b        # shifted o
                   22569:        .word   scn09-5b        # shifted p
                   22570:        .word   scn09-5b        # shifted q
                   22571:        .word   scn09-5b        # shifted r
                   22572:        .word   scn21-5b        # shifted s
                   22573:        .word   scn09-5b        # shifted t
                   22574:        .word   scn09-5b        # shifted u
                   22575:        .word   scn09-5b        # shifted v
                   22576:        .word   scn09-5b        # shifted w
                   22577:        .word   scn09-5b        # shifted x
                   22578:        .word   scn09-5b        # shifted y
                   22579:        .word   scn09-5b        # shifted z
                   22580:        .word   scn07-5b
                   22581:        .word   scn43-5b        # vertical bar
                   22582:        .word   scn07-5b
                   22583:        .word   scn35-5b        # not
                   22584:        .word   scn07-5b
                   22585:        #esw                    # end switch on character
                   22586: #
                   22587: #      HERE FOR ILLEGAL CHARACTER (UNDERLINE MERGES)
                   22588: #
                   22589: scn07: tstl    r7              # jump if scanning name or constant
                   22590:        bnequ   0f
                   22591:        jmp     scn10
                   22592: 0:             
                   22593:        jmp     er_230          # syntax error. illegal character
                   22594:        #page   
                   22595: #
                   22596: #      SCANE (CONTINUED)
                   22597: #
                   22598: #      HERE FOR DIGITS 0-9
                   22599: #
                   22600: scn08: tstl    r7              # keep scanning if name/constant
                   22601:        bnequ   0f
                   22602:        jmp     scn09
                   22603: 0:             
                   22604:        clrl    r8              # else set flag for scanning constant
                   22605: #
                   22606: #      HERE FOR LETTER. LOOP HERE WHEN SCANNING NAME/CONSTANT
                   22607: #
                   22608: scn09: cmpl    r6,scnil        # jump if end of image
                   22609:        beqlu   scn11
                   22610:        clrl    r7              # set flag for scanning name/const
                   22611:        jmp     scn06           # merge back to continue scan
                   22612: #
                   22613: #      COME HERE FOR DELIMITER ENDING NAME OR CONSTANT
                   22614: #
                   22615: scn10: decl    r6              # reset offset to point to delimiter
                   22616: #
                   22617: #      COME HERE AFTER FINISHING SCAN OF NAME OR CONSTANT
                   22618: #
                   22619: scn11: movl    r6,scnpt        # store updated scan offset
                   22620:        movl    scnse,r7        # point to start of element
                   22621:        subl2   r7,r6           # get number of characters
                   22622:        movl    r$cim,r10       # point to line image
                   22623:        tstl    r8              # jump if name
                   22624:        bnequ   scn15
                   22625: #
                   22626: #      HERE AFTER SCANNING OUT NUMERIC CONSTANT
                   22627: #
                   22628:        jsb     sbstr           # get string for constant
                   22629:        movl    r9,dnamp        # delete from storage (not needed)
                   22630:        jsb     gtnum           # convert to numeric
                   22631:        .long   scn14           # jump if conversion failure
                   22632: #
                   22633: #      MERGE HERE TO EXIT WITH CONSTANT
                   22634: #
                   22635: scn12: movl    $t$con,r10      # set result type of constant
                   22636:        #page   
                   22637: #
                   22638: #      SCANE (CONTINUED)
                   22639: #
                   22640: #      COMMON EXIT POINT (XR,XL) SET
                   22641: #
                   22642: scn13: movl    scnsa,r6        # restore wa
                   22643:        movl    scnsb,r7        # restore wb
                   22644:        movl    scnsc,r8        # restore wc
                   22645:        movl    r9,r$scp        # save xr in case rescan
                   22646:        movl    r10,scntp       # save xl in case rescan
                   22647:        clrl    scngo           # reset possible goto flag
                   22648:        rsb                     # return to scane caller
                   22649: #
                   22650: #      HERE IF CONVERSION ERROR ON NUMERIC ITEM
                   22651: #
                   22652: scn14: jmp     er_231          # syntax error. invalid numeric item
                   22653: #
                   22654: #      HERE AFTER SCANNING OUT VARIABLE NAME
                   22655: #
                   22656: scn15: jsb     sbstr           # build string name of variable
                   22657:        tstl    scncc           # return if cncrd call
                   22658:        beqlu   0f
                   22659:        jmp     scn13
                   22660: 0:             
                   22661:        jsb     gtnvr           # locate/build vrblk
                   22662:        .long   invalid$        # dummy (unused) error return
                   22663:        movl    $t$var,r10      # set type as variable
                   22664:        jmp     scn13           # back to exit
                   22665: #
                   22666: #      HERE FOR SINGLE QUOTE (START OF STRING CONSTANT)
                   22667: #
                   22668: scn16: tstl    r7              # terminator if scanning name or cnst
                   22669:        bnequ   0f
                   22670:        jmp     scn10
                   22671: 0:             
                   22672:        movl    $ch$sq,r7       # set terminator as single quote
                   22673:        jmp     scn18           # merge
                   22674: #
                   22675: #      HERE FOR DOUBLE QUOTE (START OF STRING CONSTANT)
                   22676: #
                   22677: scn17: tstl    r7              # terminator if scanning name or cnst
                   22678:        bnequ   0f
                   22679:        jmp     scn10
                   22680: 0:             
                   22681:        movl    $ch$dq,r7       # set double quote terminator, merge
                   22682: #
                   22683: #      LOOP TO SCAN OUT STRING CONSTANT
                   22684: #
                   22685: scn18: cmpl    r6,scnil        # error if end of image
                   22686:        beqlu   scn19
                   22687:        movzbl  (r10)+,r8       # else load next character
                   22688:        incl    r6              # bump offset
                   22689:        cmpl    r8,r7           # loop back if not terminator
                   22690:        bnequ   scn18
                   22691:        #page   
                   22692: #
                   22693: #      SCANE (CONTINUED)
                   22694: #
                   22695: #      HERE AFTER SCANNING OUT STRING CONSTANT
                   22696: #
                   22697:        movl    scnpt,r7        # point to first character
                   22698:        movl    r6,scnpt        # save offset past final quote
                   22699:        decl    r6              # point back past last character
                   22700:        subl2   r7,r6           # get number of characters
                   22701:        movl    r$cim,r10       # point to input image
                   22702:        jsb     sbstr           # build substring value
                   22703:        jmp     scn12           # back to exit with constant result
                   22704: #
                   22705: #      HERE IF NO MATCHING QUOTE FOUND
                   22706: #
                   22707: scn19: movl    r6,scnpt        # set updated scan pointer
                   22708:        jmp     er_232          # syntax error. unmatched string quote
                   22709: #
                   22710: #      HERE FOR F (POSSIBLE FAILURE GOTO)
                   22711: #
                   22712: scn20: movl    $t$fgo,r9       # set return code for fail goto
                   22713:        jmp     scn22           # jump to merge
                   22714: #
                   22715: #      HERE FOR S (POSSIBLE SUCCESS GOTO)
                   22716: #
                   22717: scn21: movl    $t$sgo,r9       # set success goto as return code
                   22718: #
                   22719: #      SPECIAL GOTO CASES MERGE HERE
                   22720: #
                   22721: scn22: tstl    scngo           # treat as normal letter if not goto
                   22722:        bnequ   0f
                   22723:        jmp     scn09
                   22724: 0:             
                   22725: #
                   22726: #      MERGE HERE FOR SPECIAL CHARACTER EXIT
                   22727: #
                   22728: scn23: tstl    r7              # jump if end of name/constant
                   22729:        bnequ   0f
                   22730:        jmp     scn10
                   22731: 0:             
                   22732:        movl    r9,r10          # else copy code
                   22733:        jmp     scn13           # and jump to exit
                   22734: #
                   22735: #      HERE FOR UNDERLINE
                   22736: #
                   22737: scn24: tstl    r7              # part of name if scanning name
                   22738:        bnequ   0f
                   22739:        jmp     scn09
                   22740: 0:             
                   22741:        jmp     scn07           # else illegal
                   22742:        #page   
                   22743: #
                   22744: #      SCANE (CONTINUED)
                   22745: #
                   22746: #      HERE FOR LEFT PAREN
                   22747: #
                   22748: scn25: movl    $t$lpr,r9       # set left paren return code
                   22749:        tstl    r7              # return left paren unless name
                   22750:        bnequ   scn23
                   22751:        tstl    r8              # delimiter if scanning constant
                   22752:        bnequ   0f
                   22753:        jmp     scn10
                   22754: 0:             
                   22755: #
                   22756: #      HERE FOR LEFT PAREN AFTER NAME (FUNCTION CALL)
                   22757: #
                   22758:        movl    scnse,r7        # point to start of name
                   22759:        movl    r6,scnpt        # set pointer past left paren
                   22760:        decl    r6              # point back past last char of name
                   22761:        subl2   r7,r6           # get name length
                   22762:        movl    r$cim,r10       # point to input image
                   22763:        jsb     sbstr           # get string name for function
                   22764:        jsb     gtnvr           # locate/build vrblk
                   22765:        .long   invalid$        # dummy (unused) error return
                   22766:        movl    $t$fnc,r10      # set code for function call
                   22767:        jmp     scn13           # back to exit
                   22768: #
                   22769: #      PROCESSING FOR SPECIAL CHARACTERS
                   22770: #
                   22771: scn26: movl    $t$rpr,r9       # right paren, set code
                   22772:        jmp     scn23           # take special character exit
                   22773: #
                   22774: scn27: movl    $t$rbr,r9       # right bracket, set code
                   22775:        jmp     scn23           # take special character exit
                   22776: #
                   22777: scn28: movl    $t$lbr,r9       # left bracket, set code
                   22778:        jmp     scn23           # take special character exit
                   22779: #
                   22780: scn29: movl    $t$col,r9       # colon, set code
                   22781:        jmp     scn23           # take special character exit
                   22782: #
                   22783: scn30: movl    $t$smc,r9       # semi-colon, set code
                   22784:        jmp     scn23           # take special character exit
                   22785: #
                   22786: scn31: movl    $t$cma,r9       # comma, set code
                   22787:        jmp     scn23           # take special character exit
                   22788:        #page   
                   22789: #
                   22790: #      SCANE (CONTINUED)
                   22791: #
                   22792: #      HERE FOR OPERATORS. ON ENTRY, WC POINTS TO THE TABLE OF
                   22793: #      OPERATOR DOPE VECTORS AND WB IS THE INCREMENT TO STEP
                   22794: #      TO THE NEXT PAIR (BINARY/UNARY) OF DOPE VECTORS IN THE
                   22795: #      LIST. ON REACHING SCN46, THE POINTER HAS BEEN ADJUSTED TO
                   22796: #      POINT TO THE APPROPRIATE PAIR OF DOPE VECTORS.
                   22797: #      THE FIRST THREE ENTRIES ARE SPECIAL SINCE THEY CAN OCCUR
                   22798: #      AS PART OF A VARIABLE NAME (.) OR CONSTANT (.+-).
                   22799: #
                   22800: scn32: tstl    r7              # dot can be part of name or constant
                   22801:        bnequ   0f
                   22802:        jmp     scn09
                   22803: 0:             
                   22804:        addl2   r7,r8           # else bump pointer
                   22805: #
                   22806: scn33: tstl    r8              # plus can be part of constant
                   22807:        bnequ   0f
                   22808:        jmp     scn09
                   22809: 0:             
                   22810:        tstl    r7              # plus cannot be part of name
                   22811:        bnequ   0f
                   22812:        jmp     scn48
                   22813: 0:             
                   22814:        addl2   r7,r8           # else bump pointer
                   22815: #
                   22816: scn34: tstl    r8              # minus can be part of constant
                   22817:        bnequ   0f
                   22818:        jmp     scn09
                   22819: 0:             
                   22820:        tstl    r7              # minus cannot be part of name
                   22821:        bnequ   0f
                   22822:        jmp     scn48
                   22823: 0:             
                   22824:        addl2   r7,r8           # else bump pointer
                   22825: #
                   22826: scn35: addl2   r7,r8           # not
                   22827: scn36: addl2   r7,r8           # dollar
                   22828: scn37: addl2   r7,r8           # exclamation
                   22829: scn38: addl2   r7,r8           # percent
                   22830: scn39: addl2   r7,r8           # asterisk
                   22831: scn40: addl2   r7,r8           # slash
                   22832: scn41: addl2   r7,r8           # number sign
                   22833: scn42: addl2   r7,r8           # at sign
                   22834: scn43: addl2   r7,r8           # vertical bar
                   22835: scn44: addl2   r7,r8           # ampersand
                   22836: scn45: addl2   r7,r8           # question mark
                   22837: #
                   22838: #      ALL OPERATORS COME HERE (EQUAL MERGES DIRECTLY)
                   22839: #      (WC) POINTS TO THE BINARY/UNARY PAIR OF OPERATOR DVBLKS.
                   22840: #
                   22841: scn46: tstl    r7              # operator terminates name/constant
                   22842:        bnequ   0f
                   22843:        jmp     scn10
                   22844: 0:             
                   22845:        movl    r8,r9           # else copy dv pointer
                   22846:        movzbl  (r10),r8        # load next character
                   22847:        movl    $t$bop,r10      # set binary op in case
                   22848:        cmpl    r6,scnil        # should be binary if image end
                   22849:        beqlu   scn47
                   22850:        cmpl    r8,$ch$bl       # should be binary if followed by blk
                   22851:        beqlu   scn47
                   22852:        cmpl    r8,$ch$ht       # jump if horizontal tab
                   22853:        beqlu   scn47
                   22854:        cmpl    r8,$ch$sm       # semicolon can immediately follow =
                   22855:        beqlu   scn47
                   22856: #
                   22857: #      HERE FOR UNARY OPERATOR
                   22858: #
                   22859:        addl2   $4*dvbs$,r9     # point to dv for unary op
                   22860:        movl    $t$uop,r10      # set type for unary operator
                   22861:        cmpl    scntp,$t$uok    # ok unary if ok preceding element
                   22862:        bgtru   0f
                   22863:        jmp     scn13
                   22864: 0:             
                   22865:        #page   
                   22866: #
                   22867: #      SCANE (CONTINUED)
                   22868: #
                   22869: #      MERGE HERE TO REQUIRE PRECEDING BLANKS
                   22870: #
                   22871: scn47: tstl    scnbl           # all ok if preceding blanks, exit
                   22872:        beqlu   0f
                   22873:        jmp     scn13
                   22874: 0:             
                   22875: #
                   22876: #      FAIL OPERATOR IN THIS POSITION
                   22877: #
                   22878: scn48: jmp     er_233          # syntax error. invalid use of operator
                   22879: #
                   22880: #      HERE FOR ASTERISK, COULD BE ** SUBSTITUTE FOR EXCLAMATION
                   22881: #
                   22882: scn49: tstl    r7              # end of name if scanning name
                   22883:        bnequ   0f
                   22884:        jmp     scn10
                   22885: 0:             
                   22886:        cmpl    r6,scnil        # not ** if * at image end
                   22887:        beqlu   scn39
                   22888:        movl    r6,r9           # else save offset past first *
                   22889:        movl    r6,scnof        # save another copy
                   22890:        movzbl  (r10)+,r6       # load next character
                   22891:        cmpl    r6,$ch$as       # not ** if next char not *
                   22892:        bnequ   scn50
                   22893:        incl    r9              # else step offset past second *
                   22894:        cmpl    r9,scnil        # ok exclam if end of image
                   22895:        beqlu   scn51
                   22896:        movzbl  (r10),r6        # else load next character
                   22897:        cmpl    r6,$ch$bl       # exclamation if blank
                   22898:        beqlu   scn51
                   22899:        cmpl    r6,$ch$ht       # exclamation if horizontal tab
                   22900:        beqlu   scn51
                   22901: #
                   22902: #      UNARY *
                   22903: #
                   22904: scn50: movl    scnof,r6        # recover stored offset
                   22905:        movl    r$cim,r10       # point to line again
                   22906:        movab   cfp$f(r10)[r6],r10 # point to current char
                   22907:        jmp     scn39           # merge with unary *
                   22908: #
                   22909: #      HERE FOR ** AS SUBSTITUTE FOR EXCLAMATION
                   22910: #
                   22911: scn51: movl    r9,scnpt        # save scan pointer past 2nd *
                   22912:        movl    r9,r6           # copy scan pointer
                   22913:        jmp     scn37           # merge with exclamation
                   22914:        #enp                    # end procedure scane
                   22915:        #page   
                   22916: #
                   22917: #      SCNGF -- SCAN GOTO FIELD
                   22918: #
                   22919: #      SCNGF IS CALLED FROM CMPIL TO SCAN AND ANALYZE A GOTO
                   22920: #      FIELD INCLUDING THE SURROUNDING BRACKETS OR PARENTHESES.
                   22921: #      FOR A NORMAL GOTO, THE RESULT RETURNED IS EITHER A VRBLK
                   22922: #      POINTER FOR A SIMPLE LABEL OPERAND, OR A POINTER TO AN
                   22923: #      EXPRESSION TREE WITH A SPECIAL OUTER UNARY OPERATOR
                   22924: #      (O$GOC). FOR A DIRECT GOTO, THE RESULT RETURNED IS A
                   22925: #      POINTER TO AN EXPRESSION TREE WITH THE SPECIAL OUTER
                   22926: #      UNARY OPERATOR O$GOD.
                   22927: #
                   22928: #      JSR  SCNGF            CALL TO SCAN GOTO FIELD
                   22929: #      (XR)                  RESULT (SEE ABOVE)
                   22930: #      (XL,WA,WB,WC)         DESTROYED
                   22931: #
                   22932: scngf: #prc                    # entry point
                   22933:        jsb     scane           # scan initial element
                   22934:        cmpl    r10,$t$lpr      # skip if left paren (normal goto)
                   22935:        beqlu   scng1
                   22936:        cmpl    r10,$t$lbr      # skip if left bracket (direct goto)
                   22937:        beqlu   scng2
                   22938:        jmp     er_234          # syntax error. goto field incorrect
                   22939: #
                   22940: #      HERE FOR LEFT PAREN (NORMAL GOTO)
                   22941: #
                   22942: scng1: movl    $num01,r7       # set expan flag for normal goto
                   22943:        jsb     expan           # analyze goto field
                   22944:        movl    $opdvn,r6       # point to opdv for complex goto
                   22945:        cmpl    r9,statb        # jump if not in static (sgd15)
                   22946:        blequ   scng3
                   22947:        cmpl    r9,state        # jump to exit if simple label name
                   22948:        blequ   scng4
                   22949:        jmp     scng3           # complex goto - merge
                   22950: #
                   22951: #      HERE FOR LEFT BRACKET (DIRECT GOTO)
                   22952: #
                   22953: scng2: movl    $num02,r7       # set expan flag for direct goto
                   22954:        jsb     expan           # scan goto field
                   22955:        movl    $opdvd,r6       # set opdv pointer for direct goto
                   22956:        #page   
                   22957: #
                   22958: #      SCNGF (CONTINUED)
                   22959: #
                   22960: #      MERGE HERE TO BUILD OUTER UNARY OPERATOR BLOCK
                   22961: #
                   22962: scng3: movl    r6,-(sp)        # stack operator dv pointer
                   22963:        movl    r9,-(sp)        # stack pointer to expression tree
                   22964:        jsb     expop           # pop operator off
                   22965:        movl    (sp)+,r9        # reload new expression tree pointer
                   22966: #
                   22967: #      COMMON EXIT POINT
                   22968: #
                   22969: scng4: rsb                     # return to caller
                   22970:        #enp                    # end procedure scngf
                   22971:        #page   
                   22972: #
                   22973: #      SETVR -- SET VRGET,VRSTO FIELDS OF VRBLK
                   22974: #
                   22975: #      SETVR SETS THE PROPER VALUES IN THE VRGET AND VRSTO
                   22976: #      FIELDS OF A VRBLK. IT IS CALLED WHENEVER TRBLKS ARE
                   22977: #      ADDED OR SUBTRACTED (TRACE,STOPTR,INPUT,OUTPUT,DETACH)
                   22978: #
                   22979: #      (XR)                  POINTER TO VRBLK
                   22980: #      JSR  SETVR            CALL TO SET FIELDS
                   22981: #      (XL,WA)               DESTROYED
                   22982: #
                   22983: #      NOTE THAT SETVR IGNORES THE CALL IF XR DOES NOT POINT
                   22984: #      INTO THE STATIC REGION (I.E. IS SOME OTHER NAME BASE)
                   22985: #
                   22986: setvr: #prc                    # entry point
                   22987:        cmpl    r9,state        # exit if not natural variable
                   22988:        bgequ   setv1
                   22989: #
                   22990: #      HERE IF WE HAVE A VRBLK
                   22991: #
                   22992:        movl    r9,r10          # copy vrblk pointer
                   22993:        movl    $b$vrl,4*vrget(r9) # store normal get value
                   22994:        cmpl    4*vrsto(r9),$b$vre # skip if protected variable
                   22995:        beqlu   setv1
                   22996:        movl    $b$vrs,4*vrsto(r9) # store normal store value
                   22997:        movl    4*vrval(r10),r10# point to next entry on chain
                   22998:        cmpl    (r10),$b$trt    # jump if end of trblk chain
                   22999:        bnequ   setv1
                   23000:        movl    $b$vra,4*vrget(r9) # store trapped routine address
                   23001:        movl    $b$vrv,4*vrsto(r9) # set trapped routine address
                   23002: #
                   23003: #      MERGE HERE TO EXIT TO CALLER
                   23004: #
                   23005: setv1: rsb                     # return to setvr caller
                   23006:        #enp                    # end procedure setvr
                   23007:        #page   
                   23008: #
                   23009: #      SORTA -- SORT ARRAY
                   23010: #
                   23011: #      ROUTINE TO SORT AN ARRAY OR TABLE ON SAME BASIS AS IN
                   23012: #      SITBOL. A TABLE IS CONVERTED TO AN ARRAY, LEAVING TWO
                   23013: #      DIMENSIONAL ARRAYS AND VECTORS AS CASES TO BE CONSIDERED.
                   23014: #      WHOLE ROWS OF ARRAYS ARE PERMUTED ACCORDING TO THE
                   23015: #      ORDERING OF THE KEYS THEY CONTAIN, AND THE STRIDE
                   23016: #      REFERRED TO, IS THE THE LENGTH OF A ROW. IT IS ONE
                   23017: #      FOR A VECTOR.
                   23018: #      THE SORT USED IS HEAPSORT, FUNDAMENTALS OF DATA STRUCTURE
                   23019: #      HOROWITZ AND SAHNI, PITMAN 1977, PAGE 347.
                   23020: #      IT IS AN ORDER N*LOG(N) ALGORITHM. IN ORDER
                   23021: #      TO MAKE IT STABLE, COMPARANDS MAY NOT COMPARE EQUAL. THIS
                   23022: #      IS ACHIEVED BY SORTING A COPY ARRAY (REFERRED TO AS THE
                   23023: #      SORT ARRAY) CONTAINING AT ITS HIGH ADDRESS END, BYTE
                   23024: #      OFFSETS TO THE ROWS TO BE SORTED HELD IN THE ORIGINAL
                   23025: #      ARRAY (REFERRED TO AS THE KEY ARRAY). SORTC, THE
                   23026: #      COMPARISON ROUTINE, ACCESSES THE KEYS THROUGH THESE
                   23027: #      OFFSETS AND IN THE CASE OF EQUALITY, RESOLVES IT BY
                   23028: #      COMPARING THE OFFSETS THEMSELVES. THE SORT PERMUTES THE
                   23029: #      OFFSETS WHICH ARE THEN USED IN A FINAL OPERATION TO COPY
                   23030: #      THE ACTUAL ITEMS INTO THE NEW ARRAY IN SORTED ORDER.
                   23031: #      REFERENCES TO ZEROTH ITEM ARE TO NOTIONAL ITEM
                   23032: #      PRECEDING FIRST ACTUAL ITEM.
                   23033: #      REVERSE SORTING FOR RSORT IS DONE BY HAVING THE LESS THAN
                   23034: #      TEST FOR KEYS EFFECTIVELY BE REPLACED BY A
                   23035: #      GREATER THAN TEST.
                   23036: #
                   23037: #      1(XS)                 FIRST ARG - ARRAY OR TABLE
                   23038: #      0(XS)                 2ND ARG - INDEX OR PDTYPE NAME
                   23039: #      (WA)                  0 , NON-ZERO FOR SORT , RSORT
                   23040: #      JSR  SORTA            CALL TO SORT ARRAY
                   23041: #      (XR)                  SORTED ARRAY
                   23042: #      (XL,WA,WB,WC)         DESTROYED
                   23043:        #page   
                   23044: #
                   23045: #      SORTA (CONTINUED)
                   23046: #
                   23047:        .data   1
                   23048: sorta_s:       .long   0
                   23049:        .text   0
                   23050: sorta: movl    (sp)+,sorta_s   # entry point
                   23051:        movl    r6,srtsr        # sort/rsort indicator
                   23052:        movl    $4*num01,srtst  # default stride of 1
                   23053:        clrl    srtof           # default zero offset to sort key
                   23054:        movl    $nulls,srtdf    # clear datatype field name
                   23055:        movl    (sp)+,r$sxr     # unstack argument 2
                   23056:        movl    (sp)+,r9        # get first argument
                   23057:        jsb     gtarr           # convert to array
                   23058:        .long   srt16           # fail
                   23059:        movl    r9,-(sp)        # stack ptr to resulting key array
                   23060:        movl    r9,-(sp)        # another copy for copyb
                   23061:        jsb     copyb           # get copy array for sorting into
                   23062:        .long   invalid$        # cant fail
                   23063:        movl    r9,-(sp)        # stack pointer to sort array
                   23064:        movl    r$sxr,r9        # get second arg
                   23065:        movl    4*1(sp),r10     # get ptr to key array
                   23066:        cmpl    (r10),$b$vct    # jump if arblk
                   23067:        bnequ   srt02
                   23068:        cmpl    r9,$nulls       # jump if null second arg
                   23069:        beqlu   srt01
                   23070:        jsb     gtnvr           # get vrblk ptr for it
                   23071:        .long   er_257          # erroneous 2nd arg in sort/rsort of vector
                   23072:        movl    r9,srtdf        # store datatype field name vrblk
                   23073: #
                   23074: #      COMPUTE N AND OFFSET TO ITEM A(0) IN VECTOR CASE
                   23075: #
                   23076: srt01: movl    $4*vclen,r8     # offset to a(0)
                   23077:        movl    $4*vcvls,r7     # offset to first item
                   23078:        movl    4*vclen(r10),r6 # get block length
                   23079:        subl2   $4*vcsi$,r6     # get no. of entries, n (in bytes)
                   23080:        jmp     srt04           # merge
                   23081: #
                   23082: #      HERE FOR ARRAY
                   23083: #
                   23084: srt02: movl    4*ardim(r10),r5 # get possible dimension
                   23085:        movl    r5,r6           # convert to short integer
                   23086:        moval   0[r6],r6        # further convert to baus
                   23087:        movl    $4*arvls,r7     # offset to first value if one
                   23088:        movl    $4*arpro,r8     # offset before values if one dim.
                   23089:        cmpl    4*arndm(r10),$num01 # jump in fact if one dim.
                   23090:        bnequ   0f
                   23091:        jmp     srt04
                   23092: 0:             
                   23093:        cmpl    4*arndm(r10),$num02 # fail unless two dimens
                   23094:        beqlu   0f
                   23095:        jmp     srt16
                   23096: 0:             
                   23097:        movl    4*arlb2(r10),r5 # get lower bound 2 as default
                   23098:        cmpl    r9,$nulls       # jump if default second arg
                   23099:        beqlu   srt03
                   23100:        jsb     gtint           # convert to integer
                   23101:        .long   srt17           # fail
                   23102:        movl    4*icval(r9),r5  # get actual integer value
                   23103:        #page   
                   23104: #
                   23105: #      SORTA (CONTINUED)
                   23106: #
                   23107: #      HERE WITH SORT COLUMN INDEX IN IA IN ARRAY CASE
                   23108: #
                   23109: srt03: subl2   4*arlb2(r10),r5 # subtract low bound
                   23110:        bvc     0f
                   23111:        jmp     srt17
                   23112: 0:             
                   23113:        tstl    r5              # fail if below low bound
                   23114:        bgeq    0f
                   23115:        jmp     srt17
                   23116: 0:             
                   23117:        subl2   4*ardm2(r10),r5 # check against dimension
                   23118:        tstl    r5              # fail if too large
                   23119:        blss    0f
                   23120:        jmp     srt17
                   23121: 0:             
                   23122:        addl2   4*ardm2(r10),r5 # restore value
                   23123:        movl    r5,r6           # get as small integer
                   23124:        moval   0[r6],r6        # offset within row to key
                   23125:        movl    r6,srtof        # keep offset
                   23126:        movl    4*ardm2(r10),r5 # second dimension is row length
                   23127:        movl    r5,r6           # convert to short integer
                   23128:        movl    r6,r9           # copy row length
                   23129:        moval   0[r6],r6        # convert to bytes
                   23130:        movl    r6,srtst        # store as stride
                   23131:        movl    4*ardim(r10),r5 # get number of rows
                   23132:        movl    r5,r6           # as a short integer
                   23133:        moval   0[r6],r6        # convert n to baus
                   23134:        movl    4*arlen(r10),r8 # offset past array end
                   23135:        subl2   r6,r8           # adjust, giving space for n offsets
                   23136:        subl2   $4,r8           # point to a(0)
                   23137:        movl    4*arofs(r10),r7 # offset to word before first item
                   23138:        addl2   $4,r7           # offset to first item
                   23139: #
                   23140: #      SEPARATE PRE-PROCESSING FOR ARRAYS AND VECTORS DONE.
                   23141: #      TO SIMPLIFY LATER KEY COMPARISONS, REMOVAL OF ANY TRBLK
                   23142: #      TRAP BLOCKS FROM ENTRIES IN KEY ARRAY IS EFFECTED.
                   23143: #
                   23144: #      (XL) = 1(XS) = POINTER TO KEY ARRAY
                   23145: #      (XS) = POINTER TO SORT ARRAY
                   23146: #      WA = NUMBER OF ITEMS, N (CONVERTED TO BYTES).
                   23147: #      WB = OFFSET TO FIRST ITEM OF ARRAYS.
                   23148: #      WC = OFFSET TO A(0)
                   23149: #
                   23150: srt04: cmpl    r6,$4*num01     # return if only a single item
                   23151:        bgtru   0f
                   23152:        jmp     srt15
                   23153: 0:             
                   23154:        movl    r6,srtsn        # store number of items (in baus)
                   23155:        movl    r8,srtso        # store offset to a(0)
                   23156:        movl    4*arlen(r10),r8 # length of array or vec (=vclen)
                   23157:        addl2   r10,r8          # point past end of array or vector
                   23158:        movl    r7,srtsf        # store offset to first row
                   23159:        addl2   r7,r10          # point to first item in key array
                   23160: #
                   23161: #      LOOP THROUGH ARRAY
                   23162: #
                   23163: srt05: movl    (r10),r9        # get an entry
                   23164: #
                   23165: #      HUNT ALONG TRBLK CHAIN
                   23166: #
                   23167: srt06: cmpl    (r9),$b$trt     # jump out if not trblk
                   23168:        bnequ   srt07
                   23169:        movl    4*trval(r9),r9  # get value field
                   23170:        jmp     srt06           # loop
                   23171:        #page   
                   23172: #
                   23173: #      SORTA (CONTINUED)
                   23174: #
                   23175: #      XR IS VALUE FROM END OF CHAIN
                   23176: #
                   23177: srt07: movl    r9,(r10)+       # store as array entry
                   23178:        cmpl    r10,r8          # loop if not done
                   23179:        blssu   srt05
                   23180:        movl    (sp),r10        # get adrs of sort array
                   23181:        movl    srtsf,r9        # initial offset to first key
                   23182:        movl    srtst,r7        # get stride
                   23183:        addl2   srtso,r10       # offset to a(0)
                   23184:        addl2   $4,r10          # point to a(1)
                   23185:        movl    srtsn,r8        # get n
                   23186:        ashl    $-2,r8,r8       # convert from bytes
                   23187:        movl    r8,srtnr        # store as row count
                   23188:                                # loop counter
                   23189: #
                   23190: #      STORE KEY OFFSETS AT TOP OF SORT ARRAY
                   23191: #
                   23192: srt08: movl    r9,(r10)+       # store an offset
                   23193:        addl2   r7,r9           # bump offset by stride
                   23194:        sobgtr  r8,srt08        # loop through rows
                   23195: #
                   23196: #      PERFORM THE SORT ON OFFSETS IN SORT ARRAY.
                   23197: #
                   23198: #      (SRTSN)               NUMBER OF ITEMS TO SORT, N (BYTES)
                   23199: #      (SRTSO)               OFFSET TO A(0)
                   23200: #
                   23201: srt09: movl    srtsn,r6        # get n
                   23202:        movl    srtnr,r8        # get number of rows
                   23203:        ashl    $-1,r8,r8       # i = n / 2 (wc=i, index into array)
                   23204:        moval   0[r8],r8        # convert back to bytes
                   23205: #
                   23206: #      LOOP TO FORM INITIAL HEAP
                   23207: #
                   23208: srt10: jsb     sorth           # sorth(i,n)
                   23209:        subl2   $4,r8           # i = i - 1
                   23210:        tstl    r8              # loop if i gt 0
                   23211:        bnequ   srt10
                   23212:        movl    r6,r8           # i = n
                   23213: #
                   23214: #      SORTING LOOP. AT THIS POINT, A(1) IS THE LARGEST
                   23215: #      ITEM, SINCE ALGORITHM INITIALISES IT AS, AND THEN MAINTAI
                   23216: #      IT AS, ROOT OF TREE.
                   23217: #
                   23218: srt11: subl2   $4,r8           # i = i - 1 (n - 1 initially)
                   23219:        tstl    r8              # jump if done
                   23220:        beqlu   srt12
                   23221:        movl    (sp),r9         # get sort array address
                   23222:        addl2   srtso,r9        # point to a(0)
                   23223:        movl    r9,r10          # a(0) address
                   23224:        addl2   r8,r10          # a(i) address
                   23225:        movl    4*1(r10),r7     # copy a(i+1)
                   23226:        movl    4*1(r9),4*1(r10)# move a(1) to a(i+1)
                   23227:        movl    r7,4*1(r9)      # complete exchange of a(1), a(i+1)
                   23228:        movl    r8,r6           # n = i for sorth
                   23229:        movl    $4*num01,r8     # i = 1 for sorth
                   23230:        jsb     sorth           # sorth(1,n)
                   23231:        movl    r6,r8           # restore wc
                   23232:        jmp     srt11           # loop
                   23233:        #page   
                   23234: #
                   23235: #      SORTA (CONTINUED)
                   23236: #
                   23237: #      OFFSETS HAVE BEEN PERMUTED INTO REQUIRED ORDER BY SORT.
                   23238: #      COPY ARRAY ELEMENTS OVER THEM.
                   23239: #
                   23240: srt12: movl    (sp),r10        # base adrs of key array
                   23241:        movl    r10,r8          # copy it
                   23242:        addl2   srtso,r8        # offset of a(0)
                   23243:        addl2   srtsf,r10       # adrs of first row of sort array
                   23244:        movl    srtst,r7        # get stride
                   23245:        ashl    $-2,r7,r7       # convert to words
                   23246: #
                   23247: #      COPYING LOOP FOR SUCCESSIVE ITEMS. SORTED OFFSETS ARE
                   23248: #      HELD AT END OF SORT ARRAY.
                   23249: #
                   23250: srt13: addl2   $4,r8           # adrs of next of sorted offsets
                   23251:        movl    r8,r9           # copy it for access
                   23252:        movl    (r9),r9         # get offset
                   23253:        addl2   4*1(sp),r9      # add key array base adrs
                   23254:        movl    r7,r6           # get count of words in row
                   23255: #
                   23256: #      COPY A COMPLETE ROW
                   23257: #
                   23258: srt14: movl    (r9)+,(r10)+    # move a word
                   23259:        sobgtr  r6,srt14        # loop
                   23260:        decl    srtnr           # decrement row count
                   23261:        tstl    srtnr           # repeat till all rows done
                   23262:        bnequ   srt13
                   23263: #
                   23264: #      RETURN POINT
                   23265: #
                   23266: srt15: movl    (sp)+,r9        # pop result array ptr
                   23267:        addl2   $4,sp           # pop key array ptr
                   23268:        clrl    r$sxl           # clear junk
                   23269:        clrl    r$sxr           # clear junk
                   23270:        jmp     *sorta_s        # return
                   23271: #
                   23272: #      ERROR POINT
                   23273: #
                   23274: srt16: jmp     er_256          # sort/rsort 1st arg not suitable array or table
                   23275: srt17: jmp     er_258          # sort/rsort 2nd arg out of range or non-integer
                   23276:        #enp                    # end procudure sorta
                   23277:        #page   
                   23278: #
                   23279: #      SORTC --  COMPARE SORT KEYS
                   23280: #
                   23281: #      COMPARE TWO SORT KEYS GIVEN THEIR OFFSETS. IF
                   23282: #      EQUAL, COMPARE KEY OFFSETS TO GIVE STABLE SORT.
                   23283: #      NOTE THAT IF SRTSR IS NON-ZERO (REQUEST FOR REVERSE
                   23284: #      SORT), THE QUOTED RETURNS ARE INVERTED.
                   23285: #      FOR OBJECTS OF DIFFERING DATATYPES, THE ENTRY POINT
                   23286: #      IDENTIFICATIONS ARE COMPARED.
                   23287: #
                   23288: #      (XL)                  BASE ADRS FOR KEYS
                   23289: #      (WA)                  OFFSET TO KEY 1 ITEM
                   23290: #      (WB)                  OFFSET TO KEY 2 ITEM
                   23291: #      (SRTSR)               ZERO/NON-ZERO FOR SORT/RSORT
                   23292: #      (SRTOF)               OFFSET WITHIN ROW TO COMPARANDS
                   23293: #      JSR  SORTC            CALL TO COMPARE KEYS
                   23294: #      PPM  LOC              KEY1 LESS THAN KEY2
                   23295: #                            NORMAL RETURN, KEY1 GT THAN KEY2
                   23296: #      (XL,XR,WA,WB)         DESTROYED
                   23297: #
                   23298: sortc: #prc                    # entry point
                   23299:        movl    r6,srts1        # save offset 1
                   23300:        movl    r7,srts2        # save offset 2
                   23301:        movl    r8,srtsc        # save wc
                   23302:        addl2   srtof,r10       # add offset to comparand field
                   23303:        movl    r10,r9          # copy base + offset
                   23304:        addl2   r6,r10          # add key1 offset
                   23305:        addl2   r7,r9           # add key2 offset
                   23306:        movl    (r10),r10       # get key1
                   23307:        movl    (r9),r9         # get key2
                   23308:        cmpl    srtdf,$nulls    # jump if datatype field name used
                   23309:        beqlu   0f
                   23310:        jmp     src11
                   23311: 0:             
                   23312:        #page   
                   23313: #
                   23314: #      SORTC (CONTINUED)
                   23315: #
                   23316: #      MERGE AFTER DEALING WITH FIELD NAME. TRY FOR STRINGS.
                   23317: #
                   23318: src01: movl    (r10),r8        # get type code
                   23319:        cmpl    r8,(r9)         # skip if not same datatype
                   23320:        bnequ   src02
                   23321:        cmpl    r8,$b$scl       # jump if both strings
                   23322:        beqlu   src09
                   23323: #
                   23324: #      NOW TRY FOR NUMERIC
                   23325: #
                   23326: src02: movl    r10,r$sxl       # keep arg1
                   23327:        movl    r9,r$sxr        # keep arg2
                   23328:        movl    r10,-(sp)       # stack
                   23329:        movl    r9,-(sp)        # args
                   23330:        jsb     acomp           # compare objects
                   23331:        .long   src10           # not numeric
                   23332:        .long   src10           # not numeric
                   23333:        .long   src03           # key1 less
                   23334:        .long   src08           # keys equal
                   23335:        .long   src05           # key1 greater
                   23336: #
                   23337: #      RETURN IF KEY1 SMALLER (SORT), GREATER (RSORT)
                   23338: #
                   23339: src03: tstl    srtsr           # jump if rsort
                   23340:        bnequ   src06
                   23341: #
                   23342: src04: movl    srtsc,r8        # restore wc
                   23343:        movl    (sp)+,r11       # return
                   23344:        jmp     *(r11)+
                   23345: #
                   23346: #      RETURN IF KEY1 GREATER (SORT), SMALLER (RSORT)
                   23347: #
                   23348: src05: tstl    srtsr           # jump if rsort
                   23349:        bnequ   src04
                   23350: #
                   23351: src06: movl    srtsc,r8        # restore wc
                   23352:        addl2   $4*1,(sp)       # return
                   23353:        rsb     
                   23354: #
                   23355: #      KEYS ARE OF SAME DATATYPE
                   23356: #
                   23357: src07: cmpl    r10,r9          # item first created is less
                   23358:        blssu   src03
                   23359:        cmpl    r10,r9          # addresses rise in order of creation
                   23360:        bgtru   src05
                   23361: #
                   23362: #      DROP THROUGH OR MERGE FOR IDENTICAL OR EQUAL OBJECTS
                   23363: #
                   23364: src08: cmpl    srts1,srts2     # test offsets or key addrss instead
                   23365:        blssu   src04
                   23366:        jmp     src06           # offset 1 greater
                   23367:        #page   
                   23368: #
                   23369: #      SORTC (CONTINUED)
                   23370: #
                   23371: #      STRINGS
                   23372: #
                   23373: src09: movl    r10,-(sp)       # stack
                   23374:        movl    r9,-(sp)        # args
                   23375:        jsb     lcomp           # compare objects
                   23376:        .long   invalid$        # cant
                   23377:        .long   invalid$        # fail
                   23378:        .long   src03           # key1 less
                   23379:        .long   src08           # keys equal
                   23380:        .long   src05           # key1 greater
                   23381: #
                   23382: #      ARITHMETIC COMPARISON FAILED - RECOVER ARGS
                   23383: #
                   23384: src10: movl    r$sxl,r10       # get arg1
                   23385:        movl    r$sxr,r9        # get arg2
                   23386:        movl    (r10),r8        # get type of key1
                   23387:        cmpl    r8,(r9)         # jump if keys of same type
                   23388:        beqlu   src07
                   23389:        movl    r8,r10          # get block type word
                   23390:        movl    (r9),r9         # get block type word
                   23391:        movzwl  -2(r10),r10     # entry point id for key1
                   23392:        movzwl  -2(r9),r9       # entry point id for key2
                   23393:        cmpl    r10,r9          # jump if key1 gt key2
                   23394:        bgtru   src05
                   23395:        jmp     src03           # key1 lt key2
                   23396: #
                   23397: #      DATATYPE FIELD NAME USED
                   23398: #
                   23399: src11: jsb     sortf           # call routine to find field 1
                   23400:        movl    r10,-(sp)       # stack item pointer
                   23401:        movl    r9,r10          # get key2
                   23402:        jsb     sortf           # find field 2
                   23403:        movl    r10,r9          # place as key2
                   23404:        movl    (sp)+,r10       # recover key1
                   23405:        jmp     src01           # merge
                   23406:        #enp                    # procedure sortc
                   23407:        #page   
                   23408: #
                   23409: #      SORTF -- FIND FIELD FOR SORTC
                   23410: #
                   23411: #      ROUTINE USED BY SORTC TO OBTAIN ITEM CORRESPONDING
                   23412: #      TO A GIVEN FIELD NAME, IF THIS EXISTS, IN A PROGRAMMER
                   23413: #      DEFINED OBJECT PASSED AS ARGUMENT.
                   23414: #      IF SUCH A MATCH OCCURS, RECORD IS KEPT OF DATATYPE
                   23415: #      NAME, FIELD NAME AND OFFSET TO FIELD IN ORDER TO
                   23416: #      SHORT-CIRCUIT LATER SEARCHES ON SAME TYPE. NOTE THAT
                   23417: #      DFBLKS ARE STORED IN STATIC AND HENCE CANNOT BE MOVED.
                   23418: #
                   23419: #      (SRTDF)               VRBLK POINTER OF FIELD NAME
                   23420: #      (XL)                  POSSIBLE PDBLK POINTER
                   23421: #      JSR  SORTF            CALL TO SEARCH FOR FIELD NAME
                   23422: #      (XL)                  ITEM FOUND OR ORIGINAL PDBLK PTR
                   23423: #      (WC)                  DESTROYED
                   23424: #
                   23425: sortf: #prc                    # entry point
                   23426:        cmpl    (r10),$b$pdt    # return if not pdblk
                   23427:        bnequ   srtf3
                   23428:        movl    r9,-(sp)        # keep xr
                   23429:        movl    srtfd,r9        # get possible former dfblk ptr
                   23430:        tstl    r9              # jump if not
                   23431:        beqlu   srtf4
                   23432:        cmpl    r9,4*pddfp(r10) # jump if not right datatype
                   23433:        bnequ   srtf4
                   23434:        cmpl    srtdf,srtff     # jump if not right field name
                   23435:        bnequ   srtf4
                   23436:        addl2   srtfo,r10       # add offset to required field
                   23437: #
                   23438: #      HERE WITH XL POINTING TO FOUND FIELD
                   23439: #
                   23440: srtf1: movl    (r10),r10       # get item from field
                   23441: #
                   23442: #      RETURN POINT
                   23443: #
                   23444: srtf2: movl    (sp)+,r9        # restore xr
                   23445: #
                   23446: srtf3: rsb                     # return
                   23447:        #page   
                   23448: #
                   23449: #      SORTF (CONTINUED)
                   23450: #
                   23451: #      CONDUCT A SEARCH
                   23452: #
                   23453: srtf4: movl    r10,r9          # copy original pointer
                   23454:        movl    4*pddfp(r9),r9  # point to dfblk
                   23455:        movl    r9,srtfd        # keep a copy
                   23456:        movl    4*fargs(r9),r8  # get number of fields
                   23457:        moval   0[r8],r8        # convert to bytes
                   23458:        addl2   4*dflen(r9),r9  # point past last field
                   23459: #
                   23460: #      LOOP TO FIND NAME IN PDFBLK
                   23461: #
                   23462: srtf5: subl2   $4,r8           # count down
                   23463:        subl2   $4,r9           # point in front
                   23464:        cmpl    (r9),srtdf      # skip out if found
                   23465:        beqlu   srtf6
                   23466:        tstl    r8              # loop
                   23467:        bnequ   srtf5
                   23468:        jmp     srtf2           # return - not found
                   23469: #
                   23470: #      FOUND
                   23471: #
                   23472: srtf6: movl    (r9),srtff      # keep field name ptr
                   23473:        addl2   $4*pdfld,r8     # add offset to first field
                   23474:        movl    r8,srtfo        # store as field offset
                   23475:        addl2   r8,r10          # point to field
                   23476:        jmp     srtf1           # return
                   23477:        #enp                    # procedure sortf
                   23478:        #page   
                   23479: #
                   23480: #      SORTH -- HEAP ROUTINE FOR SORTA
                   23481: #
                   23482: #      THIS ROUTINE CONSTRUCTS A HEAP FROM ELEMENTS OF ARRAY, A.
                   23483: #      IN THIS APPLICATION, THE ELEMENTS ARE OFFSETS TO KEYS IN
                   23484: #      A KEY ARRAY.
                   23485: #
                   23486: #      (XS)                  POINTER TO SORT ARRAY BASE
                   23487: #      1(XS)                 POINTER TO KEY ARRAY BASE
                   23488: #      (WA)                  MAX ARRAY INDEX, N (IN BYTES)
                   23489: #      (WC)                  OFFSET J IN A TO ROOT (IN *1 TO *N)
                   23490: #      JSR  SORTH            CALL SORTH(J,N) TO MAKE HEAP
                   23491: #      (XL,XR,WB)            DESTROYED
                   23492: #
                   23493:        .data   1
                   23494: sorth_s:       .long   0
                   23495:        .text   0
                   23496: sorth: movl    (sp)+,sorth_s   # entry point
                   23497:        movl    r6,srtsn        # save n
                   23498:        movl    r8,srtwc        # keep wc
                   23499:        movl    (sp),r10        # sort array base adrs
                   23500:        addl2   srtso,r10       # add offset to a(0)
                   23501:        addl2   r8,r10          # point to a(j)
                   23502:        movl    (r10),srtrt     # get offset to root
                   23503:        addl2   r8,r8           # double j - cant exceed n
                   23504: #
                   23505: #      LOOP TO MOVE DOWN TREE USING DOUBLED INDEX J
                   23506: #
                   23507: srh01: cmpl    r8,srtsn        # done if j gt n
                   23508:        bgtru   srh03
                   23509:        cmpl    r8,srtsn        # skip if j equals n
                   23510:        beqlu   srh02
                   23511:        movl    (sp),r9         # sort array base adrs
                   23512:        movl    4*1(sp),r10     # key array base adrs
                   23513:        addl2   srtso,r9        # point to a(0)
                   23514:        addl2   r8,r9           # adrs of a(j)
                   23515:        movl    4*1(r9),r6      # get a(j+1)
                   23516:        movl    (r9),r7         # get a(j)
                   23517: #
                   23518: #      COMPARE SONS. (WA) RIGHT SON, (WB) LEFT SON
                   23519: #
                   23520:        jsb     sortc           # compare keys - lt(a(j+1),a(j))
                   23521:        .long   srh02           # a(j+1) lt a(j)
                   23522:        addl2   $4,r8           # point to greater son, a(j+1)
                   23523:        #page   
                   23524: #
                   23525: #      SORTH (CONTINUED)
                   23526: #
                   23527: #      COMPARE ROOT WITH GREATER SON
                   23528: #
                   23529: srh02: movl    4*1(sp),r10     # key array base adrs
                   23530:        movl    (sp),r9         # get sort array address
                   23531:        addl2   srtso,r9        # adrs of a(0)
                   23532:        movl    r9,r7           # copy this adrs
                   23533:        addl2   r8,r9           # adrs of greater son, a(j)
                   23534:        movl    (r9),r6         # get a(j)
                   23535:        movl    r7,r9           # point back to a(0)
                   23536:        movl    srtrt,r7        # get root
                   23537:        jsb     sortc           # compare them - lt(a(j),root)
                   23538:        .long   srh03           # father exceeds sons - done
                   23539:        movl    (sp),r9         # get sort array adrs
                   23540:        addl2   srtso,r9        # point to a(0)
                   23541:        movl    r9,r10          # copy it
                   23542:        movl    r8,r6           # copy j
                   23543:        ashl    $-2,r8,r8       # convert to words
                   23544:        ashl    $-1,r8,r8       # get j/2
                   23545:        moval   0[r8],r8        # convert back to bytes
                   23546:        addl2   r6,r10          # point to a(j)
                   23547:        addl2   r8,r9           # adrs of a(j/2)
                   23548:        movl    (r10),(r9)      # a(j/2) = a(j)
                   23549:        movl    r6,r8           # recover j
                   23550:        addl2   r8,r8           # j = j*2. done if too big
                   23551:        bvc     0f
                   23552:        jmp     srh03
                   23553: 0:             
                   23554:        jmp     srh01           # loop
                   23555: #
                   23556: #      FINISH BY COPYING ROOT OFFSET BACK INTO ARRAY
                   23557: #
                   23558: srh03: ashl    $-2,r8,r8       # convert to words
                   23559:        ashl    $-1,r8,r8       # j = j/2
                   23560:        moval   0[r8],r8        # convert back to bytes
                   23561:        movl    (sp),r9         # sort array adrs
                   23562:        addl2   srtso,r9        # adrs of a(0)
                   23563:        addl2   r8,r9           # adrs of a(j/2)
                   23564:        movl    srtrt,(r9)      # a(j/2) = root
                   23565:        movl    srtsn,r6        # restore wa
                   23566:        movl    srtwc,r8        # restore wc
                   23567:        jmp     *sorth_s        # return
                   23568:        #enp                    # end procedure sorth
                   23569:        #page   
                   23570:        #page   
                   23571: #
                   23572: #      TFIND -- LOCATE TABLE ELEMENT
                   23573: #
                   23574: #      (XR)                  SUBSCRIPT VALUE FOR ELEMENT
                   23575: #      (XL)                  POINTER TO TABLE
                   23576: #      (WB)                  ZERO BY VALUE, NON-ZERO BY NAME
                   23577: #      JSR  TFIND            CALL TO LOCATE ELEMENT
                   23578: #      PPM  LOC              TRANSFER LOCATION IF ACCESS FAILS
                   23579: #      (XR)                  ELEMENT VALUE (IF BY VALUE)
                   23580: #      (XR)                  DESTROYED (IF BY NAME)
                   23581: #      (XL,WA)               TEBLK NAME (IF BY NAME)
                   23582: #      (XL,WA)               DESTROYED (IF BY VALUE)
                   23583: #      (WC,RA)               DESTROYED
                   23584: #
                   23585: #      NOTE THAT IF A CALL BY VALUE SPECIFIES A NON-EXISTENT
                   23586: #      SUBSCRIPT, NULL IS RETURNED WITHOUT BUILDING A NEW TEBLK.
                   23587: #
                   23588: tfind: #prc                    # entry point
                   23589:        movl    r7,-(sp)        # save name/value indicator
                   23590:        movl    r9,-(sp)        # save subscript value
                   23591:        movl    r10,-(sp)       # save table pointer
                   23592:        movl    4*tblen(r10),r6 # load length of tbblk
                   23593:        ashl    $-2,r6,r6       # convert to word count
                   23594:        subl2   $tbbuk,r6       # get number of buckets
                   23595:        movl    r6,r5           # convert to integer value
                   23596:        movl    r5,tfnsi        # save for later
                   23597:        movl    (r9),r10        # load first word of subscript
                   23598:        movzwl  -2(r10),r10     # load block entry id (bl$xx)
                   23599:        casel   r10,$0,$bl$$d   # switch on block type
                   23600: 5:             
                   23601:        .word   tfn00-5b
                   23602:        .word   tfn00-5b
                   23603:        .word   tfn00-5b
                   23604:        .word   tfn00-5b
                   23605:        .word   tfn02-5b        # jump if integer
                   23606:        .word   tfn04-5b        # jump if name
                   23607:        .word   tfn03-5b        # jump if pattern
                   23608:        .word   tfn03-5b        # jump if pattern
                   23609:        .word   tfn03-5b        # jump if pattern
                   23610:        .word   tfn02-5b        # real
                   23611:        .word   tfn05-5b        # jump if string
                   23612:        .word   tfn00-5b
                   23613:        .word   tfn00-5b
                   23614:        .word   tfn00-5b
                   23615:        .word   tfn00-5b
                   23616:        .word   tfn00-5b
                   23617:        .word   tfn00-5b
                   23618:        #esw                    # end switch on block type
                   23619: #
                   23620: #      HERE FOR BLOCKS FOR WHICH WE USE THE SECOND WORD OF THE
                   23621: #      BLOCK AS THE HASH SOURCE (SEE BLOCK FORMATS FOR DETAILS).
                   23622: #
                   23623: tfn00: movl    4*1(r9),r6      # load second word
                   23624: #
                   23625: #      MERGE HERE WITH ONE WORD HASH SOURCE IN WA
                   23626: #
                   23627: tfn01: movl    r6,r5           # convert to integer
                   23628:        jmp     tfn06           # jump to merge
                   23629:        #page   
                   23630: #
                   23631: #      TFIND (CONTINUED)
                   23632: #
                   23633: #      HERE FOR INTEGER OR REAL
                   23634: #
                   23635: tfn02: movl    4*1(r9),r5      # load value as hash source
                   23636:        tstl    r5              # ok if positive or zero
                   23637:        bgeq    tfn06
                   23638:        mnegl   r5,r5           # make positive
                   23639:        bvs     tfn06
                   23640:        jmp     tfn06           # merge
                   23641: #
                   23642: #      FOR PATTERN, USE FIRST WORD (PCODE) AS SOURCE
                   23643: #
                   23644: tfn03: movl    (r9),r6         # load first word as hash source
                   23645:        jmp     tfn01           # merge back
                   23646: #
                   23647: #      FOR NAME, USE OFFSET AS HASH SOURCE
                   23648: #
                   23649: tfn04: movl    4*nmofs(r9),r6  # load offset as hash source
                   23650:        jmp     tfn01           # merge back
                   23651: #
                   23652: #      HERE FOR STRING
                   23653: #
                   23654: tfn05: jsb     hashs           # call routine to compute hash
                   23655: #
                   23656: #      MERGE HERE WITH HASH SOURCE IN (IA)
                   23657: #
                   23658: tfn06: ashq    $-32,r4,r4      # compute hash index by remaindering
                   23659:        ediv    tfnsi,r4,r11,r5
                   23660:        movl    r5,r8           # get as one word integer
                   23661:        moval   0[r8],r8        # convert to byte offset
                   23662:        movl    (sp),r10        # get table ptr again
                   23663:        addl2   r8,r10          # point to proper bucket
                   23664:        movl    4*tbbuk(r10),r9 # load first teblk pointer
                   23665:        cmpl    r9,(sp)         # jump if no teblks on chain
                   23666:        beqlu   tfn10
                   23667: #
                   23668: #      LOOP THROUGH TEBLKS ON HASH CHAIN
                   23669: #
                   23670: tfn07: movl    r9,r7           # save teblk pointer
                   23671:        movl    4*tesub(r9),r9  # load subscript value
                   23672:        movl    4*1(sp),r10     # load input argument subscript val
                   23673:        jsb     ident           # compare them
                   23674:        .long   tfn08           # jump if equal (ident)
                   23675: #
                   23676: #      HERE IF NO MATCH WITH THAT TEBLK
                   23677: #
                   23678:        movl    r7,r10          # restore teblk pointer
                   23679:        movl    4*tenxt(r10),r9 # point to next teblk on chain
                   23680:        cmpl    r9,(sp)         # jump if there is one
                   23681:        bnequ   tfn07
                   23682: #
                   23683: #      HERE IF NO MATCH WITH ANY TEBLK ON CHAIN
                   23684: #
                   23685:        movl    $4*tenxt,r8     # set offset to link field (xl base)
                   23686:        jmp     tfn11           # jump to merge
                   23687:        #page   
                   23688: #
                   23689: #      TFIND (CONTINUED)
                   23690: #
                   23691: #      HERE WE HAVE FOUND A MATCHING ELEMENT
                   23692: #
                   23693: tfn08: movl    r7,r10          # restore teblk pointer
                   23694:        movl    $4*teval,r6     # set teblk name offset
                   23695:        movl    4*2(sp),r7      # restore name/value indicator
                   23696:        tstl    r7              # jump if called by name
                   23697:        bnequ   tfn09
                   23698:        jsb     acess           # else get value
                   23699:        .long   tfn12           # jump if reference fails
                   23700:        clrl    r7              # restore name/value indicator
                   23701: #
                   23702: #      COMMON EXIT FOR ENTRY FOUND
                   23703: #
                   23704: tfn09: addl2   $4*num03,sp     # pop stack entries
                   23705:        addl2   $4*1,(sp)       # return to tfind caller
                   23706:        rsb     
                   23707: #
                   23708: #      HERE IF NO TEBLKS ON THE HASH CHAIN
                   23709: #
                   23710: tfn10: addl2   $4*tbbuk,r8     # get offset to bucket ptr
                   23711:        movl    (sp),r10        # set tbblk ptr as base
                   23712: #
                   23713: #      MERGE HERE WITH (XL,WC) BASE,OFFSET OF FINAL LINK
                   23714: #
                   23715: tfn11: movl    (sp),r9         # tbblk pointer
                   23716:        movl    4*tbinv(r9),r9  # load default value in case
                   23717:        movl    4*2(sp),r7      # load name/value indicator
                   23718:        tstl    r7              # exit with default if value call
                   23719:        beqlu   tfn09
                   23720: #
                   23721: #      HERE WE MUST BUILD A NEW TEBLK
                   23722: #
                   23723:        movl    $4*tesi$,r6     # set size of teblk
                   23724:        jsb     alloc           # allocate teblk
                   23725:        addl2   r8,r10          # point to hash link
                   23726:        movl    r9,(r10)        # link new teblk at end of chain
                   23727:        movl    $b$tet,(r9)     # store type word
                   23728:        movl    $nulls,4*teval(r9) # set null as initial value
                   23729:        movl    (sp)+,4*tenxt(r9)# set tbblk ptr to mark end of chain
                   23730:        movl    (sp)+,4*tesub(r9)# store subscript value
                   23731:        addl2   $4,sp           # pop past name/value indicator
                   23732:        movl    r9,r10          # copy teblk pointer (name base)
                   23733:        movl    $4*teval,r6     # set offset
                   23734:        addl2   $4*1,(sp)       # return to caller with new teblk
                   23735:        rsb     
                   23736: #
                   23737: #      ACESS FAIL RETURN
                   23738: #
                   23739: tfn12: movl    (sp)+,r11       # alternative return
                   23740:        jmp     *(r11)+
                   23741:        #enp                    # end procedure tfind
                   23742:        #page   
                   23743: #
                   23744: #      TRACE -- SET/RESET A TRACE ASSOCIATION
                   23745: #
                   23746: #      THIS PROCEDURE IS SHARED BY TRACE AND STOPTR TO
                   23747: #      EITHER INITIATE OR STOP A TRACE RESPECTIVELY.
                   23748: #
                   23749: #      (XL)                  TRBLK PTR (TRACE) OR ZERO (STOPTR)
                   23750: #      1(XS)                 FIRST ARGUMENT (NAME)
                   23751: #      0(XS)                 SECOND ARGUMENT (TRACE TYPE)
                   23752: #      JSR  TRACE            CALL TO SET/RESET TRACE
                   23753: #      PPM  LOC              TRANSFER LOC IF 1ST ARG IS BAD NAME
                   23754: #      PPM  LOC              TRANSFER LOC IF 2ND ARG IS BAD TYPE
                   23755: #      (XS)                  POPPED
                   23756: #      (XL,XR,WA,WB,WC,IA)   DESTROYED
                   23757: #
                   23758:        .data   1
                   23759: trace_s:       .long   0
                   23760:        .text   0
                   23761: trace: movl    (sp)+,trace_s   # entry point
                   23762:        jsb     gtstg           # get trace type string
                   23763:        .long   trc15           # jump if not string
                   23764:        movab   cfp$f(r9),r9    # else point to string
                   23765:        movzbl  (r9),r6         # load first character
                   23766:        bicl2   $ch$bl,r6       # fold to upper case
                   23767:        movl    (sp),r9         # load name argument
                   23768:        movl    r10,(sp)        # stack trblk ptr or zero
                   23769:        movl    $trtac,r8       # set trtyp for access trace
                   23770:        cmpl    r6,$ch$la       # jump if a (access)
                   23771:        bnequ   0f
                   23772:        jmp     trc10
                   23773: 0:             
                   23774:        movl    $trtvl,r8       # set trtyp for value trace
                   23775:        cmpl    r6,$ch$lv       # jump if v (value)
                   23776:        bnequ   0f
                   23777:        jmp     trc10
                   23778: 0:             
                   23779:        tstl    r6              # jump if blank (value)
                   23780:        bnequ   0f
                   23781:        jmp     trc10
                   23782: 0:             
                   23783: #
                   23784: #      HERE FOR L,K,F,C,R
                   23785: #
                   23786:        cmpl    r6,$ch$lf       # jump if f (function)
                   23787:        beqlu   trc01
                   23788:        cmpl    r6,$ch$lr       # jump if r (return)
                   23789:        beqlu   trc01
                   23790:        cmpl    r6,$ch$ll       # jump if l (label)
                   23791:        beqlu   trc03
                   23792:        cmpl    r6,$ch$lk       # jump if k (keyword)
                   23793:        bnequ   0f
                   23794:        jmp     trc06
                   23795: 0:             
                   23796:        cmpl    r6,$ch$lc       # else error if not c (call)
                   23797:        beqlu   0f
                   23798:        jmp     trc15
                   23799: 0:             
                   23800: #
                   23801: #      HERE FOR F,C,R
                   23802: #
                   23803: trc01: jsb     gtnvr           # point to vrblk for name
                   23804:        .long   trc16           # jump if bad name
                   23805:        addl2   $4,sp           # pop stack
                   23806:        movl    4*vrfnc(r9),r9  # point to function block
                   23807:        cmpl    (r9),$b$pfc     # error if not program function
                   23808:        beqlu   0f
                   23809:        jmp     trc17
                   23810: 0:             
                   23811:        cmpl    r6,$ch$lr       # jump if r (return)
                   23812:        beqlu   trc02
                   23813:        #page   
                   23814: #
                   23815: #      TRACE (CONTINUED)
                   23816: #
                   23817: #      HERE FOR F,C TO SET/RESET CALL TRACE
                   23818: #
                   23819:        movl    r10,4*pfctr(r9) # set/reset call trace
                   23820:        cmpl    r6,$ch$lc       # exit with null if c (call)
                   23821:        bnequ   0f
                   23822:        jmp     exnul
                   23823: 0:             
                   23824: #
                   23825: #      HERE FOR F,R TO SET/RESET RETURN TRACE
                   23826: #
                   23827: trc02: movl    r10,4*pfrtr(r9) # set/reset return trace
                   23828:        addl3   $4*2,trace_s,r11        # return
                   23829:        jmp     (r11)
                   23830: #
                   23831: #      HERE FOR L TO SET/RESET LABEL TRACE
                   23832: #
                   23833: trc03: jsb     gtnvr           # point to vrblk
                   23834:        .long   trc16           # jump if bad name
                   23835:        movl    4*vrlbl(r9),r10 # load label pointer
                   23836:        cmpl    (r10),$b$trt    # jump if no old trace
                   23837:        bnequ   trc04
                   23838:        movl    4*trlbl(r10),r10# else delete old trace association
                   23839: #
                   23840: #      HERE WITH OLD LABEL TRACE ASSOCIATION DELETED
                   23841: #
                   23842: trc04: cmpl    r10,$stndl      # error if undefined label
                   23843:        bnequ   0f
                   23844:        jmp     trc16
                   23845: 0:             
                   23846:        movl    (sp)+,r7        # get trblk ptr again
                   23847:        tstl    r7              # jump if stoptr case
                   23848:        beqlu   trc05
                   23849:        movl    r7,4*vrlbl(r9)  # else set new trblk pointer
                   23850:        movl    $b$vrt,4*vrtra(r9) # set label trace routine address
                   23851:        movl    r7,r9           # copy trblk pointer
                   23852:        movl    r10,4*trlbl(r9) # store real label in trblk
                   23853:        addl3   $4*2,trace_s,r11        # return
                   23854:        jmp     (r11)
                   23855: #
                   23856: #      HERE FOR STOPTR CASE FOR LABEL
                   23857: #
                   23858: trc05: movl    r10,4*vrlbl(r9) # store label ptr back in vrblk
                   23859:        movl    $b$vrg,4*vrtra(r9) # store normal transfer address
                   23860:        addl3   $4*2,trace_s,r11        # return
                   23861:        jmp     (r11)
                   23862:        #page   
                   23863: #
                   23864: #      TRACE (CONTINUED)
                   23865: #
                   23866: #      HERE FOR K (KEYWORD)
                   23867: #
                   23868: trc06: jsb     gtnvr           # point to vrblk
                   23869:        .long   trc16           # error if not natural var
                   23870:        tstl    4*vrlen(r9)     # error if not system var
                   23871:        beqlu   0f
                   23872:        jmp     trc16
                   23873: 0:             
                   23874:        addl2   $4,sp           # pop stack
                   23875:        tstl    r10             # jump if stoptr case
                   23876:        beqlu   trc07
                   23877:        movl    r9,4*trkvr(r10) # store vrblk ptr in trblk for ktrex
                   23878: #
                   23879: #      MERGE HERE WITH TRBLK SET UP IN WB (OR ZERO)
                   23880: #
                   23881: trc07: movl    4*vrsvp(r9),r9  # point to svblk
                   23882:        cmpl    r9,$v$ert       # jump if errtype
                   23883:        beqlu   trc08
                   23884:        cmpl    r9,$v$stc       # jump if stcount
                   23885:        beqlu   trc09
                   23886:        cmpl    r9,$v$fnc       # else error if not fnclevel
                   23887:        beqlu   0f
                   23888:        jmp     trc17
                   23889: 0:             
                   23890: #
                   23891: #      FNCLEVEL
                   23892: #
                   23893:        movl    r10,r$fnc       # set/reset fnclevel trace
                   23894:        addl3   $4*2,trace_s,r11        # return
                   23895:        jmp     (r11)
                   23896: #
                   23897: #      ERRTYPE
                   23898: #
                   23899: trc08: movl    r10,r$ert       # set/reset errtype trace
                   23900:        addl3   $4*2,trace_s,r11        # return
                   23901:        jmp     (r11)
                   23902: #
                   23903: #      STCOUNT
                   23904: #
                   23905: trc09: movl    r10,r$stc       # set/reset stcount trace
                   23906:        addl3   $4*2,trace_s,r11        # return
                   23907:        jmp     (r11)
                   23908:        #page   
                   23909: #
                   23910: #      TRACE (CONTINUED)
                   23911: #
                   23912: #      A,V MERGE HERE WITH TRTYP VALUE IN WC
                   23913: #
                   23914: trc10: jsb     gtvar           # locate variable
                   23915:        .long   trc16           # error if not appropriate name
                   23916:        movl    (sp)+,r7        # get new trblk ptr again
                   23917:        addl2   r10,r6          # point to variable location
                   23918:        movl    r6,r9           # copy variable pointer
                   23919: #
                   23920: #      LOOP TO SEARCH TRBLK CHAIN
                   23921: #
                   23922: trc11: movl    (r9),r10        # point to next entry
                   23923:        cmpl    (r10),$b$trt    # jump if not trblk
                   23924:        bnequ   trc13
                   23925:        cmpl    r8,4*trtyp(r10) # jump if too far out on chain
                   23926:        blssu   trc13
                   23927:        cmpl    r8,4*trtyp(r10) # jump if this matches our type
                   23928:        beqlu   trc12
                   23929:        addl2   $4*trnxt,r10    # else point to link field
                   23930:        movl    r10,r9          # copy pointer
                   23931:        jmp     trc11           # and loop back
                   23932: #
                   23933: #      HERE TO DELETE AN OLD TRBLK OF THE TYPE WE WERE GIVEN
                   23934: #
                   23935: trc12: movl    4*trnxt(r10),r10# get ptr to next block or value
                   23936:        movl    r10,(r9)        # store to delete this trblk
                   23937: #
                   23938: #      HERE AFTER DELETING ANY OLD ASSOCIATION OF THIS TYPE
                   23939: #
                   23940: trc13: tstl    r7              # jump if stoptr case
                   23941:        beqlu   trc14
                   23942:        movl    r7,(r9)         # else link new trblk in
                   23943:        movl    r7,r9           # copy trblk pointer
                   23944:        movl    r10,4*trnxt(r9) # store forward pointer
                   23945:        movl    r8,4*trtyp(r9)  # store appropriate trap type code
                   23946: #
                   23947: #      HERE TO MAKE SURE VRGET,VRSTO ARE SET PROPERLY
                   23948: #
                   23949: trc14: movl    r6,r9           # recall possible vrblk pointer
                   23950:        subl2   $4*vrval,r9     # point back to vrblk
                   23951:        jsb     setvr           # set fields if vrblk
                   23952:        addl3   $4*2,trace_s,r11        # return
                   23953:        jmp     (r11)
                   23954: #
                   23955: #      HERE FOR BAD TRACE TYPE
                   23956: #
                   23957: trc15: addl3   $4*1,trace_s,r11        # take bad trace type error exit
                   23958:        jmp     *(r11)+
                   23959: #
                   23960: #      POP STACK BEFORE FAILING
                   23961: #
                   23962: trc16: addl2   $4,sp           # pop stack
                   23963: #
                   23964: #      HERE FOR BAD NAME ARGUMENT
                   23965: #
                   23966: trc17: movl    trace_s,r11     # take bad name error exit
                   23967:        jmp     *(r11)+
                   23968:        #enp                    # end procedure trace
                   23969:        #page   
                   23970: #
                   23971: #      TRBLD -- BUILD TRBLK
                   23972: #
                   23973: #      TRBLK IS USED BY THE INPUT, OUTPUT AND TRACE FUNCTIONS
                   23974: #      TO CONSTRUCT A TRBLK (TRAP BLOCK)
                   23975: #
                   23976: #      (XR)                  TRTAG OR TRTER
                   23977: #      (XL)                  TRFNC OR TRFPT
                   23978: #      (WB)                  TRTYP
                   23979: #      JSR  TRBLD            CALL TO BUILD TRBLK
                   23980: #      (XR)                  POINTER TO TRBLK
                   23981: #      (WA)                  DESTROYED
                   23982: #
                   23983: trbld: #prc                    # entry point
                   23984:        movl    r9,-(sp)        # stack trtag (or trfnm)
                   23985:        movl    $4*trsi$,r6     # set size of trblk
                   23986:        jsb     alloc           # allocate trblk
                   23987:        movl    $b$trt,(r9)     # store first word
                   23988:        movl    r10,4*trfnc(r9) # store trfnc (or trfpt)
                   23989:        movl    (sp)+,4*trtag(r9)# store trtag (or trfnm)
                   23990:        movl    r7,4*trtyp(r9)  # store type
                   23991:        movl    $nulls,4*trval(r9) # for now, a null value
                   23992:        rsb                     # return to caller
                   23993:        #enp                    # end procedure trbld
                   23994:        #page   
                   23995: #
                   23996: #      TRIMR -- TRIM TRAILING BLANKS
                   23997: #
                   23998: #      TRIMR IS PASSED A POINTER TO AN SCBLK WHICH MUST BE THE
                   23999: #      LAST BLOCK IN DYNAMIC STORAGE. TRAILING BLANKS ARE
                   24000: #      TRIMMED OFF AND THE DYNAMIC STORAGE POINTER RESET TO
                   24001: #      THE END OF THE (POSSIBLY) SHORTENED BLOCK.
                   24002: #
                   24003: #      (WB)                  NON-ZERO TO TRIM TRAILING BLANKS
                   24004: #      (XR)                  POINTER TO STRING TO TRIM
                   24005: #      JSR  TRIMR            CALL TO TRIM STRING
                   24006: #      (XR)                  POINTER TO TRIMMED STRING
                   24007: #      (XL,WA,WB,WC)         DESTROYED
                   24008: #
                   24009: #      THE CALL WITH WB ZERO STILL PERFORMS THE END ZERO PAD
                   24010: #      AND DNAMP READJUSTMENT. IT IS USED FROM ACESS IF KVTRM=0.
                   24011: #
                   24012: trimr: #prc                    # entry point
                   24013:        movl    r9,r10          # copy string pointer
                   24014:        movl    4*sclen(r9),r6  # load string length
                   24015:        tstl    r6              # jump if null input
                   24016:        beqlu   trim2
                   24017:        movab   cfp$f(r10)[r6],r10 # else point past last character
                   24018:        tstl    r7              # jump if no trim
                   24019:        beqlu   trim3
                   24020:        movl    $ch$bl,r8       # load blank character
                   24021: #
                   24022: #      LOOP THROUGH CHARACTERS FROM RIGHT TO LEFT
                   24023: #
                   24024: trim0: movzbl  -(r10),r7       # load next character
                   24025:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   24026:        beqlu   trim1
                   24027:        cmpl    r7,r8           # jump if non-blank found
                   24028:        bnequ   trim3
                   24029: trim1: decl    r6              # else decrement character count
                   24030:        tstl    r6              # loop back if more to check
                   24031:        bnequ   trim0
                   24032: #
                   24033: #      HERE IF RESULT IS NULL (NULL OR ALL-BLANK INPUT)
                   24034: #
                   24035: trim2: movl    r9,dnamp        # wipe out input string block
                   24036:        movl    $nulls,r9       # load null result
                   24037:        jmp     trim5           # merge to exit
                   24038:        #page   
                   24039: #
                   24040: #      TRIMR (CONTINUED)
                   24041: #
                   24042: #      HERE WITH NON-BLANK FOUND (MERGE FOR NO TRIM)
                   24043: #
                   24044: trim3: movl    r6,4*sclen(r9)  # set new length
                   24045:        movl    r9,r10          # copy string pointer
                   24046:        movab   cfp$f(r10)[r6],r10 # ready for storing blanks
                   24047:        movab   3+(4*schar)(r6),r6 # get length of block in bytes
                   24048:        bicl2   $3,r6
                   24049:        addl2   r9,r6           # point past new block
                   24050:        movl    r6,dnamp        # set new top of storage pointer
                   24051:        movl    $cfp$c,r6       # get count of chars in word
                   24052:        clrl    r8              # set blank char
                   24053: #
                   24054: #      LOOP TO ZERO PAD LAST WORD OF CHARACTERS
                   24055: #
                   24056: trim4: movb    r8,(r10)+       # store zero character
                   24057:        sobgtr  r6,trim4        # loop back till all stored
                   24058:        #csc    r10             # complete store characters
                   24059: #
                   24060: #      COMMON EXIT POINT
                   24061: #
                   24062: trim5: clrl    r10             # clear garbage xl pointer
                   24063:        rsb                     # return to caller
                   24064:        #enp                    # end procedure trimr
                   24065:        #page   
                   24066: #
                   24067: #      TRXEQ -- EXECUTE FUNCTION TYPE TRACE
                   24068: #
                   24069: #      TRXEQ IS USED TO EXECUTE A TRACE WHEN A FOURTH ARGUMENT
                   24070: #      HAS BEEN SUPPLIED. TRACE HAS ALREADY BEEN DECREMENTED.
                   24071: #
                   24072: #      (XR)                  POINTER TO TRBLK
                   24073: #      (XL,WA)               NAME BASE,OFFSET FOR VARIABLE
                   24074: #      JSR  TRXEQ            CALL TO EXECUTE TRACE
                   24075: #      (WB,WC,RA)            DESTROYED
                   24076: #
                   24077: #      THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING
                   24078: #      CONTROL TO THE TRACE FUNCTION USING THE CFUNC ROUTINE.
                   24079: #
                   24080: #                            TRXEQ RETURN POINT WORD(S)
                   24081: #                            SAVED VALUE OF TRACE KEYWORD
                   24082: #                            TRBLK POINTER
                   24083: #                            NAME BASE
                   24084: #                            NAME OFFSET
                   24085: #                            SAVED VALUE OF R$COD
                   24086: #                            SAVED CODE PTR (-R$COD)
                   24087: #                            SAVED VALUE OF FLPTR
                   24088: #      FLPTR --------------- ZERO (DUMMY FAIL OFFSET)
                   24089: #                            NMBLK FOR VARIABLE NAME
                   24090: #      XS ------------------ TRACE TAG
                   24091: #
                   24092: #      R$COD AND THE CODE PTR ARE SET TO DUMMY VALUES WHICH
                   24093: #      CAUSE CONTROL TO RETURN TO THE TRXEQ PROCEDURE ON SUCCESS
                   24094: #      OR FAILURE (TRXEQ IGNORES A FAILURE CONDITION).
                   24095: #
                   24096: trxeq: #prc                    # entry point (recursive)
                   24097:        movl    r$cod,r8        # load code block pointer
                   24098:        movl    r3,r7           # get current code pointer
                   24099:        subl2   r8,r7           # make code pointer into offset
                   24100:        movl    kvtra,-(sp)     # stack trace keyword value
                   24101:        movl    r9,-(sp)        # stack trblk pointer
                   24102:        movl    r10,-(sp)       # stack name base
                   24103:        movl    r6,-(sp)        # stack name offset
                   24104:        movl    r8,-(sp)        # stack code block pointer
                   24105:        movl    r7,-(sp)        # stack code pointer offset
                   24106:        movl    flptr,-(sp)     # stack old failure pointer
                   24107:        clrl    -(sp)           # set dummy fail offset
                   24108:        movl    sp,flptr        # set new failure pointer
                   24109:        clrl    kvtra           # reset trace keyword to zero
                   24110:        movl    $trxdc,r8       # load new (dummy) code blk pointer
                   24111:        movl    r8,r$cod        # set as code block pointer
                   24112:        movl    r8,r3           # and new code pointer
                   24113:        #page   
                   24114: #
                   24115: #      TRXEQ (CONTINUED)
                   24116: #
                   24117: #      NOW PREPARE ARGUMENTS FOR FUNCTION
                   24118: #
                   24119:        movl    r6,r7           # save name offset
                   24120:        movl    $4*nmsi$,r6     # load nmblk size
                   24121:        jsb     alloc           # allocate space for nmblk
                   24122:        movl    $b$nml,(r9)     # set type word
                   24123:        movl    r10,4*nmbas(r9) # store name base
                   24124:        movl    r7,4*nmofs(r9)  # store name offset
                   24125:        movl    4*6(sp),r10     # reload pointer to trblk
                   24126:        movl    r9,-(sp)        # stack nmblk pointer (1st argument)
                   24127:        movl    4*trtag(r10),-(sp) # stack trace tag (2nd argument)
                   24128:        movl    4*trfnc(r10),r10# load trace function pointer
                   24129:        movl    $num02,r6       # set number of arguments to two
                   24130:        jmp     cfunc           # jump to call function
                   24131: #
                   24132: #      SEE O$TXR FOR DETAILS OF RETURN TO THIS POINT
                   24133: #
                   24134: trxq1: movl    flptr,sp        # point back to our stack entries
                   24135:        addl2   $4,sp           # pop off garbage fail offset
                   24136:        movl    (sp)+,flptr     # restore old failure pointer
                   24137:        movl    (sp)+,r7        # reload code offset
                   24138:        movl    (sp)+,r8        # load old code base pointer
                   24139:        movl    r8,r9           # copy cdblk pointer
                   24140:        movl    4*cdstm(r9),kvstn# restore stmnt no
                   24141:        movl    (sp)+,r6        # reload name offset
                   24142:        movl    (sp)+,r10       # reload name base
                   24143:        movl    (sp)+,r9        # reload trblk pointer
                   24144:        movl    (sp)+,kvtra     # restore trace keyword value
                   24145:        addl2   r8,r7           # recompute absolute code pointer
                   24146:        movl    r7,r3           # restore code pointer
                   24147:        movl    r8,r$cod        # and code block pointer
                   24148:        rsb                     # return to trxeq caller
                   24149:        #enp                    # end procedure trxeq
                   24150:        #page   
                   24151: #
                   24152: #      XSCAN -- EXECUTION FUNCTION ARGUMENT SCAN
                   24153: #
                   24154: #      XSCAN SCANS OUT ONE TOKEN IN A PROTOTYPE ARGUMENT IN
                   24155: #      ARRAY,CLEAR,DATA,DEFINE,LOAD FUNCTION CALLS. XSCAN
                   24156: #      CALLS MUST BE PRECEDED BY A CALL TO THE INITIALIZATION
                   24157: #      PROCEDURE XSCNI. THE FOLLOWING VARIABLES ARE USED.
                   24158: #
                   24159: #      R$XSC                 POINTER TO SCBLK FOR FUNCTION ARG
                   24160: #      XSOFS                 OFFSET (NUM CHARS SCANNED SO FAR)
                   24161: #
                   24162: #      (WC)                  DELIMITER ONE (CH$XX)
                   24163: #      (XL)                  DELIMITER TWO (CH$XX)
                   24164: #      JSR  XSCAN            CALL TO SCAN NEXT ITEM
                   24165: #      (XR)                  POINTER TO SCBLK FOR TOKEN SCANNED
                   24166: #      (WA)                  COMPLETION CODE (SEE BELOW)
                   24167: #      (WC,XL)               DESTROYED
                   24168: #
                   24169: #      THE SCAN STARTS FROM THE CURRENT POSITION AND CONTINUES
                   24170: #      UNTIL ONE OF THE FOLLOWING THREE CONDITIONS OCCURS.
                   24171: #
                   24172: #      1)   DELIMITER ONE IS ENCOUNTERED  (WA SET TO 1)
                   24173: #
                   24174: #      2)   DELIMITER TWO ENCOUNTERED  (WA SET TO 2)
                   24175: #
                   24176: #      3)   END OF STRING ENCOUNTERED  (WA SET TO 0)
                   24177: #
                   24178: #      THE RESULT IS A STRING CONTAINING ALL CHARACTERS SCANNED
                   24179: #      UP TO BUT NOT INCLUDING ANY DELIMITER CHARACTER.
                   24180: #      THE POINTER IS LEFT POINTING PAST THE DELIMITER.
                   24181: #
                   24182: #      IF ONLY ONE DELIMITER IS TO BE DETECTED, DELIMITER ONE
                   24183: #      AND DELIMITER TWO SHOULD BE SET TO THE SAME VALUE.
                   24184: #
                   24185: #      IN THE CASE WHERE THE END OF STRING IS ENCOUNTERED, THE
                   24186: #      STRING INCLUDES ALL THE CHARACTERS TO THE END OF THE
                   24187: #      STRING. NO FURTHER CALLS CAN BE MADE TO XSCAN UNTIL
                   24188: #      XSCNI IS CALLED TO INITIALIZE A NEW ARGUMENT SCAN
                   24189:        #page   
                   24190: #
                   24191: #      XSCAN (CONTINUED)
                   24192: #
                   24193: xscan: #prc                    # entry point
                   24194:        movl    r7,xscwb        # preserve wb
                   24195:        movl    r$xsc,r9        # point to argument string
                   24196:        movl    4*sclen(r9),r6  # load string length
                   24197:        movl    xsofs,r7        # load current offset
                   24198:        subl2   r7,r6           # get number of remaining characters
                   24199:        tstl    r6              # jump if no characters left
                   24200:        beqlu   xscn2
                   24201:        movab   cfp$f(r9)[r7],r9# point to current character
                   24202: #
                   24203: #      LOOP TO SEARCH FOR DELIMITER
                   24204: #
                   24205: xscn1: movzbl  (r9)+,r7        # load next character
                   24206:        cmpl    r7,r8           # jump if delimiter one found
                   24207:        beqlu   xscn3
                   24208:        cmpl    r7,r10          # jump if delimiter two found
                   24209:        beqlu   xscn4
                   24210:        decl    r6              # decrement count of chars left
                   24211:        tstl    r6              # loop back if more chars to go
                   24212:        bnequ   xscn1
                   24213: #
                   24214: #      HERE FOR RUNOUT
                   24215: #
                   24216: xscn2: movl    r$xsc,r10       # point to string block
                   24217:        movl    4*sclen(r10),r6 # get string length
                   24218:        movl    xsofs,r7        # load offset
                   24219:        subl2   r7,r6           # get substring length
                   24220:        clrl    r$xsc           # clear string ptr for collector
                   24221:        clrl    xscrt           # set zero (runout) return code
                   24222:        jmp     xscn6           # jump to exit
                   24223:        #page   
                   24224: #
                   24225: #      XSCAN (CONTINUED)
                   24226: #
                   24227: #      HERE IF DELIMITER ONE FOUND
                   24228: #
                   24229: xscn3: movl    $num01,xscrt    # set return code
                   24230:        jmp     xscn5           # jump to merge
                   24231: #
                   24232: #      HERE IF DELIMITER TWO FOUND
                   24233: #
                   24234: xscn4: movl    $num02,xscrt    # set return code
                   24235: #
                   24236: #      MERGE HERE AFTER DETECTING A DELIMITER
                   24237: #
                   24238: xscn5: movl    r$xsc,r10       # reload pointer to string
                   24239:        movl    4*sclen(r10),r8 # get original length of string
                   24240:        subl2   r6,r8           # minus chars left = chars scanned
                   24241:        movl    r8,r6           # move to reg for sbstr
                   24242:        movl    xsofs,r7        # set offset
                   24243:        subl2   r7,r6           # compute length for sbstr
                   24244:        incl    r8              # adjust new cursor past delimiter
                   24245:        movl    r8,xsofs        # store new offset
                   24246: #
                   24247: #      COMMON EXIT POINT
                   24248: #
                   24249: xscn6: clrl    r9              # clear garbage character ptr in xr
                   24250:        jsb     sbstr           # build sub-string
                   24251:        movl    xscrt,r6        # load return code
                   24252:        movl    xscwb,r7        # restore wb
                   24253:        rsb                     # return to xscan caller
                   24254:        #enp                    # end procedure xscan
                   24255:        #page   
                   24256: #
                   24257: #      XSCNI -- EXECUTION FUNCTION ARGUMENT SCAN
                   24258: #
                   24259: #      XSCNI INITIALIZES THE SCAN USED FOR PROTOTYPE ARGUMENTS
                   24260: #      IN THE CLEAR, DEFINE, LOAD, DATA, ARRAY FUNCTIONS. SEE
                   24261: #      XSCAN FOR THE PROCEDURE WHICH IS USED AFTER THIS CALL.
                   24262: #
                   24263: #      -(XS)                 ARGUMENT TO BE SCANNED (ON STACK)
                   24264: #      JSR  XSCNI            CALL TO SCAN ARGUMENT
                   24265: #      PPM  LOC              TRANSFER LOC IF ARG IS NOT STRING
                   24266: #      PPM  LOC              TRANSFER LOC IF ARGUMENT IS NULL
                   24267: #      (XS)                  POPPED
                   24268: #      (XR,R$XSC)            ARGUMENT (SCBLK PTR)
                   24269: #      (WA)                  ARGUMENT LENGTH
                   24270: #      (IA,RA)               DESTROYED
                   24271: #
                   24272:        .data   1
                   24273: xscni_s:       .long   0
                   24274:        .text   0
                   24275: xscni: movl    (sp)+,xscni_s   # entry point
                   24276:        jsb     gtstg           # fetch argument as string
                   24277:        .long   xsci1           # jump if not convertible
                   24278:        movl    r9,r$xsc        # else store scblk ptr for xscan
                   24279:        clrl    xsofs           # set offset to zero
                   24280:        tstl    r6              # jump if null string
                   24281:        beqlu   xsci2
                   24282:        addl3   $4*2,xscni_s,r11        # return to xscni caller
                   24283:        jmp     (r11)
                   24284: #
                   24285: #      HERE IF ARGUMENT IS NOT A STRING
                   24286: #
                   24287: xsci1: movl    xscni_s,r11     # take not-string error exit
                   24288:        jmp     *(r11)+
                   24289: #
                   24290: #      HERE FOR NULL STRING
                   24291: #
                   24292: xsci2: addl3   $4*1,xscni_s,r11        # take null-string error exit
                   24293:        jmp     *(r11)+
                   24294:        #enp                    # end procedure xscni
                   24295:        #title  s p i t b o l -- utility routines
                   24296: #
                   24297: #      THE FOLLOWING SECTION CONTAINS UTILITY ROUTINES USED FOR
                   24298: #      VARIOUS PURPOSES THROUGHOUT THE SYSTEM. THESE DIFFER
                   24299: #      FROM THE PROCEDURES IN THE UTILITY PROCEDURES SECTION IN
                   24300: #      THEY ARE NOT IN PROCEDURE FORM AND THEY DO NOT RETURN
                   24301: #      TO THEIR CALLERS. THEY ARE ACCESSED WITH A BRANCH TYPE
                   24302: #      INSTRUCTION AFTER SETTING THE REGISTERS TO APPROPRIATE
                   24303: #      PARAMETER VALUES.
                   24304: #
                   24305: #      THE REGISTER VALUES REQUIRED FOR EACH ROUTINE ARE
                   24306: #      DOCUMENTED AT THE START OF EACH ROUTINE. REGISTERS NOT
                   24307: #      MENTIONED MAY CONTAIN ANY VALUES EXCEPT THAT XR,XL
                   24308: #      CAN ONLY CONTAIN PROPER COLLECTABLE POINTERS.
                   24309: #
                   24310: #      SOME OF THESE ROUTINES WILL TOLERATE GARBAGE POINTERS
                   24311: #      IN XL,XR ON ENTRY. THIS IS ALWAYS DOCUMENTED AND IN
                   24312: #      EACH CASE, THE ROUTINE CLEARS THESE GARBAGE VALUES BEFORE
                   24313: #      EXITING AFTER COMPLETING ITS TASK.
                   24314: #
                   24315: #      THE ROUTINES HAVE NAMES CONSISTING OF FIVE LETTERS
                   24316: #      AND ARE ASSEMBLED IN ALPHABETICAL ORDER.
                   24317:        #page   
                   24318: #      ARREF -- ARRAY REFERENCE
                   24319: #
                   24320: #      (XL)                  MAY BE NON-COLLECTABLE
                   24321: #      (XR)                  NUMBER OF SUBSCRIPTS
                   24322: #      (WB)                  SET ZERO/NONZERO FOR VALUE/NAME
                   24323: #                            THE VALUE IN WB MUST BE COLLECTABLE
                   24324: #      STACK                 SUBSCRIPTS AND ARRAY OPERAND
                   24325: #      BRN  ARREF            JUMP TO CALL FUNCTION
                   24326: #
                   24327: #      ARREF CONTINUES BY EXECUTING THE NEXT CODE WORD WITH
                   24328: #      THE RESULT NAME OR VALUE PLACED ON TOP OF THE STACK.
                   24329: #      TO DEAL WITH THE PROBLEM OF ACCESSING SUBSCRIPTS IN THE
                   24330: #      ORDER OF STACKING, XL IS USED AS A SUBSCRIPT POINTER
                   24331: #      WORKING BELOW THE STACK POINTER.
                   24332: #
                   24333: arref: #rtn    
                   24334:        movl    r9,r6           # copy number of subscripts
                   24335:        movl    sp,r10          # point to stack front
                   24336:        moval   0[r9],r9        # convert to byte offset
                   24337:        addl2   r9,r10          # point to array operand on stack
                   24338:        addl2   $4,r10          # final value for stack popping
                   24339:        movl    r10,arfxs       # keep for later
                   24340:        movl    -(r10),r9       # load array operand pointer
                   24341:        movl    r9,r$arf        # keep array pointer
                   24342:        movl    r10,r9          # save pointer to subscripts
                   24343:        movl    r$arf,r10       # point xl to possible vcblk or tbblk
                   24344:        movl    (r10),r8        # load first word
                   24345:        cmpl    r8,$b$art       # jump if arblk
                   24346:        beqlu   arf01
                   24347:        cmpl    r8,$b$vct       # jump if vcblk
                   24348:        bnequ   0f
                   24349:        jmp     arf07
                   24350: 0:             
                   24351:        cmpl    r8,$b$tbt       # jump if tbblk
                   24352:        bnequ   0f
                   24353:        jmp     arf10
                   24354: 0:             
                   24355:        jmp     er_235          # subscripted operand is not table or array
                   24356: #
                   24357: #      HERE FOR ARRAY (ARBLK)
                   24358: #
                   24359: arf01: cmpl    r6,4*arndm(r10) # jump if wrong number of dims
                   24360:        beqlu   0f
                   24361:        jmp     arf09
                   24362: 0:             
                   24363:        movl    intv0,r5        # get initial subscript of zero
                   24364:        movl    r9,r10          # point before subscripts
                   24365:        clrl    r6              # initial offset to bounds
                   24366:        jmp     arf03           # jump into loop
                   24367: #
                   24368: #      LOOP TO COMPUTE SUBSCRIPTS BY MULTIPLICATIONS
                   24369: #
                   24370: arf02: mull2   4*ardm2(r9),r5  # multiply total by next dimension
                   24371: #
                   24372: #      MERGE HERE FIRST TIME
                   24373: #
                   24374: arf03: movl    -(r10),r9       # load next subscript
                   24375:        movl    r5,arfsi        # save current subscript
                   24376:        movl    4*icval(r9),r5  # load integer value in case
                   24377:        cmpl    (r9),$b$icl     # jump if it was an integer
                   24378:        beqlu   arf04
                   24379:        #page   
                   24380: #
                   24381: #      ARREF (CONTINUED)
                   24382: #
                   24383: #
                   24384:        jsb     gtint           # convert to integer
                   24385:        .long   arf12           # jump if not integer
                   24386:        movl    4*icval(r9),r5  # if ok, load integer value
                   24387: #
                   24388: #      HERE WITH INTEGER SUBSCRIPT IN (IA)
                   24389: #
                   24390: arf04: movl    r$arf,r9        # point to array
                   24391:        addl2   r6,r9           # offset to next bounds
                   24392:        subl2   4*arlbd(r9),r5  # subtract low bound to compare
                   24393:        bvc     0f
                   24394:        jmp     arf13
                   24395: 0:             
                   24396:        tstl    r5              # out of range fail if too small
                   24397:        bgeq    0f
                   24398:        jmp     arf13
                   24399: 0:             
                   24400:        subl2   4*ardim(r9),r5  # subtract dimension
                   24401:        tstl    r5              # out of range fail if too large
                   24402:        blss    0f
                   24403:        jmp     arf13
                   24404: 0:             
                   24405:        addl2   4*ardim(r9),r5  # else restore subscript offset
                   24406:        addl2   arfsi,r5        # add to current total
                   24407:        addl2   $4*ardms,r6     # point to next bounds
                   24408:        cmpl    r10,sp          # loop back if more to go
                   24409:        bnequ   arf02
                   24410: #
                   24411: #      HERE WITH INTEGER SUBSCRIPT COMPUTED
                   24412: #
                   24413:        movl    r5,r6           # get as one word integer
                   24414:        moval   0[r6],r6        # convert to offset
                   24415:        movl    r$arf,r10       # point to arblk
                   24416:        addl2   4*arofs(r10),r6 # add offset past bounds
                   24417:        addl2   $4,r6           # adjust for arpro field
                   24418:        tstl    r7              # exit with name if name call
                   24419:        bnequ   arf08
                   24420: #
                   24421: #      MERGE HERE TO GET VALUE FOR VALUE CALL
                   24422: #
                   24423: arf05: jsb     acess           # get value
                   24424:        .long   arf13           # fail if acess fails
                   24425: #
                   24426: #      RETURN VALUE
                   24427: #
                   24428: arf06: movl    arfxs,sp        # pop stack entries
                   24429:        clrl    r$arf           # finished with array pointer
                   24430:        jmp     exixr           # exit with value in xr
                   24431:        #page   
                   24432: #
                   24433: #      ARREF (CONTINUED)
                   24434: #
                   24435: #      HERE FOR VECTOR
                   24436: #
                   24437: arf07: cmpl    r6,$num01       # error if more than 1 subscript
                   24438:        beqlu   0f
                   24439:        jmp     arf09
                   24440: 0:             
                   24441:        movl    (sp),r9         # else load subscript
                   24442:        jsb     gtint           # convert to integer
                   24443:        .long   arf12           # error if not integer
                   24444:        movl    4*icval(r9),r5  # else load integer value
                   24445:        subl2   intv1,r5        # subtract for ones offset
                   24446:        movl    r5,r6           # get subscript as one word
                   24447:        bgeq    0f
                   24448:        jmp     arf13
                   24449: 0:             
                   24450:        addl2   $vcvls,r6       # add offset for standard fields
                   24451:        moval   0[r6],r6        # convert offset to bytes
                   24452:        cmpl    r6,4*vclen(r10) # fail if out of range subscript
                   24453:        blssu   0f
                   24454:        jmp     arf13
                   24455: 0:             
                   24456:        tstl    r7              # back to get value if value call
                   24457:        beqlu   arf05
                   24458: #
                   24459: #      RETURN NAME
                   24460: #
                   24461: arf08: movl    arfxs,sp        # pop stack entries
                   24462:        clrl    r$arf           # finished with array pointer
                   24463:        jmp     exnam           # else exit with name
                   24464: #
                   24465: #      HERE IF SUBSCRIPT COUNT IS WRONG
                   24466: #
                   24467: arf09: jmp     er_236          # array referenced with wrong number of subscripts
                   24468: #
                   24469: #      TABLE
                   24470: #
                   24471: arf10: cmpl    r6,$num01       # error if more than 1 subscript
                   24472:        bnequ   arf11
                   24473:        movl    (sp),r9         # else load subscript
                   24474:        jsb     tfind           # call table search routine
                   24475:        .long   arf13           # fail if failed
                   24476:        tstl    r7              # exit with name if name call
                   24477:        bnequ   arf08
                   24478:        jmp     arf06           # else exit with value
                   24479: #
                   24480: #      HERE FOR BAD TABLE REFERENCE
                   24481: #
                   24482: arf11: jmp     er_237          # table referenced with more than one subscript
                   24483: #
                   24484: #      HERE FOR BAD SUBSCRIPT
                   24485: #
                   24486: arf12: jmp     er_238          # array subscript is not integer
                   24487: #
                   24488: #      HERE TO SIGNAL FAILURE
                   24489: #
                   24490: arf13: clrl    r$arf           # finished with array pointer
                   24491:        jmp     exfal           # fail
                   24492:        #page   
                   24493: #
                   24494: #      CFUNC -- CALL A FUNCTION
                   24495: #
                   24496: #      CFUNC IS USED TO CALL A SNOBOL LEVEL FUNCTION. IT IS
                   24497: #      USED BY THE APPLY FUNCTION (S$APP), THE FUNCTION
                   24498: #      TRACE ROUTINE (TRXEQ) AND THE MAIN FUNCTION CALL ENTRY
                   24499: #      (O$FNC, O$FNS). IN THE LATTER CASES, CFUNC IS USED ONLY
                   24500: #      IF THE NUMBER OF ARGUMENTS IS INCORRECT.
                   24501: #
                   24502: #      (XL)                  POINTER TO FUNCTION BLOCK
                   24503: #      (WA)                  ACTUAL NUMBER OF ARGUMENTS
                   24504: #      (XS)                  POINTS TO STACKED ARGUMENTS
                   24505: #      BRN  CFUNC            JUMP TO CALL FUNCTION
                   24506: #
                   24507: #      CFUNC CONTINUES BY EXECUTING THE FUNCTION
                   24508: #
                   24509: cfunc: #rtn    
                   24510:        cmpl    r6,4*fargs(r10) # jump if too few arguments
                   24511:        blssu   cfnc1
                   24512:        cmpl    r6,4*fargs(r10) # jump if correct number of args
                   24513:        beqlu   cfnc3
                   24514: #
                   24515: #      HERE IF TOO MANY ARGUMENTS SUPPLIED, POP THEM OFF
                   24516: #
                   24517:        movl    r6,r7           # copy actual number
                   24518:        subl2   4*fargs(r10),r7 # get number of extra args
                   24519:        moval   0[r7],r7        # convert to bytes
                   24520:        addl2   r7,sp           # pop off unwanted arguments
                   24521:        jmp     cfnc3           # jump to go off to function
                   24522: #
                   24523: #      HERE IF TOO FEW ARGUMENTS
                   24524: #
                   24525: cfnc1: movl    4*fargs(r10),r7 # load required number of arguments
                   24526:        cmpl    r7,$nini9       # jump if case of var num of args
                   24527:        beqlu   cfnc3
                   24528:        subl2   r6,r7           # calculate number missing
                   24529:                                # set counter to control loop
                   24530: #
                   24531: #      LOOP TO SUPPLY EXTRA NULL ARGUMENTS
                   24532: #
                   24533: cfnc2: movl    $nulls,-(sp)    # stack a null argument
                   24534:        sobgtr  r7,cfnc2        # loop till proper number stacked
                   24535: #
                   24536: #      MERGE HERE TO JUMP TO FUNCTION
                   24537: #
                   24538: cfnc3: movl    (r10),r11       # jump through fcode field
                   24539:        jmp     (r11)
                   24540:        #page   
                   24541: #
                   24542: #      EXFAL -- EXIT SIGNALLING SNOBOL FAILURE
                   24543: #
                   24544: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24545: #      BRN  EXFAL            JUMP TO FAIL
                   24546: #
                   24547: #      EXFAL CONTINUES BY EXECUTING THE APPROPRIATE FAIL GOTO
                   24548: #
                   24549: exfal: #rtn    
                   24550:        movl    flptr,sp        # pop stack
                   24551:        movl    (sp),r9         # load failure offset
                   24552:        addl2   r$cod,r9        # point to failure code location
                   24553:        movl    r9,r3           # set code pointer
                   24554:        jmp     exits           # do next code word
                   24555:        #page   
                   24556: #
                   24557: #      EXINT -- EXIT WITH INTEGER RESULT
                   24558: #
                   24559: #      (XL,XR)               MAY BE NONCOLLECTABLE
                   24560: #      (IA)                  INTEGER VALUE
                   24561: #      BRN  EXINT            JUMP TO EXIT WITH INTEGER
                   24562: #
                   24563: #      EXINT CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24564: #      WHICH IT DOES BY FALLING THROUGH TO EXIXR
                   24565: #
                   24566: exint: #rtn    
                   24567:        jsb     icbld           # build icblk
                   24568:        #page   
                   24569: #      EXIXR -- EXIT WITH RESULT IN (XR)
                   24570: #
                   24571: #      (XR)                  RESULT
                   24572: #      (XL)                  MAY BE NON-COLLECTABLE
                   24573: #      BRN  EXIXR            JUMP TO EXIT WITH RESULT IN (XR)
                   24574: #
                   24575: #      EXIXR CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24576: #      WHICH IT DOES BY FALLING THROUGH TO EXITS.
                   24577: exixr: #rtn    
                   24578: #
                   24579:        movl    r9,-(sp)        # stack result
                   24580: #
                   24581: #
                   24582: #      EXITS -- EXIT WITH RESULT IF ANY STACKED
                   24583: #
                   24584: #      (XR,XL)               MAY BE NON-COLLECTABLE
                   24585: #
                   24586: #      BRN  EXITS            ENTER EXITS ROUTINE
                   24587: #
                   24588: exits: #rtn    
                   24589:        movl    (r3)+,r9        # load next code word
                   24590:        movl    (r9),r10        # load entry address
                   24591:        movl    r10,r11         # jump to execute next code word
                   24592:        jmp     (r11)
                   24593:        #page   
                   24594: #
                   24595: #      EXNAM -- EXIT WITH NAME IN (XL,WA)
                   24596: #
                   24597: #      (XL)                  NAME BASE
                   24598: #      (WA)                  NAME OFFSET
                   24599: #      (XR)                  MAY BE NON-COLLECTABLE
                   24600: #      BRN  EXNAM            JUMP TO EXIT WITH NAME IN (XL,WA)
                   24601: #
                   24602: #      EXNAM CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24603: #
                   24604: exnam: #rtn    
                   24605:        movl    r10,-(sp)       # stack name base
                   24606:        movl    r6,-(sp)        # stack name offset
                   24607:        jmp     exits           # do next code word
                   24608:        #page   
                   24609: #
                   24610: #      EXNUL -- EXIT WITH NULL RESULT
                   24611: #
                   24612: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24613: #      BRN  EXNUL            JUMP TO EXIT WITH NULL VALUE
                   24614: #
                   24615: #      EXNUL CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24616: #
                   24617: exnul: #rtn    
                   24618:        movl    $nulls,-(sp)    # stack null value
                   24619:        jmp     exits           # do next code word
                   24620:        #page   
                   24621: #
                   24622: #      EXREA -- EXIT WITH REAL RESULT
                   24623: #
                   24624: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24625: #      (RA)                  REAL VALUE
                   24626: #      BRN  EXREA            JUMP TO EXIT WITH REAL VALUE
                   24627: #
                   24628: #      EXREA CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24629: #
                   24630: exrea: #rtn    
                   24631:        jsb     rcbld           # build rcblk
                   24632:        jmp     exixr           # jump to exit with result in xr
                   24633:        #page   
                   24634: #
                   24635: #      EXSID -- EXIT SETTING ID FIELD
                   24636: #
                   24637: #      EXSID IS USED TO EXIT AFTER BUILDING ANY OF THE FOLLOWING
                   24638: #      BLOCKS (ARBLK, TBBLK, PDBLK, VCBLK). IT SETS THE IDVAL.
                   24639: #
                   24640: #      (XR)                  PTR TO BLOCK WITH IDVAL FIELD
                   24641: #      (XL)                  MAY BE NON-COLLECTABLE
                   24642: #      BRN  EXSID            JUMP TO EXIT AFTER SETTING ID FIELD
                   24643: #
                   24644: #      EXSID CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24645: #
                   24646: exsid: #rtn    
                   24647:        movl    curid,r6        # load current id value
                   24648:        cmpl    r6,$cfp$m       # jump if no overflow
                   24649:        bnequ   exsi1
                   24650:        clrl    r6              # else reset for wraparound
                   24651: #
                   24652: #      HERE WITH OLD IDVAL IN WA
                   24653: #
                   24654: exsi1: incl    r6              # bump id value
                   24655:        movl    r6,curid        # store for next time
                   24656:        movl    r6,4*idval(r9)  # store id value
                   24657:        jmp     exixr           # exit with result in (xr)
                   24658:        #page   
                   24659: #
                   24660: #      EXVNM -- EXIT WITH NAME OF VARIABLE
                   24661: #
                   24662: #      EXVNM EXITS AFTER STACKING A VALUE WHICH IS A NMBLK
                   24663: #      REFERENCING THE NAME OF A GIVEN NATURAL VARIABLE.
                   24664: #
                   24665: #      (XR)                  VRBLK POINTER
                   24666: #      (XL)                  MAY BE NON-COLLECTABLE
                   24667: #      BRN  EXVNM            EXIT WITH VRBLK POINTER IN XR
                   24668: #
                   24669: exvnm: #rtn    
                   24670:        movl    r9,r10          # copy name base pointer
                   24671:        movl    $4*nmsi$,r6     # set size of nmblk
                   24672:        jsb     alloc           # allocate nmblk
                   24673:        movl    $b$nml,(r9)     # store type word
                   24674:        movl    r10,4*nmbas(r9) # store name base
                   24675:        movl    $4*vrval,4*nmofs(r9) # store name offset
                   24676:        jmp     exixr           # exit with result in xr
                   24677:        #page   
                   24678: #
                   24679: #      FLPOP -- FAIL AND POP IN PATTERN MATCHING
                   24680: #
                   24681: #      FLPOP POPS THE NODE AND CURSOR ON THE STACK AND THEN
                   24682: #      DROPS THROUGH INTO FAILP TO CAUSE PATTERN FAILURE
                   24683: #
                   24684: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24685: #      BRN  FLPOP            JUMP TO FAIL AND POP STACK
                   24686: #
                   24687: flpop: #rtn    
                   24688:        addl2   $4*num02,sp     # pop two entries off stack
                   24689:        #page   
                   24690: #
                   24691: #      FAILP -- FAILURE IN MATCHING PATTERN NODE
                   24692: #
                   24693: #      FAILP IS USED AFTER FAILING TO MATCH A PATTERN NODE.
                   24694: #      SEE PATTERN MATCH ROUTINES FOR DETAILS OF USE.
                   24695: #
                   24696: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24697: #      BRN  FAILP            SIGNAL FAILURE TO MATCH
                   24698: #
                   24699: #      FAILP CONTINUES BY MATCHING AN ALTERNATIVE FROM THE STACK
                   24700: #
                   24701: failp: #rtn    
                   24702:        movl    (sp)+,r9        # load alternative node pointer
                   24703:        movl    (sp)+,r7        # restore old cursor
                   24704:        movl    (r9),r10        # load pcode entry pointer
                   24705:        movl    r10,r11         # jump to execute code for node
                   24706:        jmp     (r11)
                   24707:        #page   
                   24708: #
                   24709: #      INDIR -- COMPUTE INDIRECT REFERENCE
                   24710: #
                   24711: #      (WB)                  NONZERO/ZERO FOR BY NAME/VALUE
                   24712: #      BRN  INDIR            JUMP TO GET INDIRECT REF ON STACK
                   24713: #
                   24714: #      INDIR CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24715: #
                   24716: indir: #rtn    
                   24717:        movl    (sp)+,r9        # load argument
                   24718:        cmpl    (r9),$b$nml     # jump if a name
                   24719:        beqlu   indr2
                   24720:        jsb     gtnvr           # else convert to variable
                   24721:        .long   er_239          # indirection operand is not name
                   24722:        tstl    r7              # skip if by value
                   24723:        beqlu   indr1
                   24724:        movl    r9,-(sp)        # else stack vrblk ptr
                   24725:        movl    $4*vrval,-(sp)  # stack name offset
                   24726:        jmp     exits           # exit with result on stack
                   24727: #
                   24728: #      HERE TO GET VALUE OF NATURAL VARIABLE
                   24729: #
                   24730: indr1: movl    (r9),r11        # jump through vrget field of vrblk
                   24731:        jmp     (r11)
                   24732: #
                   24733: #      HERE IF OPERAND IS A NAME
                   24734: #
                   24735: indr2: movl    4*nmbas(r9),r10 # load name base
                   24736:        movl    4*nmofs(r9),r6  # load name offset
                   24737:        tstl    r7              # exit if called by name
                   24738:        beqlu   0f
                   24739:        jmp     exnam
                   24740: 0:             
                   24741:        jsb     acess           # else get value first
                   24742:        .long   exfal           # fail if access fails
                   24743:        jmp     exixr           # else return with value in xr
                   24744:        #page   
                   24745: #
                   24746: #      MATCH -- INITIATE PATTERN MATCH
                   24747: #
                   24748: #      (WB)                  MATCH TYPE CODE
                   24749: #      BRN  MATCH            JUMP TO INITIATE PATTERN MATCH
                   24750: #
                   24751: #      MATCH CONTINUES BY EXECUTING THE PATTERN MATCH. SEE
                   24752: #      PATTERN MATCH ROUTINES (P$XXX) FOR FULL DETAILS.
                   24753: #
                   24754: match: #rtn    
                   24755:        movl    (sp)+,r9        # load pattern operand
                   24756:        jsb     gtpat           # convert to pattern
                   24757:        .long   er_240          # pattern match right operand is not pattern
                   24758:        movl    r9,r10          # if ok, save pattern pointer
                   24759:        tstl    r7              # jump if not match by name
                   24760:        bnequ   mtch1
                   24761:        movl    (sp),r6         # else load name offset
                   24762:        movl    r10,-(sp)       # save pattern pointer
                   24763:        movl    4*2(sp),r10     # load name base
                   24764:        jsb     acess           # access subject value
                   24765:        .long   exfal           # fail if access fails
                   24766:        movl    (sp),r10        # restore pattern pointer
                   24767:        movl    r9,(sp)         # stack subject string val for merge
                   24768:        clrl    r7              # restore type code
                   24769: #
                   24770: #      MERGE HERE WITH SUBJECT VALUE ON STACK
                   24771: #
                   24772: mtch1: movl    (sp),r9         # load subject value
                   24773:        clrl    r$pmb           # assume not a buffer
                   24774:        cmpl    (r9),$b$bct     # branch if not
                   24775:        bnequ   mtcha
                   24776:        addl2   $4,sp           # else pop value
                   24777:        movl    r9,r$pmb        # save pointer
                   24778:        movl    4*bclen(r9),r6  # get defined length
                   24779:        movl    4*bcbuf(r9),r9  # point to bfblk
                   24780:        jmp     mtchb
                   24781: #
                   24782: #      HERE IF NOT BUFFER TO CONVERT TO STRING
                   24783: #
                   24784: mtcha: jsb     gtstg           # not buffer - convert to string
                   24785:        .long   er_241          # pattern match left operand is not string
                   24786: #
                   24787: #      MERGE WITH BUFFER OR STRING
                   24788: #
                   24789: mtchb: movl    r9,r$pms        # if ok, store subject string pointer
                   24790:        movl    r6,pmssl        # and length
                   24791:        movl    r7,-(sp)        # stack match type code
                   24792:        clrl    -(sp)           # stack initial cursor (zero)
                   24793:        clrl    r7              # set initial cursor
                   24794:        movl    sp,pmhbs        # set history stack base ptr
                   24795:        clrl    pmdfl           # reset pattern assignment flag
                   24796:        movl    r10,r9          # set initial node pointer
                   24797:        tstl    kvanc           # jump if anchored
                   24798:        bnequ   mtch2
                   24799: #
                   24800: #      HERE FOR UNANCHORED
                   24801: #
                   24802:        movl    r9,-(sp)        # stack initial node pointer
                   24803:        movl    $nduna,-(sp)    # stack pointer to anchor move node
                   24804:        movl    (r9),r11        # start match of first node
                   24805:        jmp     (r11)
                   24806: #
                   24807: #      HERE IN ANCHORED MODE
                   24808: #
                   24809: mtch2: clrl    -(sp)           # dummy cursor value
                   24810:        movl    $ndabo,-(sp)    # stack pointer to abort node
                   24811:        movl    (r9),r11        # start match of first node
                   24812:        jmp     (r11)
                   24813:        #page   
                   24814: #
                   24815: #      RETRN -- RETURN FROM FUNCTION
                   24816: #
                   24817: #      (WA)                  STRING POINTER FOR RETURN TYPE
                   24818: #      BRN  RETRN            JUMP TO RETURN FROM (SNOBOL) FUNC
                   24819: #
                   24820: #      RETRN CONTINUES BY EXECUTING THE CODE AT THE RETURN POINT
                   24821: #      THE STACK IS CLEANED OF ANY GARBAGE LEFT BY OTHER
                   24822: #      ROUTINES WHICH MAY HAVE ALTERED FLPTR SINCE FUNCTION
                   24823: #      ENTRY BY USING FLPRT, RESERVED FOR USE ONLY BY
                   24824: #      FUNCTION CALL AND RETURN.
                   24825: #
                   24826: retrn: #rtn    
                   24827:        tstl    kvfnc           # jump if not level zero
                   24828:        bnequ   rtn01
                   24829:        jmp     er_242          # function return from level zero
                   24830: #
                   24831: #      HERE IF NOT LEVEL ZERO RETURN
                   24832: #
                   24833: rtn01: movl    flprt,sp        # pop stack
                   24834:        addl2   $4,sp           # remove failure offset
                   24835:        movl    (sp)+,r9        # pop pfblk pointer
                   24836:        movl    (sp)+,flptr     # pop failure pointer
                   24837:        movl    (sp)+,flprt     # pop old flprt
                   24838:        movl    (sp)+,r7        # pop code pointer offset
                   24839:        movl    (sp)+,r8        # pop old code block pointer
                   24840:        addl2   r8,r7           # make old code pointer absolute
                   24841:        movl    r7,r3           # restore old code pointer
                   24842:        movl    r8,r$cod        # restore old code block pointer
                   24843:        decl    kvfnc           # decrement function level
                   24844:        movl    kvtra,r7        # load trace
                   24845:        addl2   kvftr,r7        # add ftrace
                   24846:        tstl    r7              # jump if no tracing possible
                   24847:        bnequ   0f
                   24848:        jmp     rtn06
                   24849: 0:             
                   24850: #
                   24851: #      HERE IF THERE MAY BE A TRACE
                   24852: #
                   24853:        movl    r6,-(sp)        # save function return type
                   24854:        movl    r9,-(sp)        # save pfblk pointer
                   24855:        movl    r6,kvrtn        # set rtntype for trace function
                   24856:        movl    r$fnc,r10       # load fnclevel trblk ptr (if any)
                   24857:        jsb     ktrex           # execute possible fnclevel trace
                   24858:        movl    4*pfvbl(r9),r10 # load vrblk ptr (sgd13)
                   24859:        tstl    kvtra           # jump if trace is off
                   24860:        beqlu   rtn02
                   24861:        movl    4*pfrtr(r9),r9  # else load return trace trblk ptr
                   24862:        tstl    r9              # jump if not return traced
                   24863:        beqlu   rtn02
                   24864:        decl    kvtra           # else decrement trace count
                   24865:        tstl    4*trfnc(r9)     # jump if print trace
                   24866:        beqlu   rtn03
                   24867:        movl    $4*vrval,r6     # else set name offset
                   24868:        movl    4*1(sp),kvrtn   # make sure rtntype is set right
                   24869:        jsb     trxeq           # execute full trace
                   24870:        #page   
                   24871: #
                   24872: #      RETRN (CONTINUED)
                   24873: #
                   24874: #      HERE TO TEST FOR FTRACE
                   24875: #
                   24876: rtn02: tstl    kvftr           # jump if ftrace is off
                   24877:        beqlu   rtn05
                   24878:        decl    kvftr           # else decrement ftrace
                   24879: #
                   24880: #      HERE FOR PRINT TRACE OF FUNCTION RETURN
                   24881: #
                   24882: rtn03: jsb     prtsn           # print statement number
                   24883:        movl    4*1(sp),r9      # load return type
                   24884:        jsb     prtst           # print it
                   24885:        movl    $ch$bl,r6       # load blank
                   24886:        jsb     prtch           # print it
                   24887:        movl    (sp),r10        # load pfblk ptr
                   24888:        movl    4*pfvbl(r10),r10# load function vrblk ptr
                   24889:        movl    $4*vrval,r6     # set vrblk name offset
                   24890:        cmpl    r9,$scfrt       # jump if not freturn case
                   24891:        bnequ   rtn04
                   24892: #
                   24893: #      FOR FRETURN, JUST PRINT FUNCTION NAME
                   24894: #
                   24895:        jsb     prtnm           # print name
                   24896:        jsb     prtnl           # terminate print line
                   24897:        jmp     rtn05           # merge
                   24898: #
                   24899: #      HERE FOR RETURN OR NRETURN, PRINT FUNCTION NAME = VALUE
                   24900: #
                   24901: rtn04: jsb     prtnv           # print name = value
                   24902: #
                   24903: #      HERE AFTER COMPLETING TRACE
                   24904: #
                   24905: rtn05: movl    (sp)+,r9        # pop pfblk pointer
                   24906:        movl    (sp)+,r6        # pop return type string
                   24907: #
                   24908: #      MERGE HERE IF NO TRACE REQUIRED
                   24909: #
                   24910: rtn06: movl    r6,kvrtn        # set rtntype keyword
                   24911:        movl    4*pfvbl(r9),r10 # load pointer to fn vrblk
                   24912:        #page   
                   24913: #      RETRN (CONTINUED)
                   24914: #
                   24915: #      GET VALUE OF FUNCTION
                   24916: #
                   24917: rtn07: movl    r10,rtnbp       # save block pointer
                   24918:        movl    4*vrval(r10),r10# load value
                   24919:        cmpl    (r10),$b$trt    # loop back if trapped
                   24920:        beqlu   rtn07
                   24921:        movl    r10,rtnfv       # else save function result value
                   24922:        movl    (sp)+,rtnsv     # save original function value
                   24923:        movl    (sp)+,r10       # pop saved pointer
                   24924:        tstl    r10             # no action if none
                   24925:        beqlu   rtn7c
                   24926:        tstl    kvpfl           # jump if no profiling
                   24927:        beqlu   rtn7c
                   24928:        jsb     prflu           # else profile last func stmt
                   24929:        cmpl    kvpfl,$num02    # branch on value of profile keywd
                   24930:        beqlu   rtn7a
                   24931: #
                   24932: #      HERE IF &PROFILE = 1. START TIME MUST BE FRIGGED TO
                   24933: #      APPEAR EARLIER THAN IT ACTUALLY IS, BY AMOUNT USED BEFORE
                   24934: #      THE CALL.
                   24935: #
                   24936:        movl    pfstm,r5        # load current time
                   24937:        subl2   4*icval(r10),r5 # frig by subtracting saved amount
                   24938:        jmp     rtn7b           # and merge
                   24939: #
                   24940: #      HERE IF &PROFILE = 2
                   24941: #
                   24942: rtn7a: movl    4*icval(r10),r5 # load saved time
                   24943: #
                   24944: #      BOTH PROFILE TYPES MERGE HERE
                   24945: #
                   24946: rtn7b: movl    r5,pfstm        # store back correct start time
                   24947: #
                   24948: #      MERGE HERE IF NO PROFILING
                   24949: #
                   24950: rtn7c: movl    4*fargs(r9),r7  # get number of args
                   24951:        addl2   4*pfnlo(r9),r7  # add number of locals
                   24952:        tstl    r7              # jump if no args/locals
                   24953:        beqlu   rtn10
                   24954:                                # else set loop counter
                   24955:        addl2   4*pflen(r9),r9  # and point to end of pfblk
                   24956: #
                   24957: #      LOOP TO RESTORE FUNCTIONS AND LOCALS
                   24958: #
                   24959: rtn08: movl    -(r9),r10       # load next vrblk pointer
                   24960: #
                   24961: #      LOOP TO FIND VALUE BLOCK
                   24962: #
                   24963: rtn09: movl    r10,r6          # save block pointer
                   24964:        movl    4*vrval(r10),r10# load pointer to next value
                   24965:        cmpl    (r10),$b$trt    # loop back if trapped
                   24966:        beqlu   rtn09
                   24967:        movl    r6,r10          # else restore last block pointer
                   24968:        movl    (sp)+,4*vrval(r10) # restore old variable value
                   24969:        sobgtr  r7,rtn08        # loop till all processed
                   24970: #
                   24971: #      NOW RESTORE FUNCTION VALUE AND EXIT
                   24972: #
                   24973: rtn10: movl    rtnbp,r10       # restore ptr to last function block
                   24974:        movl    rtnsv,4*vrval(r10) # restore old function value
                   24975:        movl    rtnfv,r9        # reload function result
                   24976:        movl    r$cod,r10       # point to new code block
                   24977:        movl    kvstn,kvlst     # set lastno from stno
                   24978:        movl    4*cdstm(r10),kvstn # reset proper stno value
                   24979:        movl    kvrtn,r6        # load return type
                   24980:        cmpl    r6,$scrtn       # exit with result in xr if return
                   24981:        bnequ   0f
                   24982:        jmp     exixr
                   24983: 0:             
                   24984:        cmpl    r6,$scfrt       # fail if freturn
                   24985:        bnequ   0f
                   24986:        jmp     exfal
                   24987: 0:             
                   24988:        #page   
                   24989: #
                   24990: #      RETRN (CONTINUED)
                   24991: #
                   24992: #      HERE FOR NRETURN
                   24993: #
                   24994:        cmpl    (r9),$b$nml     # jump if is a name
                   24995:        beqlu   rtn11
                   24996:        jsb     gtnvr           # else try convert to variable name
                   24997:        .long   er_243          # function result in nreturn is not name
                   24998:        movl    r9,r10          # if ok, copy vrblk (name base) ptr
                   24999:        movl    $4*vrval,r6     # set name offset
                   25000:        jmp     rtn12           # and merge
                   25001: #
                   25002: #      HERE IF RETURNED RESULT IS A NAME
                   25003: #
                   25004: rtn11: movl    4*nmbas(r9),r10 # load name base
                   25005:        movl    4*nmofs(r9),r6  # load name offset
                   25006: #
                   25007: #      MERGE HERE WITH RETURNED NAME IN (XL,WA)
                   25008: #
                   25009: rtn12: movl    r10,r9          # preserve xl
                   25010:        movl    (r3)+,r7        # load next word
                   25011:        movl    r9,r10          # restore xl
                   25012:        cmpl    r7,$ofne$       # exit if called by name
                   25013:        bnequ   0f
                   25014:        jmp     exnam
                   25015: 0:             
                   25016:        movl    r7,-(sp)        # else save code word
                   25017:        jsb     acess           # get value
                   25018:        .long   exfal           # fail if access fails
                   25019:        movl    r9,r10          # if ok, copy result
                   25020:        movl    (sp),r9         # reload next code word
                   25021:        movl    r10,(sp)        # store result on stack
                   25022:        movl    (r9),r10        # load routine address
                   25023:        movl    r10,r11         # jump to execute next code word
                   25024:        jmp     (r11)
                   25025:        #page   
                   25026: #
                   25027: #      STCOV -- SIGNAL STATEMENT COUNTER OVERFLOW
                   25028: #
                   25029: #      BRN  STCOV            JUMP TO SIGNAL STATEMENT COUNT OFLO
                   25030: #
                   25031: #      PERMIT UP TO 10 MORE STATEMENTS TO BE OBEYED SO THAT
                   25032: #      SETEXIT TRAP CAN REGAIN CONTROL.
                   25033: #      STCOV CONTINUES BY ISSUING THE ERROR MESSAGE
                   25034: #
                   25035: stcov: #rtn    
                   25036:        incl    errft           # fatal error
                   25037:        movl    intvt,r5        # get 10
                   25038:        addl2   kvstl,r5        # add to former limit
                   25039:        movl    r5,kvstl        # store as new stlimit
                   25040:        movl    intvt,r5        # get 10
                   25041:        movl    r5,kvstc        # set as new count
                   25042:        jmp     er_244          # statement count exceeds value of stlimit keyword
                   25043:        #page   
                   25044: #
                   25045: #      STMGO -- START EXECUTION OF NEW STATEMENT
                   25046: #
                   25047: #      (XR)                  POINTER TO CDBLK FOR NEW STATEMENT
                   25048: #      BRN  STMGO            JUMP TO EXECUTE NEW STATEMENT
                   25049: #
                   25050: #      STMGO CONTINUES BY EXECUTING THE NEXT STATEMENT
                   25051: #
                   25052: stmgo: #rtn    
                   25053:        movl    r9,r$cod        # set new code block pointer
                   25054:        tstl    kvpfl           # skip if no profiling
                   25055:        beqlu   stgo1
                   25056:        jsb     prflu           # else profile the statement
                   25057: stgo1: movl    kvstn,kvlst     # set lastno
                   25058:        movl    4*cdstm(r9),kvstn# set stno
                   25059:        addl2   $4*cdcod,r9     # point to first code word
                   25060:        movl    r9,r3           # set code pointer
                   25061:        movl    kvstc,r5        # get stmt count
                   25062:        tstl    r5              # omit counting if negative
                   25063:        bgeq    0f
                   25064:        jmp     exits
                   25065: 0:             
                   25066:        tstl    r5              # fail if stlimit reached
                   25067:        beql    stcov
                   25068:        subl2   intv1,r5        # decrement
                   25069:        movl    r5,kvstc        # replace it
                   25070:        tstl    r$stc           # exit if no stcount trace
                   25071:        bnequ   0f
                   25072:        jmp     exits
                   25073: 0:             
                   25074: #
                   25075: #      HERE FOR STCOUNT TRACE
                   25076: #
                   25077:        clrl    r9              # clear garbage value in xr
                   25078:        movl    r$stc,r10       # load pointer to stcount trblk
                   25079:        jsb     ktrex           # execute keyword trace
                   25080:        jmp     exits           # and then exit for next code word
                   25081:        #page   
                   25082: #
                   25083: #      STOPR -- TERMINATE RUN
                   25084: #
                   25085: #      (XR)                  POINTS TO ENDING MESSAGE
                   25086: #      BRN STOPR             JUMP TO TERMINATE RUN
                   25087: #
                   25088: #      TERMINATE RUN AND PRINT STATISTICS.  ON ENTRY XR POINTS
                   25089: #      TO ENDING MESSAGE OR IS ZERO IF MESSAGE  PRINTED ALREADY.
                   25090: #
                   25091: stopr: #rtn    
                   25092:        tstl    r9              # skip if sysax already called (reg04)
                   25093:        beqlu   stpra
                   25094:        jsb     sysax           # call after execution proc
                   25095: stpra: addl2   rsmem,dname     # use the reserve memory
                   25096:        cmpl    r9,$endms       # skip if not normal end message
                   25097:        bnequ   stpr0
                   25098:        tstl    exsts           # skip if exec stats suppressed
                   25099:        beqlu   0f
                   25100:        jmp     stpr3
                   25101: 0:             
                   25102:        clrl    erich           # clear errors to int.ch. flag
                   25103: #
                   25104: #      LOOK TO SEE IF AN ENDING MESSAGE IS SUPPLIED
                   25105: #
                   25106: stpr0: jsb     prtpg           # eject printer
                   25107:        tstl    r9              # skip if no message
                   25108:        beqlu   stpr1
                   25109:        jsb     prtst           # print message
                   25110: #
                   25111: #      MERGE HERE IF NO MESSAGE TO PRINT
                   25112: #
                   25113: stpr1: jsb     prtis           # print blank line
                   25114:        movl    kvstn,r5        # get statement number
                   25115:        movl    $stpm1,r9       # point to message /in statement xxx/
                   25116:        jsb     prtmx           # print it
                   25117:        jsb     systm           # get current time
                   25118:        subl2   timsx,r5        # minus start time = elapsed exec tim
                   25119:        movl    r5,stpti        # save for later
                   25120:        movl    $stpm3,r9       # point to msg /execution time msec /
                   25121:        jsb     prtmx           # print it
                   25122:        movl    kvstl,r5        # get statement limit
                   25123:        tstl    r5              # skip if negative
                   25124:        blss    stpr2
                   25125:        subl2   kvstc,r5        # minus counter = count
                   25126:        movl    r5,stpsi        # save
                   25127:        movl    $stpm2,r9       # point to message /stmts executed/
                   25128:        jsb     prtmx           # print it
                   25129:        movl    stpti,r5        # reload elapsed time
                   25130:        mull2   intth,r5        # *1000 (microsecs)
                   25131:        bvs     stpr2
                   25132:        divl2   stpsi,r5        # divide by statement count
                   25133:        bvs     stpr2
                   25134:        movl    $stpm4,r9       # point to msg (mcsec per statement /
                   25135:        jsb     prtmx           # print it
                   25136:        #page   
                   25137: #
                   25138: #      STOPR (CONTINUED)
                   25139: #
                   25140: #      MERGE TO SKIP MESSAGE (OVERFLOW OR NEGATIVE STLIMIT)
                   25141: #
                   25142: stpr2: movl    gbcnt,r5        # load count of collections
                   25143:        movl    $stpm5,r9       # point to message /regenerations /
                   25144:        jsb     prtmx           # print it
                   25145:        jsb     prtis           # one more blank for luck
                   25146: #
                   25147: #      CHECK IF DUMP REQUESTED
                   25148: #
                   25149: stpr3: jsb     prflr           # print profile if wanted
                   25150: #
                   25151:        movl    kvdmp,r9        # load dump keyword
                   25152:        jsb     dumpr           # execute dump if requested
                   25153:        movl    r$fcb,r10       # get fcblk chain head
                   25154:        movl    kvabe,r6        # load abend value
                   25155:        movl    kvcod,r7        # load code value
                   25156:        jsb     sysej           # exit to system
                   25157:        #page   
                   25158: #
                   25159: #      SUCCP -- SIGNAL SUCCESSFUL MATCH OF A PATTERN NODE
                   25160: #
                   25161: #      SEE PATTERN MATCH ROUTINES FOR DETAILS
                   25162: #
                   25163: #      (XR)                  CURRENT NODE
                   25164: #      (WB)                  CURRENT CURSOR
                   25165: #      (XL)                  MAY BE NON-COLLECTABLE
                   25166: #      BRN  SUCCP            SIGNAL SUCCESSFUL PATTERN MATCH
                   25167: #
                   25168: #      SUCCP CONTINUES BY MATCHING THE SUCCESSOR NODE
                   25169: #
                   25170: succp: #rtn    
                   25171:        movl    4*pthen(r9),r9  # load successor node
                   25172:        movl    (r9),r10        # load node code entry address
                   25173:        movl    r10,r11         # jump to match successor node
                   25174:        jmp     (r11)
                   25175:        #page   
                   25176: #
                   25177: #      SYSAB -- PRINT /ABNORMAL END/ AND TERMINATE
                   25178: #
                   25179: sysab: #rtn    
                   25180:        movl    $endab,r9       # point to message
                   25181:        movl    $num01,kvabe    # set abend flag
                   25182:        jsb     prtnl           # skip to new line
                   25183:        jmp     stopr           # jump to pack up
                   25184:        #page   
                   25185: #
                   25186: #      SYSTU -- PRINT /TIME UP/ AND TERMINATE
                   25187: #
                   25188: systu: #rtn    
                   25189:        movl    $endtu,r9       # point to message
                   25190:        movl    strtu,r6        # get chars /tu/
                   25191:        movl    r6,kvcod        # put in kvcod
                   25192:        movl    timup,r6        # check state of timeup switch
                   25193:        movl    sp,timup        # set switch
                   25194:        tstl    r6              # stop run if already set
                   25195:        beqlu   0f
                   25196:        jmp     stopr
                   25197: 0:             
                   25198:        jmp     er_245          # translation/execution time expired
                   25199:        #title  s p i t b o l -- stack overflow section
                   25200: #
                   25201: #      CONTROL COMES HERE IF THE MAIN STACK OVERFLOWS
                   25202: #
                   25203: er_001:        movzwl  $1,r6
                   25204:        jmp     error
                   25205: er_002:        movzwl  $2,r6
                   25206:        jmp     error
                   25207: er_003:        movzwl  $3,r6
                   25208:        jmp     error
                   25209: er_004:        movzwl  $4,r6
                   25210:        jmp     error
                   25211: er_005:        movzwl  $5,r6
                   25212:        jmp     error
                   25213: er_006:        movzwl  $6,r6
                   25214:        jmp     error
                   25215: er_007:        movzwl  $7,r6
                   25216:        jmp     error
                   25217: er_008:        movzwl  $8,r6
                   25218:        jmp     error
                   25219: er_009:        movzwl  $9,r6
                   25220:        jmp     error
                   25221: er_010:        movzwl  $10,r6
                   25222:        jmp     error
                   25223: er_011:        movzwl  $11,r6
                   25224:        jmp     error
                   25225: er_012:        movzwl  $12,r6
                   25226:        jmp     error
                   25227: er_013:        movzwl  $13,r6
                   25228:        jmp     error
                   25229: er_014:        movzwl  $14,r6
                   25230:        jmp     error
                   25231: er_015:        movzwl  $15,r6
                   25232:        jmp     error
                   25233: er_016:        movzwl  $16,r6
                   25234:        jmp     error
                   25235: er_017:        movzwl  $17,r6
                   25236:        jmp     error
                   25237: er_018:        movzwl  $18,r6
                   25238:        jmp     error
                   25239: er_019:        movzwl  $19,r6
                   25240:        jmp     error
                   25241: er_020:        movzwl  $20,r6
                   25242:        jmp     error
                   25243: er_021:        movzwl  $21,r6
                   25244:        jmp     error
                   25245: er_022:        movzwl  $22,r6
                   25246:        jmp     error
                   25247: er_023:        movzwl  $23,r6
                   25248:        jmp     error
                   25249: er_024:        movzwl  $24,r6
                   25250:        jmp     error
                   25251: er_025:        movzwl  $25,r6
                   25252:        jmp     error
                   25253: er_026:        movzwl  $26,r6
                   25254:        jmp     error
                   25255: er_027:        movzwl  $27,r6
                   25256:        jmp     error
                   25257: er_028:        movzwl  $28,r6
                   25258:        jmp     error
                   25259: er_029:        movzwl  $29,r6
                   25260:        jmp     error
                   25261: er_030:        movzwl  $30,r6
                   25262:        jmp     error
                   25263: er_031:        movzwl  $31,r6
                   25264:        jmp     error
                   25265: er_032:        movzwl  $32,r6
                   25266:        jmp     error
                   25267: er_033:        movzwl  $33,r6
                   25268:        jmp     error
                   25269: er_034:        movzwl  $34,r6
                   25270:        jmp     error
                   25271: er_035:        movzwl  $35,r6
                   25272:        jmp     error
                   25273: er_036:        movzwl  $36,r6
                   25274:        jmp     error
                   25275: er_037:        movzwl  $37,r6
                   25276:        jmp     error
                   25277: er_038:        movzwl  $38,r6
                   25278:        jmp     error
                   25279: er_039:        movzwl  $39,r6
                   25280:        jmp     error
                   25281: er_040:        movzwl  $40,r6
                   25282:        jmp     error
                   25283: er_041:        movzwl  $41,r6
                   25284:        jmp     error
                   25285: er_042:        movzwl  $42,r6
                   25286:        jmp     error
                   25287: er_043:        movzwl  $43,r6
                   25288:        jmp     error
                   25289: er_044:        movzwl  $44,r6
                   25290:        jmp     error
                   25291: er_045:        movzwl  $45,r6
                   25292:        jmp     error
                   25293: er_046:        movzwl  $46,r6
                   25294:        jmp     error
                   25295: er_047:        movzwl  $47,r6
                   25296:        jmp     error
                   25297: er_048:        movzwl  $48,r6
                   25298:        jmp     error
                   25299: er_049:        movzwl  $49,r6
                   25300:        jmp     error
                   25301: er_050:        movzwl  $50,r6
                   25302:        jmp     error
                   25303: er_051:        movzwl  $51,r6
                   25304:        jmp     error
                   25305: er_052:        movzwl  $52,r6
                   25306:        jmp     error
                   25307: er_053:        movzwl  $53,r6
                   25308:        jmp     error
                   25309: er_054:        movzwl  $54,r6
                   25310:        jmp     error
                   25311: er_055:        movzwl  $55,r6
                   25312:        jmp     error
                   25313: er_056:        movzwl  $56,r6
                   25314:        jmp     error
                   25315: er_057:        movzwl  $57,r6
                   25316:        jmp     error
                   25317: er_058:        movzwl  $58,r6
                   25318:        jmp     error
                   25319: er_059:        movzwl  $59,r6
                   25320:        jmp     error
                   25321: er_060:        movzwl  $60,r6
                   25322:        jmp     error
                   25323: er_061:        movzwl  $61,r6
                   25324:        jmp     error
                   25325: er_062:        movzwl  $62,r6
                   25326:        jmp     error
                   25327: er_063:        movzwl  $63,r6
                   25328:        jmp     error
                   25329: er_064:        movzwl  $64,r6
                   25330:        jmp     error
                   25331: er_065:        movzwl  $65,r6
                   25332:        jmp     error
                   25333: er_066:        movzwl  $66,r6
                   25334:        jmp     error
                   25335: er_067:        movzwl  $67,r6
                   25336:        jmp     error
                   25337: er_068:        movzwl  $68,r6
                   25338:        jmp     error
                   25339: er_069:        movzwl  $69,r6
                   25340:        jmp     error
                   25341: er_070:        movzwl  $70,r6
                   25342:        jmp     error
                   25343: er_071:        movzwl  $71,r6
                   25344:        jmp     error
                   25345: er_072:        movzwl  $72,r6
                   25346:        jmp     error
                   25347: er_073:        movzwl  $73,r6
                   25348:        jmp     error
                   25349: er_074:        movzwl  $74,r6
                   25350:        jmp     error
                   25351: er_075:        movzwl  $75,r6
                   25352:        jmp     error
                   25353: er_076:        movzwl  $76,r6
                   25354:        jmp     error
                   25355: er_077:        movzwl  $77,r6
                   25356:        jmp     error
                   25357: er_078:        movzwl  $78,r6
                   25358:        jmp     error
                   25359: er_079:        movzwl  $79,r6
                   25360:        jmp     error
                   25361: er_080:        movzwl  $80,r6
                   25362:        jmp     error
                   25363: er_081:        movzwl  $81,r6
                   25364:        jmp     error
                   25365: er_082:        movzwl  $82,r6
                   25366:        jmp     error
                   25367: er_083:        movzwl  $83,r6
                   25368:        jmp     error
                   25369: er_084:        movzwl  $84,r6
                   25370:        jmp     error
                   25371: er_085:        movzwl  $85,r6
                   25372:        jmp     error
                   25373: er_086:        movzwl  $86,r6
                   25374:        jmp     error
                   25375: er_087:        movzwl  $87,r6
                   25376:        jmp     error
                   25377: er_088:        movzwl  $88,r6
                   25378:        jmp     error
                   25379: er_089:        movzwl  $89,r6
                   25380:        jmp     error
                   25381: er_090:        movzwl  $90,r6
                   25382:        jmp     error
                   25383: er_091:        movzwl  $91,r6
                   25384:        jmp     error
                   25385: er_092:        movzwl  $92,r6
                   25386:        jmp     error
                   25387: er_093:        movzwl  $93,r6
                   25388:        jmp     error
                   25389: er_094:        movzwl  $94,r6
                   25390:        jmp     error
                   25391: er_095:        movzwl  $95,r6
                   25392:        jmp     error
                   25393: er_096:        movzwl  $96,r6
                   25394:        jmp     error
                   25395: er_097:        movzwl  $97,r6
                   25396:        jmp     error
                   25397: er_098:        movzwl  $98,r6
                   25398:        jmp     error
                   25399: er_099:        movzwl  $99,r6
                   25400:        jmp     error
                   25401: er_100:        movzwl  $100,r6
                   25402:        jmp     error
                   25403: er_101:        movzwl  $101,r6
                   25404:        jmp     error
                   25405: er_102:        movzwl  $102,r6
                   25406:        jmp     error
                   25407: er_103:        movzwl  $103,r6
                   25408:        jmp     error
                   25409: er_104:        movzwl  $104,r6
                   25410:        jmp     error
                   25411: er_105:        movzwl  $105,r6
                   25412:        jmp     error
                   25413: er_106:        movzwl  $106,r6
                   25414:        jmp     error
                   25415: er_107:        movzwl  $107,r6
                   25416:        jmp     error
                   25417: er_108:        movzwl  $108,r6
                   25418:        jmp     error
                   25419: er_109:        movzwl  $109,r6
                   25420:        jmp     error
                   25421: er_110:        movzwl  $110,r6
                   25422:        jmp     error
                   25423: er_111:        movzwl  $111,r6
                   25424:        jmp     error
                   25425: er_112:        movzwl  $112,r6
                   25426:        jmp     error
                   25427: er_113:        movzwl  $113,r6
                   25428:        jmp     error
                   25429: er_114:        movzwl  $114,r6
                   25430:        jmp     error
                   25431: er_115:        movzwl  $115,r6
                   25432:        jmp     error
                   25433: er_116:        movzwl  $116,r6
                   25434:        jmp     error
                   25435: er_117:        movzwl  $117,r6
                   25436:        jmp     error
                   25437: er_118:        movzwl  $118,r6
                   25438:        jmp     error
                   25439: er_119:        movzwl  $119,r6
                   25440:        jmp     error
                   25441: er_120:        movzwl  $120,r6
                   25442:        jmp     error
                   25443: er_121:        movzwl  $121,r6
                   25444:        jmp     error
                   25445: er_122:        movzwl  $122,r6
                   25446:        jmp     error
                   25447: er_123:        movzwl  $123,r6
                   25448:        jmp     error
                   25449: er_124:        movzwl  $124,r6
                   25450:        jmp     error
                   25451: er_125:        movzwl  $125,r6
                   25452:        jmp     error
                   25453: er_126:        movzwl  $126,r6
                   25454:        jmp     error
                   25455: er_127:        movzwl  $127,r6
                   25456:        jmp     error
                   25457: er_128:        movzwl  $128,r6
                   25458:        jmp     error
                   25459: er_129:        movzwl  $129,r6
                   25460:        jmp     error
                   25461: er_130:        movzwl  $130,r6
                   25462:        jmp     error
                   25463: er_131:        movzwl  $131,r6
                   25464:        jmp     error
                   25465: er_132:        movzwl  $132,r6
                   25466:        jmp     error
                   25467: er_133:        movzwl  $133,r6
                   25468:        jmp     error
                   25469: er_134:        movzwl  $134,r6
                   25470:        jmp     error
                   25471: er_135:        movzwl  $135,r6
                   25472:        jmp     error
                   25473: er_136:        movzwl  $136,r6
                   25474:        jmp     error
                   25475: er_137:        movzwl  $137,r6
                   25476:        jmp     error
                   25477: er_138:        movzwl  $138,r6
                   25478:        jmp     error
                   25479: er_139:        movzwl  $139,r6
                   25480:        jmp     error
                   25481: er_140:        movzwl  $140,r6
                   25482:        jmp     error
                   25483: er_141:        movzwl  $141,r6
                   25484:        jmp     error
                   25485: er_142:        movzwl  $142,r6
                   25486:        jmp     error
                   25487: er_143:        movzwl  $143,r6
                   25488:        jmp     error
                   25489: er_144:        movzwl  $144,r6
                   25490:        jmp     error
                   25491: er_145:        movzwl  $145,r6
                   25492:        jmp     error
                   25493: er_146:        movzwl  $146,r6
                   25494:        jmp     error
                   25495: er_147:        movzwl  $147,r6
                   25496:        jmp     error
                   25497: er_148:        movzwl  $148,r6
                   25498:        jmp     error
                   25499: er_149:        movzwl  $149,r6
                   25500:        jmp     error
                   25501: er_150:        movzwl  $150,r6
                   25502:        jmp     error
                   25503: er_151:        movzwl  $151,r6
                   25504:        jmp     error
                   25505: er_152:        movzwl  $152,r6
                   25506:        jmp     error
                   25507: er_153:        movzwl  $153,r6
                   25508:        jmp     error
                   25509: er_154:        movzwl  $154,r6
                   25510:        jmp     error
                   25511: er_155:        movzwl  $155,r6
                   25512:        jmp     error
                   25513: er_156:        movzwl  $156,r6
                   25514:        jmp     error
                   25515: er_157:        movzwl  $157,r6
                   25516:        jmp     error
                   25517: er_158:        movzwl  $158,r6
                   25518:        jmp     error
                   25519: er_159:        movzwl  $159,r6
                   25520:        jmp     error
                   25521: er_160:        movzwl  $160,r6
                   25522:        jmp     error
                   25523: er_161:        movzwl  $161,r6
                   25524:        jmp     error
                   25525: er_162:        movzwl  $162,r6
                   25526:        jmp     error
                   25527: er_163:        movzwl  $163,r6
                   25528:        jmp     error
                   25529: er_164:        movzwl  $164,r6
                   25530:        jmp     error
                   25531: er_165:        movzwl  $165,r6
                   25532:        jmp     error
                   25533: er_166:        movzwl  $166,r6
                   25534:        jmp     error
                   25535: er_167:        movzwl  $167,r6
                   25536:        jmp     error
                   25537: er_168:        movzwl  $168,r6
                   25538:        jmp     error
                   25539: er_169:        movzwl  $169,r6
                   25540:        jmp     error
                   25541: er_170:        movzwl  $170,r6
                   25542:        jmp     error
                   25543: er_171:        movzwl  $171,r6
                   25544:        jmp     error
                   25545: er_172:        movzwl  $172,r6
                   25546:        jmp     error
                   25547: er_173:        movzwl  $173,r6
                   25548:        jmp     error
                   25549: er_174:        movzwl  $174,r6
                   25550:        jmp     error
                   25551: er_175:        movzwl  $175,r6
                   25552:        jmp     error
                   25553: er_176:        movzwl  $176,r6
                   25554:        jmp     error
                   25555: er_177:        movzwl  $177,r6
                   25556:        jmp     error
                   25557: er_178:        movzwl  $178,r6
                   25558:        jmp     error
                   25559: er_179:        movzwl  $179,r6
                   25560:        jmp     error
                   25561: er_180:        movzwl  $180,r6
                   25562:        jmp     error
                   25563: er_181:        movzwl  $181,r6
                   25564:        jmp     error
                   25565: er_182:        movzwl  $182,r6
                   25566:        jmp     error
                   25567: er_183:        movzwl  $183,r6
                   25568:        jmp     error
                   25569: er_184:        movzwl  $184,r6
                   25570:        jmp     error
                   25571: er_185:        movzwl  $185,r6
                   25572:        jmp     error
                   25573: er_186:        movzwl  $186,r6
                   25574:        jmp     error
                   25575: er_187:        movzwl  $187,r6
                   25576:        jmp     error
                   25577: er_188:        movzwl  $188,r6
                   25578:        jmp     error
                   25579: er_189:        movzwl  $189,r6
                   25580:        jmp     error
                   25581: er_190:        movzwl  $190,r6
                   25582:        jmp     error
                   25583: er_191:        movzwl  $191,r6
                   25584:        jmp     error
                   25585: er_192:        movzwl  $192,r6
                   25586:        jmp     error
                   25587: er_193:        movzwl  $193,r6
                   25588:        jmp     error
                   25589: er_194:        movzwl  $194,r6
                   25590:        jmp     error
                   25591: er_195:        movzwl  $195,r6
                   25592:        jmp     error
                   25593: er_196:        movzwl  $196,r6
                   25594:        jmp     error
                   25595: er_197:        movzwl  $197,r6
                   25596:        jmp     error
                   25597: er_198:        movzwl  $198,r6
                   25598:        jmp     error
                   25599: er_199:        movzwl  $199,r6
                   25600:        jmp     error
                   25601: er_200:        movzwl  $200,r6
                   25602:        jmp     error
                   25603: er_201:        movzwl  $201,r6
                   25604:        jmp     error
                   25605: er_202:        movzwl  $202,r6
                   25606:        jmp     error
                   25607: er_203:        movzwl  $203,r6
                   25608:        jmp     error
                   25609: er_204:        movzwl  $204,r6
                   25610:        jmp     error
                   25611: er_205:        movzwl  $205,r6
                   25612:        jmp     error
                   25613: er_206:        movzwl  $206,r6
                   25614:        jmp     error
                   25615: er_207:        movzwl  $207,r6
                   25616:        jmp     error
                   25617: er_208:        movzwl  $208,r6
                   25618:        jmp     error
                   25619: er_209:        movzwl  $209,r6
                   25620:        jmp     error
                   25621: er_210:        movzwl  $210,r6
                   25622:        jmp     error
                   25623: er_211:        movzwl  $211,r6
                   25624:        jmp     error
                   25625: er_212:        movzwl  $212,r6
                   25626:        jmp     error
                   25627: er_213:        movzwl  $213,r6
                   25628:        jmp     error
                   25629: er_214:        movzwl  $214,r6
                   25630:        jmp     error
                   25631: er_215:        movzwl  $215,r6
                   25632:        jmp     error
                   25633: er_216:        movzwl  $216,r6
                   25634:        jmp     error
                   25635: er_217:        movzwl  $217,r6
                   25636:        jmp     error
                   25637: er_218:        movzwl  $218,r6
                   25638:        jmp     error
                   25639: er_219:        movzwl  $219,r6
                   25640:        jmp     error
                   25641: er_220:        movzwl  $220,r6
                   25642:        jmp     error
                   25643: er_221:        movzwl  $221,r6
                   25644:        jmp     error
                   25645: er_222:        movzwl  $222,r6
                   25646:        jmp     error
                   25647: er_223:        movzwl  $223,r6
                   25648:        jmp     error
                   25649: er_224:        movzwl  $224,r6
                   25650:        jmp     error
                   25651: er_225:        movzwl  $225,r6
                   25652:        jmp     error
                   25653: er_226:        movzwl  $226,r6
                   25654:        jmp     error
                   25655: er_227:        movzwl  $227,r6
                   25656:        jmp     error
                   25657: er_228:        movzwl  $228,r6
                   25658:        jmp     error
                   25659: er_229:        movzwl  $229,r6
                   25660:        jmp     error
                   25661: er_230:        movzwl  $230,r6
                   25662:        jmp     error
                   25663: er_231:        movzwl  $231,r6
                   25664:        jmp     error
                   25665: er_232:        movzwl  $232,r6
                   25666:        jmp     error
                   25667: er_233:        movzwl  $233,r6
                   25668:        jmp     error
                   25669: er_234:        movzwl  $234,r6
                   25670:        jmp     error
                   25671: er_235:        movzwl  $235,r6
                   25672:        jmp     error
                   25673: er_236:        movzwl  $236,r6
                   25674:        jmp     error
                   25675: er_237:        movzwl  $237,r6
                   25676:        jmp     error
                   25677: er_238:        movzwl  $238,r6
                   25678:        jmp     error
                   25679: er_239:        movzwl  $239,r6
                   25680:        jmp     error
                   25681: er_240:        movzwl  $240,r6
                   25682:        jmp     error
                   25683: er_241:        movzwl  $241,r6
                   25684:        jmp     error
                   25685: er_242:        movzwl  $242,r6
                   25686:        jmp     error
                   25687: er_243:        movzwl  $243,r6
                   25688:        jmp     error
                   25689: er_244:        movzwl  $244,r6
                   25690:        jmp     error
                   25691: er_245:        movzwl  $245,r6
                   25692:        jmp     error
                   25693: er_246:        movzwl  $246,r6
                   25694:        jmp     error
                   25695: er_247:        movzwl  $247,r6
                   25696:        jmp     error
                   25697: er_248:        movzwl  $248,r6
                   25698:        jmp     error
                   25699: er_249:        movzwl  $249,r6
                   25700:        jmp     error
                   25701: er_250:        movzwl  $250,r6
                   25702:        jmp     error
                   25703: er_251:        movzwl  $251,r6
                   25704:        jmp     error
                   25705: er_252:        movzwl  $252,r6
                   25706:        jmp     error
                   25707: er_253:        movzwl  $253,r6
                   25708:        jmp     error
                   25709: er_254:        movzwl  $254,r6
                   25710:        jmp     error
                   25711: er_255:        movzwl  $255,r6
                   25712:        jmp     error
                   25713: er_256:        movzwl  $256,r6
                   25714:        jmp     error
                   25715: er_257:        movzwl  $257,r6
                   25716:        jmp     error
                   25717: er_258:        movzwl  $258,r6
                   25718:        jmp     error
                   25719: er_259:        movzwl  $259,r6
                   25720:        jmp     error
                   25721: er_260:        movzwl  $260,r6
                   25722:        jmp     error
                   25723: er_261:        movzwl  $261,r6
                   25724:        jmp     error
                   25725: er_262:        movzwl  $262,r6
                   25726:        jmp     error
                   25727: er_263:        movzwl  $263,r6
                   25728:        jmp     error
                   25729: er_264:        movzwl  $264,r6
                   25730:        jmp     error
                   25731: er_265:        movzwl  $265,r6
                   25732:        jmp     error
                   25733: er_266:        movzwl  $266,r6
                   25734:        jmp     error
                   25735: er_267:        movzwl  $267,r6
                   25736:        jmp     error
                   25737: er_268:        movzwl  $268,r6
                   25738:        jmp     error
                   25739: er_269:        movzwl  $269,r6
                   25740:        jmp     error
                   25741: er_270:        movzwl  $270,r6
                   25742:        jmp     error
                   25743: er_271:        movzwl  $271,r6
                   25744:        jmp     error
                   25745: er_272:        movzwl  $272,r6
                   25746:        jmp     error
                   25747: er_273:        movzwl  $273,r6
                   25748:        jmp     error
                   25749: er_274:        movzwl  $274,r6
                   25750:        jmp     error
                   25751: er_275:        movzwl  $275,r6
                   25752:        jmp     error
                   25753: er_276:        movzwl  $276,r6
                   25754:        jmp     error
                   25755: er_277:        movzwl  $277,r6
                   25756:        jmp     error
                   25757: er_278:        movzwl  $278,r6
                   25758:        jmp     error
                   25759: er_279:        movzwl  $279,r6
                   25760:        jmp     error
                   25761: er_280:        movzwl  $280,r6
                   25762:        jmp     error
                   25763: er_281:        movzwl  $281,r6
                   25764:        jmp     error
                   25765: er_282:        movzwl  $282,r6
                   25766:        jmp     error
                   25767: er_283:        movzwl  $283,r6
                   25768:        jmp     error
                   25769: er_284:        movzwl  $284,r6
                   25770:        jmp     error
                   25771: er_285:        movzwl  $285,r6
                   25772:        jmp     error
                   25773: er_286:        movzwl  $286,r6
                   25774:        jmp     error
                   25775: er_287:        movzwl  $287,r6
                   25776:        jmp     error
                   25777: er_288:        movzwl  $288,r6
                   25778:        jmp     error
                   25779: er_289:        movzwl  $289,r6
                   25780:        jmp     error
                   25781: er_290:        movzwl  $290,r6
                   25782:        jmp     error
                   25783: er_291:        movzwl  $291,r6
                   25784:        jmp     error
                   25785: er_292:        movzwl  $292,r6
                   25786:        jmp     error
                   25787: er_293:        movzwl  $293,r6
                   25788:        jmp     error
                   25789: er_294:        movzwl  $294,r6
                   25790:        jmp     error
                   25791: er_295:        movzwl  $295,r6
                   25792:        jmp     error
                   25793: er_296:        movzwl  $296,r6
                   25794:        jmp     error
                   25795: er_297:        movzwl  $297,r6
                   25796:        jmp     error
                   25797:        .globl  sec05
                   25798: sec05:         
                   25799:        #sec                    # start of stack overflow section
                   25800: #
                   25801:        incl    errft           # fatal error
                   25802:        movl    flptr,sp        # pop stack to avoid more fails
                   25803:        tstl    gbcfl           # jump if garbage collecting
                   25804:        bnequ   stak1
                   25805:        jmp     er_246          # stack overflow
                   25806: #
                   25807: #      NO CHANCE OF RECOVERY IN MID GARBAGE COLLECTION
                   25808: #
                   25809: stak1: movl    $endso,r9       # point to message
                   25810:        clrl    kvdmp           # memory is undumpable
                   25811:        jmp     stopr           # give up
                   25812:        #title  s p i t b o l -- error section
                   25813: #
                   25814: #      THIS SECTION OF CODE IS ENTERED WHENEVER A PROCEDURE
                   25815: #      RETURN VIA AN ERR PARAMETER OR AN ERB OPCODE IS OBEYED.
                   25816: #
                   25817: #      (WA)                  IS THE ERROR CODE
                   25818: #
                   25819: #      THE GLOBAL VARIABLE STAGE INDICATES THE POINT AT WHICH
                   25820: #      THE ERROR OCCURED AS FOLLOWS.
                   25821: #
                   25822: #      STAGE=STGIC           ERROR DURING INITIAL COMPILE
                   25823: #
                   25824: #      STAGE=STGXC           ERROR DURING COMPILE AT EXECUTE
                   25825: #                            TIME (CODE, CONVERT FUNCTION CALLS)
                   25826: #
                   25827: #      STAGE=STGEV           ERROR DURING COMPILATION OF
                   25828: #                            EXPRESSION AT EXECUTION TIME
                   25829: #                            (EVAL, CONVERT FUNCTION CALL).
                   25830: #
                   25831: #      STAGE=STGXT           ERROR AT EXECUTE TIME. COMPILER
                   25832: #                            NOT ACTIVE.
                   25833: #
                   25834: #      STAGE=STGCE           ERROR DURING INITIAL COMPILE AFTER
                   25835: #                            SCANNING OUT THE END LINE.
                   25836: #
                   25837: #      STAGE=STGXE           ERROR DURING COMPILE AT EXECUTE
                   25838: #                            TIME AFTER SCANNING END LINE.
                   25839: #
                   25840: #      STAGE=STGEE           ERROR DURING EXPRESSION EVALUATION
                   25841: #
                   25842:        #sec                    # start of error section
                   25843: #
                   25844: error: cmpl    r$cim,$cmlab    # jump if error in scanning label
                   25845:        bnequ   0f
                   25846:        jmp     cmple
                   25847: 0:             
                   25848:        movl    r6,kvert        # save error code
                   25849:        clrl    scnrs           # reset rescan switch for scane
                   25850:        clrl    scngo           # reset goto switch for scane
                   25851:        movl    stage,r9        # load current stage
                   25852:        casel   r9,$0,$stgno    # jump to appropriate error circuit
                   25853: 5:             
                   25854:        .word   err01-5b        # initial compile
                   25855:        .word   err04-5b        # execute time compile
                   25856:        .word   err04-5b        # eval compiling expr.
                   25857:        .word   err05-5b        # execute time
                   25858:        .word   err01-5b        # compile - after end
                   25859:        .word   err04-5b        # xeq compile-past end
                   25860:        .word   err04-5b        # eval evaluating expr
                   25861:        #esw                    # end switch on error type
                   25862:        #page   
                   25863: #
                   25864: #      ERROR DURING INITIAL COMPILE
                   25865: #
                   25866: #      THE ERROR MESSAGE IS PRINTED AS PART OF THE COMPILER
                   25867: #      OUTPUT. THIS PRINTOUT INCLUDES THE OFFENDING LINE (IF NOT
                   25868: #      PRINTED ALREADY) AND AN ERROR FLAG UNDER THE APPROPRIATE
                   25869: #      COLUMN AS INDICATED BY SCNSE UNLESS SCNSE IS SET TO ZERO.
                   25870: #
                   25871: #      AFTER PRINTING THE MESSAGE, THE GENERATED CODE IS
                   25872: #      MODIFIED TO AN ERROR CALL AND CONTROL IS RETURNED TO
                   25873: #      THE CMPIL PROCEDURE AFTER RESETTING THE STACK POINTER.
                   25874: #
                   25875: #      IF THE ERROR OCCURS AFTER THE END LINE, CONTROL RETURNS
                   25876: #      IN A SLIGHTLY DIFFERENT MANNER TO ENSURE PROPER CLEANUP.
                   25877: #
                   25878: err01: movl    cmpxs,sp        # reset stack pointer
                   25879:        #ssl    cmpss           # restore s-r stack ptr for cmpil
                   25880:        tstl    errsp           # jump if error suppress flag set
                   25881:        beqlu   0f
                   25882:        jmp     err03
                   25883: 0:             
                   25884:        movl    erich,erlst     # set flag for listr
                   25885:        jsb     listr           # list line
                   25886:        jsb     prtis           # terminate listing
                   25887:        clrl    erlst           # clear listr flag
                   25888:        movl    scnse,r6        # load scan element offset
                   25889:        tstl    r6              # skip if not set
                   25890:        beqlu   err02
                   25891:        movl    r6,r7           # loop counter
                   25892:        incl    r6              # increase for ch$ex
                   25893:        jsb     alocs           # string block for error flag
                   25894:        movl    r9,r6           # remember string ptr
                   25895:        movab   cfp$f(r9),r9    # ready for character storing
                   25896:        movl    r$cim,r10       # point to bad statement
                   25897:        movab   cfp$f(r10),r10  # ready to get chars
                   25898: #
                   25899: #      LOOP TO REPLACE ALL CHARS BUT TABS BY BLANKS
                   25900: #
                   25901: erra1: movzbl  (r10)+,r8       # get next char
                   25902:        cmpl    r8,$ch$ht       # skip if tab
                   25903:        beqlu   erra2
                   25904:        movl    $ch$bl,r8       # get a blank
                   25905:        #page   
                   25906: #
                   25907: #      MERGE TO STORE BLANK OR TAB IN ERROR LINE
                   25908: #
                   25909: erra2: movb    r8,(r9)+        # store char
                   25910:        sobgtr  r7,erra1        # loop
                   25911:        movl    $ch$ex,r10      # exclamation mark
                   25912:        movb    r10,(r9)        # store at end of error line
                   25913:        #csc    r9              # end of sch loop
                   25914:        movl    $stnpd,profs    # allow for statement number
                   25915:        movl    r6,r9           # point to error line
                   25916:        jsb     prtst           # print error line
                   25917: #
                   25918: #      HERE AFTER PLACING ERROR FLAG AS REQUIRED
                   25919: #
                   25920: err02: jsb     ermsg           # generate flag and error message
                   25921:        addl2   $num03,lstlc    # bump page ctr for blank, error, blk
                   25922:        clrl    r9              # in case of fatal error
                   25923:        cmpl    errft,$num03    # pack up if several fatals
                   25924:        blssu   0f
                   25925:        jmp     stopr
                   25926: 0:             
                   25927: #
                   25928: #      COUNT ERROR, INHIBIT EXECUTION IF REQUIRED
                   25929: #
                   25930:        incl    cmerc           # bump error count
                   25931:        addl2   cswer,noxeq     # inhibit xeq if -noerrors
                   25932:        cmpl    stage,$stgic    # special return if after end line
                   25933:        beqlu   0f
                   25934:        jmp     cmp10
                   25935: 0:             
                   25936:        #page   
                   25937: #
                   25938: #      LOOP TO SCAN TO END OF STATEMENT
                   25939: #
                   25940: err03: movl    r$cim,r9        # point to start of image
                   25941:        movab   cfp$f(r9),r9    # point to first char
                   25942:        movzbl  (r9),r9         # get first char
                   25943:        cmpl    r9,$ch$mn       # jump if error in control card
                   25944:        bnequ   0f
                   25945:        jmp     cmpce
                   25946: 0:             
                   25947:        clrl    scnrs           # clear rescan flag
                   25948:        movl    sp,errsp        # set error suppress flag
                   25949:        jsb     scane           # scan next element
                   25950:        cmpl    r10,$t$smc      # loop back if not statement end
                   25951:        beqlu   0f
                   25952:        jmp     err03
                   25953: 0:             
                   25954:        clrl    errsp           # clear error suppress flag
                   25955: #
                   25956: #      GENERATE ERROR CALL IN CODE AND RETURN TO CMPIL
                   25957: #
                   25958:        movl    $4*cdcod,cwcof  # reset offset in ccblk
                   25959:        movl    $ocer$,r6       # load compile error call
                   25960:        jsb     cdwrd           # generate it
                   25961:        movl    cwcof,4*cmsoc(sp)# set success fill in offset
                   25962:        movl    sp,4*cmffc(sp)  # set failure fill in flag
                   25963:        jsb     cdwrd           # generate succ. fill in word
                   25964:        jmp     cmpse           # merge to generate error as cdfal
                   25965: #
                   25966: #      ERROR DURING EXECUTE TIME COMPILE OR EXPRESSION EVALUATIO
                   25967: #
                   25968: #      EXECUTE TIME COMPILATION IS INITIATED THROUGH GTCOD OR
                   25969: #      GTEXP WHICH ARE CALLED BY COMPILE, CODE OR EVAL.
                   25970: #      BEFORE CAUSING STATEMENT FAILURE THROUGH EXFAL IT IS
                   25971: #      HELPFUL TO SET KEYWORD ERRTEXT AND FOR GENERALITY
                   25972: #      THESE ERRORS MAY BE HANDLED BY THE SETEXIT MECHANISM.
                   25973: #
                   25974: err04: clrl    r$ccb           # forget garbage code block
                   25975:        #ssl    iniss           # restore main prog s-r stack ptr
                   25976:        jsb     ertex           # get fail message text
                   25977:        subl2   $4,sp           # ensure stack ok on loop start
                   25978: #
                   25979: #      POP STACK UNTIL FIND FLPTR FOR MOST DEEPLY NESTED PROG.
                   25980: #      DEFINED FUNCTION CALL OR CALL OF EVAL / CODE.
                   25981: #
                   25982: erra4: addl2   $4,sp           # pop stack
                   25983:        cmpl    sp,flprt        # jump if prog defined fn call found
                   25984:        beqlu   errc4
                   25985:        cmpl    sp,gtcef        # loop if not eval or code call yet
                   25986:        bnequ   erra4
                   25987:        movl    $stgxt,stage    # re-set stage for execute
                   25988:        movl    r$gtc,r$cod     # recover code ptr
                   25989:        movl    sp,flptr        # restore fail pointer
                   25990:        clrl    r$cim           # forget possible image
                   25991: #
                   25992: #      TEST ERRLIMIT
                   25993: #
                   25994: errb4: tstl    kverl           # jump if errlimit non-zero
                   25995:        bnequ   err07
                   25996:        jmp     exfal           # fail
                   25997: #
                   25998: #      RETURN FROM PROG. DEFINED FUNCTION IS OUTSTANDING
                   25999: #
                   26000: errc4: movl    flptr,sp        # restore stack from flptr
                   26001:        jmp     errb4           # merge
                   26002:        #page   
                   26003: #
                   26004: #      ERROR AT EXECUTE TIME.
                   26005: #
                   26006: #      THE ACTION TAKEN ON AN ERROR IS AS FOLLOWS.
                   26007: #
                   26008: #      IF ERRLIMIT KEYWORD IS ZERO, AN ABORT IS SIGNALLED,
                   26009: #      SEE CODING FOR SYSTEM LABEL ABORT AT L$ABO.
                   26010: #
                   26011: #      OTHERWISE, ERRLIMIT IS DECREMENTED AND AN ERRTYPE TRACE
                   26012: #      GENERATED IF REQUIRED. CONTROL RETURNS EITHER VIA A JUMP
                   26013: #      TO CONTINUE (TO TAKE THE FAILURE EXIT) OR A SPECIFIED
                   26014: #      SETEXIT TRAP IS EXECUTED AND CONTROL PASSES TO THE TRAP.
                   26015: #      IF 3 OR MORE FATAL ERRORS OCCUR AN ABORT IS SIGNALLED
                   26016: #      REGARDLESS OF ERRLIMIT AND SETEXIT - LOOPING IS ALL TOO
                   26017: #      PROBABLE OTHERWISE. FATAL ERRORS INCLUDE STACK OVERFLOW
                   26018: #      AND EXCEEDING STLIMIT.
                   26019: #
                   26020: err05: #ssl    iniss           # restore main prog s-r stack ptr
                   26021:        tstl    dmvch           # jump if in mid-dump
                   26022:        bnequ   err08
                   26023: #
                   26024: #      MERGE HERE FROM ERR08
                   26025: #
                   26026: err06: tstl    kverl           # abort if errlimit is zero
                   26027:        bnequ   0f
                   26028:        jmp     labo1
                   26029: 0:             
                   26030:        jsb     ertex           # get fail message text
                   26031: #
                   26032: #      MERGE FROM ERR04
                   26033: #
                   26034: err07: cmpl    errft,$num03    # abort if too many fatal errors
                   26035:        blssu   0f
                   26036:        jmp     labo1
                   26037: 0:             
                   26038:        decl    kverl           # decrement errlimit
                   26039:        movl    r$ert,r10       # load errtype trace pointer
                   26040:        jsb     ktrex           # generate errtype trace if required
                   26041:        movl    r$cod,r$cnt     # set cdblk ptr for continuation
                   26042:        movl    flptr,r9        # set ptr to failure offset
                   26043:        movl    (r9),stxof      # save failure offset for continue
                   26044:        movl    r$sxc,r9        # load setexit cdblk pointer
                   26045:        tstl    r9              # continue if no setexit trap
                   26046:        bnequ   0f
                   26047:        jmp     lcnt1
                   26048: 0:             
                   26049:        clrl    r$sxc           # else reset trap
                   26050:        movl    $nulls,stxvr    # reset setexit arg to null
                   26051:        movl    (r9),r10        # load ptr to code block routine
                   26052:        movl    r10,r11         # execute first trap statement
                   26053:        jmp     (r11)
                   26054: #
                   26055: #      INTERRUPTED PARTLY THROUGH A DUMP WHILST STORE IS IN A
                   26056: #      MESS SO DO A TIDY UP OPERATION. SEE DUMPR FOR DETAILS.
                   26057: #
                   26058: err08: movl    dmvch,r9        # chain head for affected vrblks
                   26059:        tstl    r9              # done if zero
                   26060:        beqlu   err06
                   26061:        movl    (r9),dmvch      # set next link as chain head
                   26062:        jsb     setvr           # restore vrget field
                   26063:        jmp     err08           # loop through chain
                   26064:        #title  s p i t b o l -- here endeth the code
                   26065: #
                   26066: #      END OF ASSEMBLY
                   26067: #
                   26068:        #end                    # end macro-spitbol assembly

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.