Annotation of researchv10no/cmd/spitbol/spitv35.serr, 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:        beqlu   ini13           # skip if no terminal
                   6299:        jsb     prpar           # associate terminal
                   6300:        #page   
                   6301: #
                   6302: #      CHECK FOR EXPIRY DATE
                   6303: #
                   6304: ini13: jsb     sysdc           # call date check
                   6305:        movl    sp,flptr        # in case stack overflows in compiler
                   6306: #
                   6307: #      NOW COMPILE SOURCE INPUT CODE
                   6308: #
                   6309:        jsb     cmpil           # call compiler
                   6310:        movl    r9,r$cod        # set ptr to first code block
                   6311:        movl    $nulls,r$ttl    # forget title      (reg04)
                   6312:        movl    $nulls,r$stl    # forget sub-title  (reg04)
                   6313:        clrl    r$cim           # forget compiler input image
                   6314:        clrl    r10             # clear dud value
                   6315:        clrl    r7              # dont shift dynamic store up
                   6316:        jsb     gbcol           # clear garbage left from compile
                   6317:        tstl    cpsts           # skip if no listing of comp stats
                   6318:        beqlu   0f
                   6319:        jmp     inix0
                   6320: 0:             
                   6321:        jsb     prtpg           # eject page
                   6322: #
                   6323: #      PRINT COMPILE STATISTICS
                   6324: #
                   6325:        movl    dnamp,r6        # next available loc
                   6326:        subl2   statb,r6        # minus start
                   6327:        ashl    $-2,r6,r6       # convert to words
                   6328:        movl    r6,r5           # convert to integer
                   6329:        movl    $encm1,r9       # point to /memory used (words)/
                   6330:        jsb     prtmi           # print message
                   6331:        movl    dname,r6        # end of memory
                   6332:        subl2   dnamp,r6        # minus next available loc
                   6333:        ashl    $-2,r6,r6       # convert to words
                   6334:        movl    r6,r5           # convert to integer
                   6335:        movl    $encm2,r9       # point to /memory available (words)/
                   6336:        jsb     prtmi           # print line
                   6337:        movl    cmerc,r5        # get count of errors as integer
                   6338:        movl    $encm3,r9       # point to /compile errors/
                   6339:        jsb     prtmi           # print it
                   6340:        movl    gbcnt,r5        # garbage collection count
                   6341:        subl2   intv1,r5        # adjust for unavoidable collect
                   6342:        movl    $stpm5,r9       # point to /storage regenerations/
                   6343:        jsb     prtmi           # print gbcol count
                   6344:        jsb     systm           # get time
                   6345:        subl2   timsx,r5        # get compilation time
                   6346:        movl    $encm4,r9       # point to compilation time (msec)/
                   6347:        jsb     prtmi           # print message
                   6348:        addl2   $num05,lstlc    # bump line count
                   6349:        tstl    headp           # no eject if nothing printed (sdg11)
                   6350:        bnequ   0f
                   6351:        jmp     inix0
                   6352: 0:             
                   6353:        jsb     prtpg           # eject printer
                   6354:        #page   
                   6355: #
                   6356: #      PREPARE NOW TO START EXECUTION
                   6357: #
                   6358: #      SET DEFAULT INPUT RECORD LENGTH
                   6359: #
                   6360: inix0: cmpl    cswin,$iniln    # skip if not default -in72 used
                   6361:        bgtru   inix1
                   6362:        movl    $inils,cswin    # else use default record length
                   6363: #
                   6364: #      RESET TIMER
                   6365: #
                   6366: inix1: jsb     systm           # get time again
                   6367:        movl    r5,timsx        # store for end run processing
                   6368:        addl2   cswex,noxeq     # add -noexecute flag
                   6369:        bnequ   inix2           # jump if execution suppressed
                   6370:        clrl    gbcnt           # initialise collect count
                   6371:        jsb     sysbx           # call before starting execution
                   6372: #
                   6373: #      MERGE WHEN LISTING FILE SET FOR EXECUTION
                   6374: #
                   6375: iniy0: movl    sp,headp        # mark headers out regardless
                   6376:        clrl    -(sp)           # set failure location on stack
                   6377:        movl    sp,flptr        # save ptr to failure offset word
                   6378:        movl    r$cod,r9        # load ptr to entry code block
                   6379:        movl    $stgxt,stage    # set stage for execute time
                   6380:        movl    cmpsn,pfnte     # copy stmts compiled count in case
                   6381:        jsb     systm           # time yet again
                   6382:        movl    r5,pfstm
                   6383:        movl    (r9),r11        # start xeq with first statement
                   6384:        jmp     (r11)
                   6385: #
                   6386: #      HERE IF EXECUTION IS SUPPRESSED
                   6387: #
                   6388: inix2: jsb     prtnl           # print a blank line
                   6389:        movl    $encm5,r9       # point to /execution suppressed/
                   6390:        jsb     prtst           # print string
                   6391:        jsb     prtnl           # output line
                   6392:        clrl    r6              # set abend value to zero
                   6393:        movl    $nini9,r7       # set special code value
                   6394:        jsb     sysej           # end of job, exit to system
                   6395:        #title  s p i t b o l -- snobol4 operator routines
                   6396: #
                   6397: #      THIS SECTION INCLUDES ALL ROUTINES WHICH CAN BE ACCESSED
                   6398: #      DIRECTLY FROM THE GENERATED CODE EXCEPT SYSTEM FUNCTIONS.
                   6399: #
                   6400: #      ALL ROUTINES IN THIS SECTION START WITH A LABEL OF THE
                   6401: #      FORM O$XXX WHERE XXX IS THREE LETTERS. THE GENERATED CODE
                   6402: #      CONTAINS A POINTER TO THE APPROPRIATE ENTRY LABEL.
                   6403: #
                   6404: #      SINCE THE GENERAL FORM OF THE GENERATED CODE CONSISTS OF
                   6405: #      POINTERS TO BLOCKS WHOSE FIRST WORD IS THE ADDRESS OF THE
                   6406: #      ACTUAL ENTRY POINT LABEL (O$XXX).
                   6407: #
                   6408: #      THESE ROUTINES ARE IN ALPHABETICAL ORDER BY THEIR
                   6409: #      ENTRY LABEL NAMES (I.E. BY THE XXX OF THE O$XXX NAME)
                   6410: #
                   6411: #      THESE ROUTINES RECEIVE CONTROL AS FOLLOWS
                   6412: #
                   6413: #      (CP)                  POINTER TO NEXT CODE WORD
                   6414: #      (XS)                  CURRENT STACK POINTER
                   6415:        #page   
                   6416: #
                   6417: #      BINARY PLUS (ADDITION)
                   6418: #
                   6419: o$add:                         # entry point
                   6420:        jsb     arith           # fetch arithmetic operands
                   6421:        .long   er_001          # addition left operand is not numeric
                   6422:        .long   er_002          # addition right operand is not numeric
                   6423:        .long   oadd1           # jump if real operands
                   6424: #
                   6425: #      HERE TO ADD TWO INTEGERS
                   6426: #
                   6427:        addl2   4*icval(r10),r5 # add right operand to left
                   6428:        bvs     0f
                   6429:        jmp     exint
                   6430: 0:             
                   6431:        jmp     er_003          # addition caused integer overflow
                   6432: #
                   6433: #      HERE TO ADD TWO REALS
                   6434: #
                   6435: oadd1: addf2   4*rcval(r10),r2 # add right operand to left
                   6436:        bvs     0f
                   6437:        jmp     exrea
                   6438: 0:             
                   6439:        jmp     er_261          # addition caused real overflow
                   6440:        #page   
                   6441: #
                   6442: #      UNARY PLUS (AFFIRMATION)
                   6443: #
                   6444: o$aff:                         # entry point
                   6445:        movl    (sp)+,r9        # load operand
                   6446:        jsb     gtnum           # convert to numeric
                   6447:        .long   er_004          # affirmation operand is not numeric
                   6448:        jmp     exixr           # return if converted to numeric
                   6449:        #page   
                   6450: #
                   6451: #      BINARY BAR (ALTERNATION)
                   6452: #
                   6453: o$alt:                         # entry point
                   6454:        movl    (sp)+,r9        # load right operand
                   6455:        jsb     gtpat           # convert to pattern
                   6456:        .long   er_005          # alternation right operand is not pattern
                   6457: #
                   6458: #      MERGE HERE FROM SPECIAL (LEFT ALTERNATION) CASE
                   6459: #
                   6460: oalt1: movl    $p$alt,r7       # set pcode for alternative node
                   6461:        jsb     pbild           # build alternative node
                   6462:        movl    r9,r10          # save address of alternative node
                   6463:        movl    (sp)+,r9        # load left operand
                   6464:        jsb     gtpat           # convert to pattern
                   6465:        .long   er_006          # alternation left operand is not pattern
                   6466:        cmpl    r9,$p$alt       # jump if left arg is alternation
                   6467:        beqlu   oalt2
                   6468:        movl    r9,4*pthen(r10) # set left operand as successor
                   6469:        movl    r10,r9          # move result to proper register
                   6470:        jmp     exixr           # jump for next code word
                   6471: #
                   6472: #      COME HERE IF LEFT ARGUMENT IS ITSELF AN ALTERNATION
                   6473: #
                   6474: #      THE RESULT IS MORE EFFICIENT IF WE MAKE THE REPLACEMENT
                   6475: #
                   6476: #      (A / B) / C = A / (B / C)
                   6477: #
                   6478: oalt2: movl    4*parm1(r9),4*pthen(r10) # build the (b / c) node
                   6479:        movl    4*pthen(r9),-(sp)# set a as new left arg
                   6480:        movl    r10,r9          # set (b / c) as new right arg
                   6481:        jmp     oalt1           # merge back to build a / (b / c)
                   6482:        #page   
                   6483: #
                   6484: #      ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY NAME)
                   6485: #
                   6486: o$amn:                         # entry point
                   6487:        movl    (r3)+,r9        # load number of subscripts
                   6488:        movl    r9,r7           # set flag for by name
                   6489:        jmp     arref           # jump to array reference routine
                   6490:        #page   
                   6491: #
                   6492: #      ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY VALUE)
                   6493: #
                   6494: o$amv:                         # entry point
                   6495:        movl    (r3)+,r9        # load number of subscripts
                   6496:        clrl    r7              # set flag for by value
                   6497:        jmp     arref           # jump to array reference routine
                   6498:        #page   
                   6499: #
                   6500: #      ARRAY REFERENCE (ONE SUBSCRIPT, BY NAME)
                   6501: #
                   6502: o$aon:                         # entry point
                   6503:        movl    (sp),r9         # load subscript value
                   6504:        movl    4*1(sp),r10     # load array value
                   6505:        movl    (r10),r6        # load first word of array operand
                   6506:        cmpl    r6,$b$vct       # jump if vector reference
                   6507:        beqlu   oaon2
                   6508:        cmpl    r6,$b$tbt       # jump if table reference
                   6509:        beqlu   oaon3
                   6510: #
                   6511: #      HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE
                   6512: #
                   6513: oaon1: movl    $num01,r9       # set number of subscripts to one
                   6514:        movl    r9,r7           # set flag for by name
                   6515:        jmp     arref           # jump to array reference routine
                   6516: #
                   6517: #      HERE IF WE HAVE A VECTOR REFERENCE
                   6518: #
                   6519: oaon2: cmpl    (r9),$b$icl     # use long routine if not integer
                   6520:        bnequ   oaon1
                   6521:        movl    4*icval(r9),r5  # load integer subscript value
                   6522:        movl    r5,r6           # copy as address int, fail if ovflo
                   6523:        bgeq    0f
                   6524:        jmp     exfal
                   6525: 0:             
                   6526:        tstl    r6              # fail if zero
                   6527:        bnequ   0f
                   6528:        jmp     exfal
                   6529: 0:             
                   6530:        addl2   $vcvlb,r6       # compute offset in words
                   6531:        moval   0[r6],r6        # convert to bytes
                   6532:        movl    r6,(sp)         # complete name on stack
                   6533:        cmpl    r6,4*vclen(r10) # exit if subscript not too large
                   6534:        bgequ   0f
                   6535:        jmp     exits
                   6536: 0:             
                   6537:        jmp     exfal           # else fail
                   6538: #
                   6539: #      HERE FOR TABLE REFERENCE
                   6540: #
                   6541: oaon3: movl    sp,r7           # set flag for name reference
                   6542:        jsb     tfind           # locate/create table element
                   6543:        .long   exfal           # fail if access fails
                   6544:        movl    r10,4*1(sp)     # store name base on stack
                   6545:        movl    r6,(sp)         # store name offset on stack
                   6546:        jmp     exits           # exit with result on stack
                   6547:        #page   
                   6548: #
                   6549: #      ARRAY REFERENCE (ONE SUBSCRIPT, BY VALUE)
                   6550: #
                   6551: o$aov:                         # entry point
                   6552:        movl    (sp)+,r9        # load subscript value
                   6553:        movl    (sp)+,r10       # load array value
                   6554:        movl    (r10),r6        # load first word of array operand
                   6555:        cmpl    r6,$b$vct       # jump if vector reference
                   6556:        beqlu   oaov2
                   6557:        cmpl    r6,$b$tbt       # jump if table reference
                   6558:        beqlu   oaov3
                   6559: #
                   6560: #      HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE
                   6561: #
                   6562: oaov1: movl    r10,-(sp)       # restack array value
                   6563:        movl    r9,-(sp)        # restack subscript
                   6564:        movl    $num01,r9       # set number of subscripts to one
                   6565:        clrl    r7              # set flag for value call
                   6566:        jmp     arref           # jump to array reference routine
                   6567: #
                   6568: #      HERE IF WE HAVE A VECTOR REFERENCE
                   6569: #
                   6570: oaov2: cmpl    (r9),$b$icl     # use long routine if not integer
                   6571:        bnequ   oaov1
                   6572:        movl    4*icval(r9),r5  # load integer subscript value
                   6573:        movl    r5,r6           # move as one word int, fail if ovflo
                   6574:        bgeq    0f
                   6575:        jmp     exfal
                   6576: 0:             
                   6577:        tstl    r6              # fail if zero
                   6578:        bnequ   0f
                   6579:        jmp     exfal
                   6580: 0:             
                   6581:        addl2   $vcvlb,r6       # compute offset in words
                   6582:        moval   0[r6],r6        # convert to bytes
                   6583:        cmpl    r6,4*vclen(r10) # fail if subscript too large
                   6584:        blssu   0f
                   6585:        jmp     exfal
                   6586: 0:             
                   6587:        jsb     acess           # access value
                   6588:        .long   exfal           # fail if access fails
                   6589:        jmp     exixr           # else return value to caller
                   6590: #
                   6591: #      HERE FOR TABLE REFERENCE BY VALUE
                   6592: #
                   6593: oaov3: clrl    r7              # set flag for value reference
                   6594:        jsb     tfind           # call table search routine
                   6595:        .long   exfal           # fail if access fails
                   6596:        jmp     exixr           # exit with result in xr
                   6597:        #page   
                   6598: #
                   6599: #      ASSIGNMENT
                   6600: #
                   6601: o$ass:                         # entry point
                   6602: #
                   6603: #      O$RPL (PATTERN REPLACEMENT) MERGES HERE
                   6604: #
                   6605: oass0: movl    (sp)+,r7        # load value to be assigned
                   6606:        movl    (sp)+,r6        # load name offset
                   6607:        movl    (sp),r10        # load name base
                   6608:        movl    r7,(sp)         # store assigned value as result
                   6609:        jsb     asign           # perform assignment
                   6610:        .long   exfal           # fail if assignment fails
                   6611:        jmp     exits           # exit with result on stack
                   6612:        #page   
                   6613: #
                   6614: #      COMPILATION ERROR
                   6615: #
                   6616: o$cer:                         # entry point
                   6617:        jmp     er_007          # compilation error encountered during execution
                   6618:        #page   
                   6619: #
                   6620: #      UNARY AT (CURSOR ASSIGNMENT)
                   6621: #
                   6622: o$cas:                         # entry point
                   6623:        movl    (sp)+,r8        # load name offset (parm2)
                   6624:        movl    (sp)+,r9        # load name base (parm1)
                   6625:        movl    $p$cas,r7       # set pcode for cursor assignment
                   6626:        jsb     pbild           # build node
                   6627:        jmp     exixr           # jump for next code word
                   6628:        #page   
                   6629: #
                   6630: #      CONCATENATION
                   6631: #
                   6632: o$cnc:                         # entry point
                   6633:        movl    (sp),r9         # load right argument
                   6634:        cmpl    r9,$nulls       # jump if right arg is null
                   6635:        bnequ   0f
                   6636:        jmp     ocnc3
                   6637: 0:             
                   6638:        movl    4*1(sp),r10     # load left argument
                   6639:        cmpl    r10,$nulls      # jump if left argument is null
                   6640:        bnequ   0f
                   6641:        jmp     ocnc4
                   6642: 0:             
                   6643:        movl    $b$scl,r6       # get constant to test for string
                   6644:        cmpl    r6,(r10)        # jump if left arg not a string
                   6645:        beqlu   0f
                   6646:        jmp     ocnc2
                   6647: 0:             
                   6648:        cmpl    r6,(r9)         # jump if right arg not a string
                   6649:        beqlu   0f
                   6650:        jmp     ocnc2
                   6651: 0:             
                   6652: #
                   6653: #      MERGE HERE TO CONCATENATE TWO STRINGS
                   6654: #
                   6655: ocnc1: movl    4*sclen(r10),r6 # load left argument length
                   6656:        addl2   4*sclen(r9),r6  # compute result length
                   6657:        jsb     alocs           # allocate scblk for result
                   6658:        movl    r9,4*1(sp)      # store result ptr over left argument
                   6659:        movab   cfp$f(r9),r9    # prepare to store chars of result
                   6660:        movl    4*sclen(r10),r6 # get number of chars in left arg
                   6661:        movab   cfp$f(r10),r10  # prepare to load left arg chars
                   6662:        jsb     sbmvc           # move characters of left argument
                   6663:        movl    (sp)+,r10       # load right arg pointer, pop stack
                   6664:        movl    4*sclen(r10),r6 # load number of chars in right arg
                   6665:        movab   cfp$f(r10),r10  # prepare to load right arg chars
                   6666:        jsb     sbmvc           # move characters of right argument
                   6667:        jmp     exits           # exit with result on stack
                   6668: #
                   6669: #      COME HERE IF ARGUMENTS ARE NOT BOTH STRINGS
                   6670: #
                   6671: ocnc2: jsb     gtstg           # convert right arg to string
                   6672:        .long   ocnc5           # jump if right arg is not string
                   6673:        movl    r9,r10          # save right arg ptr
                   6674:        jsb     gtstg           # convert left arg to string
                   6675:        .long   ocnc6           # jump if left arg is not a string
                   6676:        movl    r9,-(sp)        # stack left argument
                   6677:        movl    r10,-(sp)       # stack right argument
                   6678:        movl    r9,r10          # move left arg to proper reg
                   6679:        movl    (sp),r9         # move right arg to proper reg
                   6680:        jmp     ocnc1           # merge back to concatenate strings
                   6681:        #page   
                   6682: #
                   6683: #      CONCATENATION (CONTINUED)
                   6684: #
                   6685: #      COME HERE FOR NULL RIGHT ARGUMENT
                   6686: #
                   6687: ocnc3: addl2   $4,sp           # remove right arg from stack
                   6688:        jmp     exits           # return with left argument on stack
                   6689: #
                   6690: #      HERE FOR NULL LEFT ARGUMENT
                   6691: #
                   6692: ocnc4: addl2   $4,sp           # unstack one argument
                   6693:        movl    r9,(sp)         # store right argument
                   6694:        jmp     exits           # exit with result on stack
                   6695: #
                   6696: #      HERE IF RIGHT ARGUMENT IS NOT A STRING
                   6697: #
                   6698: ocnc5: movl    r9,r10          # move right argument ptr
                   6699:        movl    (sp)+,r9        # load left arg pointer
                   6700: #
                   6701: #      MERGE HERE WHEN LEFT ARGUMENT IS NOT A STRING
                   6702: #
                   6703: ocnc6: jsb     gtpat           # convert left arg to pattern
                   6704:        .long   er_008          # concatenation left opnd is not string or pattern
                   6705:        movl    r9,-(sp)        # save result on stack
                   6706:        movl    r10,r9          # point to right operand
                   6707:        jsb     gtpat           # convert to pattern
                   6708:        .long   er_009          # concatenation right opd is not string or pattern
                   6709:        movl    r9,r10          # move for pconc
                   6710:        movl    (sp)+,r9        # reload left operand ptr
                   6711:        jsb     pconc           # concatenate patterns
                   6712:        jmp     exixr           # exit with result in xr
                   6713:        #page   
                   6714: #
                   6715: #      COMPLEMENTATION
                   6716: #
                   6717: o$com:                         # entry point
                   6718:        movl    (sp)+,r9        # load operand
                   6719:        movl    (r9),r6         # load type word
                   6720: #
                   6721: #      MERGE BACK HERE AFTER CONVERSION
                   6722: #
                   6723: ocom1: cmpl    r6,$b$icl       # jump if integer
                   6724:        beqlu   ocom2
                   6725:        cmpl    r6,$b$rcl       # jump if real
                   6726:        beqlu   ocom3
                   6727:        jsb     gtnum           # else convert to numeric
                   6728:        .long   er_010          # complementation operand is not numeric
                   6729:        jmp     ocom1           # back to check cases
                   6730: #
                   6731: #      HERE TO COMPLEMENT INTEGER
                   6732: #
                   6733: ocom2: movl    4*icval(r9),r5  # load integer value
                   6734:        mnegl   r5,r5           # negate
                   6735:        bvs     0f
                   6736:        jmp     exint
                   6737: 0:             
                   6738:        jmp     er_011          # complementation caused integer overflow
                   6739: #
                   6740: #      HERE TO COMPLEMENT REAL
                   6741: #
                   6742: ocom3: movf    4*rcval(r9),r2  # load real value
                   6743:        mnegf   r2,r2           # negate
                   6744:        jmp     exrea           # return real result
                   6745:        #page   
                   6746: #
                   6747: #      BINARY SLASH (DIVISION)
                   6748: #
                   6749: o$dvd:                         # entry point
                   6750:        jsb     arith           # fetch arithmetic operands
                   6751:        .long   er_012          # division left operand is not numeric
                   6752:        .long   er_013          # division right operand is not numeric
                   6753:        .long   odvd2           # jump if real operands
                   6754: #
                   6755: #      HERE TO DIVIDE TWO INTEGERS
                   6756: #
                   6757:        divl2   4*icval(r10),r5 # divide left operand by right
                   6758:        bvs     0f
                   6759:        jmp     exint
                   6760: 0:             
                   6761:        jmp     er_014          # division caused integer overflow
                   6762: #
                   6763: #      HERE TO DIVIDE TWO REALS
                   6764: #
                   6765: odvd2: divf2   4*rcval(r10),r2 # divide left operand by right
                   6766:        bvs     0f
                   6767:        jmp     exrea
                   6768: 0:             
                   6769:        jmp     er_262          # division caused real overflow
                   6770:        #page   
                   6771: #
                   6772: #      EXPONENTIATION
                   6773: #
                   6774: o$exp:                         # entry point
                   6775:        movl    (sp)+,r9        # load exponent
                   6776:        jsb     gtnum           # convert to number
                   6777:        .long   er_015          # exponentiation right operand is not numeric
                   6778:        cmpl    r6,$b$icl       # jump if real
                   6779:        beqlu   0f
                   6780:        jmp     oexp7
                   6781: 0:             
                   6782:        movl    r9,r10          # move exponent
                   6783:        movl    (sp)+,r9        # load base
                   6784:        jsb     gtnum           # convert to numeric
                   6785:        .long   er_016          # exponentiation left operand is not numeric
                   6786:        movl    4*icval(r10),r5 # load exponent
                   6787:        bgeq    0f              # error if negative exponent
                   6788:        jmp     oexp8
                   6789: 0:             
                   6790:        cmpl    r6,$b$rcl       # jump if base is real
                   6791:        beqlu   oexp3
                   6792: #
                   6793: #      HERE TO EXPONENTIATE AN INTEGER
                   6794: #
                   6795:        movl    r5,r6           # convert exponent to 1 word integer
                   6796:        bgeq    0f
                   6797:        jmp     oexp2
                   6798: 0:             
                   6799:                                # set loop counter
                   6800:        movl    intv1,r5        # load initial value of 1
                   6801:        tstl    r6              # jump if non-zero exponent
                   6802:        bnequ   oexp1
                   6803:        tstl    r5              # give zero as result for nonzero**0
                   6804:        beql    0f
                   6805:        jmp     exint
                   6806: 0:             
                   6807:        jmp     oexp4           # else error of 0**0
                   6808: #
                   6809: #      LOOP TO PERFORM EXPONENTIATION
                   6810: #
                   6811: oexp1: mull2   4*icval(r9),r5  # multiply by base
                   6812:        bvs     oexp2
                   6813:        sobgtr  r6,oexp1        # loop back till computation complete
                   6814:        jmp     exint           # then return integer result
                   6815: #
                   6816: #      HERE IF INTEGER OVERFLOW
                   6817: #
                   6818: oexp2: jmp     er_017          # exponentiation caused integer overflow
                   6819:        #page   
                   6820: #
                   6821: #      EXPONENTIATION (CONTINUED)
                   6822: #
                   6823: #      HERE TO EXPONENTIATE A REAL
                   6824: #
                   6825: oexp3: movl    r5,r6           # convert exponent to one word
                   6826:        bgeq    0f
                   6827:        jmp     oexp6
                   6828: 0:             
                   6829:                                # set loop counter
                   6830:        movf    reav1,r2        # load 1.0 as initial value
                   6831:        tstl    r6              # jump if non-zero exponent
                   6832:        bnequ   oexp5
                   6833:        tstf    r2              # return 1.0 if nonzero**zero
                   6834:        beql    0f
                   6835:        jmp     exrea
                   6836: 0:             
                   6837: #
                   6838: #      HERE FOR ERROR OF 0**0 OR 0.0**0
                   6839: #
                   6840: oexp4: jmp     er_018          # exponentiation result is undefined
                   6841: #
                   6842: #      LOOP TO PERFORM EXPONENTIATION
                   6843: #
                   6844: oexp5: mulf2   4*rcval(r9),r2  # multiply by base
                   6845:        bvs     oexp6
                   6846:        sobgtr  r6,oexp5        # loop till computation complete
                   6847:        jmp     exrea           # then return real result
                   6848: #
                   6849: #      HERE IF REAL OVERFLOW
                   6850: #
                   6851: oexp6: jmp     er_266          # exponentiation caused real overflow
                   6852: #
                   6853: #      HERE IF REAL EXPONENT
                   6854: #
                   6855: oexp7: jmp     er_267          # exponentiation right operand is real not integer
                   6856: #
                   6857: #      HERE FOR NEGATIVE EXPONENT
                   6858: #
                   6859: oexp8: jmp     er_019          # exponentiation right operand is negative
                   6860:        #page   
                   6861: #
                   6862: #      FAILURE IN EXPRESSION EVALUATION
                   6863: #
                   6864: #      THIS ENTRY POINT IS USED IF THE EVALUATION OF AN
                   6865: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, FAILS.
                   6866: #      CONTROL IS RETURNED TO AN APPROPRIATE POINT IN EVALX.
                   6867: #
                   6868: o$fex:                         # entry point
                   6869:        jmp     evlx6           # jump to failure loc in evalx
                   6870:        #page   
                   6871: #
                   6872: #      FAILURE DURING EVALUATION OF A COMPLEX OR DIRECT GOTO
                   6873: #
                   6874: o$fif:                         # entry point
                   6875:        jmp     er_020          # goto evaluation failure
                   6876:        #page   
                   6877: #
                   6878: #      FUNCTION CALL (MORE THAN ONE ARGUMENT)
                   6879: #
                   6880: o$fnc:                         # entry point
                   6881:        movl    (r3)+,r6        # load number of arguments
                   6882:        movl    (r3)+,r9        # load function vrblk pointer
                   6883:        movl    4*vrfnc(r9),r10 # load function pointer
                   6884:        cmpl    r6,4*fargs(r10) # use central routine if wrong num
                   6885:        beqlu   0f
                   6886:        jmp     cfunc
                   6887: 0:             
                   6888:        movl    (r10),r11       # jump to function if arg count ok
                   6889:        jmp     (r11)
                   6890:        #page   
                   6891: #
                   6892: #      FUNCTION NAME ERROR
                   6893: #
                   6894: o$fne:                         # entry point
                   6895:        movl    (r3)+,r6        # get next code word
                   6896:        cmpl    r6,$ornm$       # fail if not evaluating expression
                   6897:        bnequ   ofne1
                   6898:        tstl    4*2(sp) # ok if expr. was wanted by value
                   6899:        bnequ   0f
                   6900:        jmp     evlx3
                   6901: 0:             
                   6902: #
                   6903: #      HERE FOR ERROR
                   6904: #
                   6905: ofne1: jmp     er_021          # function called by name returned a value
                   6906:        #page   
                   6907: #
                   6908: #      FUNCTION CALL (SINGLE ARGUMENT)
                   6909: #
                   6910: o$fns:                         # entry point
                   6911:        movl    (r3)+,r9        # load function vrblk pointer
                   6912:        movl    $num01,r6       # set number of arguments to one
                   6913:        movl    4*vrfnc(r9),r10 # load function pointer
                   6914:        cmpl    r6,4*fargs(r10) # use central routine if wrong num
                   6915:        beqlu   0f
                   6916:        jmp     cfunc
                   6917: 0:             
                   6918:        movl    (r10),r11       # jump to function if arg count ok
                   6919:        jmp     (r11)
                   6920:        #page   
                   6921: #      CALL TO UNDEFINED FUNCTION
                   6922: #
                   6923: o$fun:                         # entry point
                   6924:        jmp     er_022          # undefined function called
                   6925:        #page   
                   6926: #
                   6927: #      EXECUTE COMPLEX GOTO
                   6928: #
                   6929: o$goc:                         # entry point
                   6930:        movl    4*1(sp),r9      # load name base pointer
                   6931:        cmpl    r9,state        # jump if not natural variable
                   6932:        bgequ   ogoc1
                   6933:        addl2   $4*vrtra,r9     # else point to vrtra field
                   6934:        movl    (r9),r11        # and jump through it
                   6935:        jmp     (r11)
                   6936: #
                   6937: #      HERE IF GOTO OPERAND IS NOT NATURAL VARIABLE
                   6938: #
                   6939: ogoc1: jmp     er_023          # goto operand is not a natural variable
                   6940:        #page   
                   6941: #
                   6942: #      EXECUTE DIRECT GOTO
                   6943: #
                   6944: o$god:                         # entry point
                   6945:        movl    (sp),r9         # load operand
                   6946:        movl    (r9),r6         # load first word
                   6947:        cmpl    r6,$b$cds       # jump if code block to code routine
                   6948:        bnequ   0f
                   6949:        jmp     bcds0
                   6950: 0:             
                   6951:        cmpl    r6,$b$cdc       # jump if code block to code routine
                   6952:        bnequ   0f
                   6953:        jmp     bcdc0
                   6954: 0:             
                   6955:        jmp     er_024          # goto operand in direct goto is not code
                   6956:        #page   
                   6957: #
                   6958: #      SET GOTO FAILURE TRAP
                   6959: #
                   6960: #      THIS ROUTINE IS EXECUTED AT THE START OF A COMPLEX OR
                   6961: #      DIRECT FAILURE GOTO TO TRAP A SUBSEQUENT FAIL (SEE EXFAL)
                   6962: #
                   6963: o$gof:                         # entry point
                   6964:        movl    flptr,r9        # point to fail offset on stack
                   6965:        addl2   $4,(r9)         # point failure to o$fif word
                   6966:        tstl    (r3)+           # point to next code word
                   6967:        jmp     exits           # exit to continue
                   6968:        #page   
                   6969: #
                   6970: #      BINARY DOLLAR (IMMEDIATE ASSIGNMENT)
                   6971: #
                   6972: #      THE PATTERN BUILT BY BINARY DOLLAR IS A COMPOUND PATTERN.
                   6973: #      SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR
                   6974: #      DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED.
                   6975: #
                   6976: o$ima:                         # entry point
                   6977:        movl    $p$imc,r7       # set pcode for last node
                   6978:        movl    (sp)+,r8        # pop name offset (parm2)
                   6979:        movl    (sp)+,r9        # pop name base (parm1)
                   6980:        jsb     pbild           # build p$imc node
                   6981:        movl    r9,r10          # save ptr to node
                   6982:        movl    (sp),r9         # load left argument
                   6983:        jsb     gtpat           # convert to pattern
                   6984:        .long   er_025          # immediate assignment left operand is not pattern
                   6985:        movl    r9,(sp)         # save ptr to left operand pattern
                   6986:        movl    $p$ima,r7       # set pcode for first node
                   6987:        jsb     pbild           # build p$ima node
                   6988:        movl    (sp)+,4*pthen(r9)# set left operand as p$ima successor
                   6989:        jsb     pconc           # concatenate to form final pattern
                   6990:        jmp     exixr           # all done
                   6991:        #page   
                   6992: #
                   6993: #      INDIRECTION (BY NAME)
                   6994: #
                   6995: o$inn:                         # entry point
                   6996:        movl    sp,r7           # set flag for result by name
                   6997:        jmp     indir           # jump to common routine
                   6998:        #page   
                   6999: #
                   7000: #      INTERROGATION
                   7001: #
                   7002: o$int:                         # entry point
                   7003:        movl    $nulls,(sp)     # replace operand with null
                   7004:        jmp     exits           # exit for next code word
                   7005:        #page   
                   7006: #
                   7007: #      INDIRECTION (BY VALUE)
                   7008: #
                   7009: o$inv:                         # entry point
                   7010:        clrl    r7              # set flag for by value
                   7011:        jmp     indir           # jump to common routine
                   7012:        #page   
                   7013: #
                   7014: #      KEYWORD REFERENCE (BY NAME)
                   7015: #
                   7016: o$kwn:                         # entry point
                   7017:        jsb     kwnam           # get keyword name
                   7018:        jmp     exnam           # exit with result name
                   7019:        #page   
                   7020: #
                   7021: #      KEYWORD REFERENCE (BY VALUE)
                   7022: #
                   7023: o$kwv:                         # entry point
                   7024:        jsb     kwnam           # get keyword name
                   7025:        movl    r9,dnamp        # delete kvblk
                   7026:        jsb     acess           # access value
                   7027:        .long   exnul           # dummy (unused) failure return
                   7028:        jmp     exixr           # jump with value in xr
                   7029:        #page   
                   7030: #
                   7031: #      LOAD EXPRESSION BY NAME
                   7032: #
                   7033: o$lex:                         # entry point
                   7034:        movl    $4*evsi$,r6     # set size of evblk
                   7035:        jsb     alloc           # allocate space for evblk
                   7036:        movl    $b$evt,(r9)     # set type word
                   7037:        movl    $trbev,4*evvar(r9) # set dummy trblk pointer
                   7038:        movl    (r3)+,r6        # load exblk pointer
                   7039:        movl    r6,4*evexp(r9)  # set exblk pointer
                   7040:        movl    r9,r10          # move name base to proper reg
                   7041:        movl    $4*evvar,r6     # set name offset = zero
                   7042:        jmp     exnam           # exit with name in (xl,wa)
                   7043:        #page   
                   7044: #
                   7045: #      LOAD PATTERN VALUE
                   7046: #
                   7047: o$lpt:                         # entry point
                   7048:        movl    (r3)+,r9        # load pattern pointer
                   7049:        jmp     exixr           # stack ptr and obey next code word
                   7050:        #page   
                   7051: #
                   7052: #      LOAD VARIABLE NAME
                   7053: #
                   7054: o$lvn:                         # entry point
                   7055:        movl    (r3)+,r6        # load vrblk pointer
                   7056:        movl    r6,-(sp)        # stack vrblk ptr (name base)
                   7057:        movl    $4*vrval,-(sp)  # stack name offset
                   7058:        jmp     exits           # exit with result on stack
                   7059:        #page   
                   7060: #
                   7061: #      BINARY ASTERISK (MULTIPLICATION)
                   7062: #
                   7063: o$mlt:                         # entry point
                   7064:        jsb     arith           # fetch arithmetic operands
                   7065:        .long   er_026          # multiplication left operand is not numeric
                   7066:        .long   er_027          # multiplication right operand is not numeric
                   7067:        .long   omlt1           # jump if real operands
                   7068: #
                   7069: #      HERE TO MULTIPLY TWO INTEGERS
                   7070: #
                   7071:        mull2   4*icval(r10),r5 # multiply left operand by right
                   7072:        bvs     0f
                   7073:        jmp     exint
                   7074: 0:             
                   7075:        jmp     er_028          # multiplication caused integer overflow
                   7076: #
                   7077: #      HERE TO MULTIPLY TWO REALS
                   7078: #
                   7079: omlt1: mulf2   4*rcval(r10),r2 # multiply left operand by right
                   7080:        bvs     0f
                   7081:        jmp     exrea
                   7082: 0:             
                   7083:        jmp     er_263          # multiplication caused real overflow
                   7084:        #page   
                   7085: #
                   7086: #      NAME REFERENCE
                   7087: #
                   7088: o$nam:                         # entry point
                   7089:        movl    $4*nmsi$,r6     # set length of nmblk
                   7090:        jsb     alloc           # allocate nmblk
                   7091:        movl    $b$nml,(r9)     # set name block code
                   7092:        movl    (sp)+,4*nmofs(r9)# set name offset from operand
                   7093:        movl    (sp)+,4*nmbas(r9)# set name base from operand
                   7094:        jmp     exixr           # exit with result in xr
                   7095:        #page   
                   7096: #
                   7097: #      NEGATION
                   7098: #
                   7099: #      INITIAL ENTRY
                   7100: #
                   7101: o$nta:                         # entry point
                   7102:        movl    (r3)+,r6        # load new failure offset
                   7103:        movl    flptr,-(sp)     # stack old failure pointer
                   7104:        movl    r6,-(sp)        # stack new failure offset
                   7105:        movl    sp,flptr        # set new failure pointer
                   7106:        jmp     exits           # jump to continue execution
                   7107: #
                   7108: #      ENTRY AFTER SUCCESSFUL EVALUATION OF OPERAND
                   7109: #
                   7110: o$ntb:                         # entry point
                   7111:        movl    4*2(sp),flptr   # restore old failure pointer
                   7112:        jmp     exfal           # and fail
                   7113: #
                   7114: #      ENTRY FOR FAILURE DURING OPERAND EVALUATION
                   7115: #
                   7116: o$ntc:                         # entry point
                   7117:        addl2   $4,sp           # pop failure offset
                   7118:        movl    (sp)+,flptr     # restore old failure pointer
                   7119:        jmp     exnul           # exit giving null result
                   7120:        #page   
                   7121: #
                   7122: #      USE OF UNDEFINED OPERATOR
                   7123: #
                   7124: o$oun:                         # entry point
                   7125:        jmp     er_029          # undefined operator referenced
                   7126:        #page   
                   7127: #
                   7128: #      BINARY DOT (PATTERN ASSIGNMENT)
                   7129: #
                   7130: #      THE PATTERN BUILT BY BINARY DOT IS A COMPOUND PATTERN.
                   7131: #      SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR
                   7132: #      DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED.
                   7133: #
                   7134: o$pas:                         # entry point
                   7135:        movl    $p$pac,r7       # load pcode for p$pac node
                   7136:        movl    (sp)+,r8        # load name offset (parm2)
                   7137:        movl    (sp)+,r9        # load name base (parm1)
                   7138:        jsb     pbild           # build p$pac node
                   7139:        movl    r9,r10          # save ptr to node
                   7140:        movl    (sp),r9         # load left operand
                   7141:        jsb     gtpat           # convert to pattern
                   7142:        .long   er_030          # pattern assignment left operand is not pattern
                   7143:        movl    r9,(sp)         # save ptr to left operand pattern
                   7144:        movl    $p$paa,r7       # set pcode for p$paa node
                   7145:        jsb     pbild           # build p$paa node
                   7146:        movl    (sp)+,4*pthen(r9)# set left operand as p$paa successor
                   7147:        jsb     pconc           # concatenate to form final pattern
                   7148:        jmp     exixr           # jump for next code word
                   7149:        #page   
                   7150: #
                   7151: #      PATTERN MATCH (BY NAME, FOR REPLACEMENT)
                   7152: #
                   7153: o$pmn:                         # entry point
                   7154:        clrl    r7              # set type code for match by name
                   7155:        jmp     match           # jump to routine to start match
                   7156:        #page   
                   7157: #
                   7158: #      PATTERN MATCH (STATEMENT)
                   7159: #
                   7160: #      O$PMS IS USED IN PLACE OF O$PMV WHEN THE PATTERN MATCH
                   7161: #      OCCURS AT THE OUTER (STATEMENT) LEVEL SINCE IN THIS
                   7162: #      CASE THE SUBSTRING VALUE NEED NOT BE CONSTRUCTED.
                   7163: #
                   7164: o$pms:                         # entry point
                   7165:        movl    $num02,r7       # set flag for statement to match
                   7166:        jmp     match           # jump to routine to start match
                   7167:        #page   
                   7168: #
                   7169: #      PATTERN MATCH (BY VALUE)
                   7170: #
                   7171: o$pmv:                         # entry point
                   7172:        movl    $num01,r7       # set type code for value match
                   7173:        jmp     match           # jump to routine to start match
                   7174:        #page   
                   7175: #
                   7176: #      POP TOP ITEM ON STACK
                   7177: #
                   7178: o$pop:                         # entry point
                   7179:        addl2   $4,sp           # pop top stack entry
                   7180:        jmp     exits           # obey next code word
                   7181:        #page   
                   7182: #
                   7183: #      TERMINATE EXECUTION (CODE COMPILED FOR END STATEMENT)
                   7184: #
                   7185: o$stp:                         # entry point
                   7186:        jmp     lend0           # jump to end circuit
                   7187:        #page   
                   7188: #
                   7189: #      RETURN NAME FROM EXPRESSION
                   7190: #      THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN
                   7191: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS
                   7192: #      A NAME. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX.
                   7193: #
                   7194: o$rnm:                         # entry point
                   7195:        jmp     evlx4           # return to evalx procedure
                   7196:        #page   
                   7197: #
                   7198: #      PATTERN REPLACEMENT
                   7199: #
                   7200: #      WHEN THIS ROUTINE GETS CONTROL, THE FOLLOWING STACK
                   7201: #      ENTRIES HAVE BEEN MADE (SEE END OF MATCH ROUTINE P$NTH)
                   7202: #
                   7203: #                            SUBJECT NAME BASE
                   7204: #                            SUBJECT NAME OFFSET
                   7205: #                            INITIAL CURSOR VALUE
                   7206: #                            FINAL CURSOR VALUE
                   7207: #                            SUBJECT POINTER
                   7208: #      (XS) ---------------- REPLACEMENT VALUE
                   7209: #
                   7210: o$rpl:                         # entry point
                   7211:        jsb     gtstg           # convert replacement val to string
                   7212:        .long   er_031          # pattern replacement right operand is not string
                   7213: #
                   7214: #      GET RESULT LENGTH AND ALLOCATE RESULT SCBLK
                   7215: #
                   7216:        movl    (sp),r10        # load subject string pointer
                   7217:        cmpl    (r10),$b$bct    # branch if buffer assignment
                   7218:        bnequ   0f
                   7219:        jmp     orpl4
                   7220: 0:             
                   7221:        addl2   4*sclen(r10),r6 # add subject string length
                   7222:        addl2   4*2(sp),r6      # add starting cursor
                   7223:        subl2   4*1(sp),r6      # minus final cursor = total length
                   7224:        bnequ   0f              # jump if result is null
                   7225:        jmp     orpl3
                   7226: 0:             
                   7227:        movl    r9,-(sp)        # restack replacement string
                   7228:        jsb     alocs           # allocate scblk for result
                   7229:        movl    4*3(sp),r6      # get initial cursor (part 1 len)
                   7230:        movl    r9,4*3(sp)      # stack result pointer
                   7231:        movab   cfp$f(r9),r9    # point to characters of result
                   7232: #
                   7233: #      MOVE PART 1 (START OF SUBJECT) TO RESULT
                   7234: #
                   7235:        tstl    r6              # jump if first part is null
                   7236:        beqlu   orpl1
                   7237:        movl    4*1(sp),r10     # else point to subject string
                   7238:        movab   cfp$f(r10),r10  # point to subject string chars
                   7239:        jsb     sbmvc           # move first part to result
                   7240:        #page   
                   7241: #      PATTERN REPLACEMENT (CONTINUED)
                   7242: #
                   7243: #      NOW MOVE IN REPLACEMENT VALUE
                   7244: #
                   7245: orpl1: movl    (sp)+,r10       # load replacement string, pop
                   7246:        movl    4*sclen(r10),r6 # load length
                   7247:        beqlu   orpl2           # jump if null replacement
                   7248:        movab   cfp$f(r10),r10  # else point to chars of replacement
                   7249:        jsb     sbmvc           # move in chars (part 2)
                   7250: #
                   7251: #      NOW MOVE IN REMAINDER OF STRING (PART 3)
                   7252: #
                   7253: orpl2: movl    (sp)+,r10       # load subject string pointer, pop
                   7254:        movl    (sp)+,r8        # load final cursor, pop
                   7255:        movl    4*sclen(r10),r6 # load subject string length
                   7256:        subl2   r8,r6           # minus final cursor = part 3 length
                   7257:        bnequ   0f              # jump to assign if part 3 is null
                   7258:        jmp     oass0
                   7259: 0:             
                   7260:        movab   cfp$f(r10)[r8],r10 # else point to last part of string
                   7261:        jsb     sbmvc           # move part 3 to result
                   7262:        jmp     oass0           # jump to perform assignment
                   7263: #
                   7264: #      HERE IF RESULT IS NULL
                   7265: #
                   7266: orpl3: addl2   $4*num02,sp     # pop subject str ptr, final cursor
                   7267:        movl    $nulls,(sp)     # set null result
                   7268:        jmp     oass0           # jump to assign null value
                   7269: #
                   7270: #      HERE FOR BUFFER SUBSTRING ASSIGNMENT
                   7271: #
                   7272: orpl4: movl    r9,r10          # copy scblk replacement ptr
                   7273:        movl    (sp)+,r9        # unstack bcblk ptr
                   7274:        movl    (sp)+,r7        # get final cursor value
                   7275:        movl    (sp)+,r6        # get initial cursor
                   7276:        subl2   r6,r7           # get length in wb
                   7277:        addl2   $4*num02,sp     # get rid of name base/offset
                   7278:        jsb     insbf           # insert substring
                   7279:        .long   invalid$        # convert fail impossible
                   7280:        .long   exfal           # fail if insert fails
                   7281:        jmp     exnul           # else null result
                   7282:        #page   
                   7283: #
                   7284: #      RETURN VALUE FROM EXPRESSION
                   7285: #
                   7286: #      THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN
                   7287: #      EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS
                   7288: #      A VALUE. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX
                   7289: #
                   7290: o$rvl:                         # entry point
                   7291:        jmp     evlx3           # return to evalx procedure
                   7292:        #page   
                   7293: #
                   7294: #      SELECTION
                   7295: #
                   7296: #      INITIAL ENTRY
                   7297: #
                   7298: o$sla:                         # entry point
                   7299:        movl    (r3)+,r6        # load new failure offset
                   7300:        movl    flptr,-(sp)     # stack old failure pointer
                   7301:        movl    r6,-(sp)        # stack new failure offset
                   7302:        movl    sp,flptr        # set new failure pointer
                   7303:        jmp     exits           # jump to execute first alternative
                   7304: #
                   7305: #      ENTRY AFTER SUCCESSFUL EVALUATION OF ALTERNATIVE
                   7306: #
                   7307: o$slb:                         # entry point
                   7308:        movl    (sp)+,r9        # load result
                   7309:        addl2   $4,sp           # pop fail offset
                   7310:        movl    (sp),flptr      # restore old failure pointer
                   7311:        movl    r9,(sp)         # restack result
                   7312:        movl    (r3)+,r6        # load new code offset
                   7313:        addl2   r$cod,r6        # point to absolute code location
                   7314:        movl    r6,r3           # set new code pointer
                   7315:        jmp     exits           # jump to continue past selection
                   7316: #
                   7317: #      ENTRY AT START OF SUBSEQUENT ALTERNATIVES
                   7318: #
                   7319: o$slc:                         # entry point
                   7320:        movl    (r3)+,r6        # load new fail offset
                   7321:        movl    r6,(sp)         # store new fail offset
                   7322:        jmp     exits           # jump to execute next alternative
                   7323: #
                   7324: #      ENTRY AT START OF LAST ALTERNATIVE
                   7325: #
                   7326: o$sld:                         # entry point
                   7327:        addl2   $4,sp           # pop failure offset
                   7328:        movl    (sp)+,flptr     # restore old failure pointer
                   7329:        jmp     exits           # jump to execute last alternative
                   7330:        #page   
                   7331: #
                   7332: #      BINARY MINUS (SUBTRACTION)
                   7333: #
                   7334: o$sub:                         # entry point
                   7335:        jsb     arith           # fetch arithmetic operands
                   7336:        .long   er_032          # subtraction left operand is not numeric
                   7337:        .long   er_033          # subtraction right operand is not numeric
                   7338:        .long   osub1           # jump if real operands
                   7339: #
                   7340: #      HERE TO SUBTRACT TWO INTEGERS
                   7341: #
                   7342:        subl2   4*icval(r10),r5 # subtract right operand from left
                   7343:        bvs     0f
                   7344:        jmp     exint
                   7345: 0:             
                   7346:        jmp     er_034          # subtraction caused integer overflow
                   7347: #
                   7348: #      HERE TO SUBTRACT TWO REALS
                   7349: #
                   7350: osub1: subf2   4*rcval(r10),r2 # subtract right operand from left
                   7351:        bvs     0f
                   7352:        jmp     exrea
                   7353: 0:             
                   7354:        jmp     er_264          # subtraction caused real overflow
                   7355:        #page   
                   7356: #
                   7357: #      DUMMY OPERATOR TO RETURN CONTROL TO TRXEQ PROCEDURE
                   7358: #
                   7359: o$txr:                         # entry point
                   7360:        jmp     trxq1           # jump into trxeq procedure
                   7361:        #page   
                   7362: #
                   7363: #      UNEXPECTED FAILURE
                   7364: #
                   7365: #      NOTE THAT IF A SETEXIT TRAP IS OPERATING THEN
                   7366: #      TRANSFER TO SYSTEM LABEL CONTINUE
                   7367: #      WILL RESULT IN LOOPING HERE.  DIFFICULT TO AVOID EXCEPT
                   7368: #      WITH A CONSIDERABLE OVERHEAD WHICH IS NOT WORTHWHILE OR
                   7369: #      ELSE BY A TECHNIQUE SUCH AS SETTING KVERL TO ZERO.
                   7370: #
                   7371: o$unf:                         # entry point
                   7372:        jmp     er_035          # unexpected failure in -nofail mode
                   7373:        #title  s p i t b o l -- snobol4 builtin label routines
                   7374: #
                   7375: #      THE FOLLOWING SECTION CONTAINS THE ROUTINES FOR LABELS
                   7376: #      WHICH HAVE A PREDEFINED MEANING IN SNOBOL4.
                   7377: #
                   7378: #      CONTROL IS PASSED DIRECTLY TO THE LABEL NAME ENTRY POINT.
                   7379: #
                   7380: #      ENTRY NAMES ARE OF THE FORM L$XXX WHERE XXX IS THE THREE
                   7381: #      LETTER VARIABLE NAME IDENTIFIER.
                   7382: #
                   7383: #      ENTRIES ARE IN ALPHABETICAL ORDER
                   7384:        #page   
                   7385: #
                   7386: #      ABORT
                   7387: #
                   7388: l$abo:                         # entry point
                   7389: #
                   7390: #      MERGE HERE IF EXECUTION TERMINATES IN ERROR
                   7391: #
                   7392: labo1: movl    kvert,r6        # load error code
                   7393:        beqlu   labo2           # jump if no error has occured
                   7394:        jsb     sysax           # call after execution proc (reg04)
                   7395:        jsb     prtpg           # else eject printer
                   7396:        jsb     ermsg           # print error message
                   7397:        clrl    r9              # indicate no message to print
                   7398:        jmp     stopr           # jump to routine to stop run
                   7399: #
                   7400: #      HERE IF NO ERROR HAD OCCURED
                   7401: #
                   7402: labo2: jmp     er_036          # goto abort with no preceding error
                   7403:        #page   
                   7404: #
                   7405: #      CONTINUE
                   7406: #
                   7407: l$cnt:                         # entry point
                   7408: #
                   7409: #      MERGE HERE AFTER EXECUTION ERROR
                   7410: #
                   7411: lcnt1: movl    r$cnt,r9        # load continuation code block ptr
                   7412:        beqlu   lcnt2           # jump if no previous error
                   7413:        clrl    r$cnt           # clear flag
                   7414:        movl    r9,r$cod        # else store as new code block ptr
                   7415:        addl2   stxof,r9        # add failure offset
                   7416:        movl    r9,r3           # load code pointer
                   7417:        movl    flptr,sp        # reset stack pointer
                   7418:        jmp     exits           # jump to take indicated failure
                   7419: #
                   7420: #      HERE IF NO PREVIOUS ERROR
                   7421: #
                   7422: lcnt2: jmp     er_037          # goto continue with no preceding error
                   7423:        #page   
                   7424: #
                   7425: #      END
                   7426: #
                   7427: l$end:                         # entry point
                   7428: #
                   7429: #      MERGE HERE FROM END CODE CIRCUIT
                   7430: #
                   7431: lend0: movl    $endms,r9       # point to message /normal term../
                   7432:        jmp     stopr           # jump to routine to stop run
                   7433:        #page   
                   7434: #
                   7435: #      FRETURN
                   7436: #
                   7437: l$frt:                         # entry point
                   7438:        movl    $scfrt,r6       # point to string /freturn/
                   7439:        jmp     retrn           # jump to common return routine
                   7440:        #page   
                   7441: #
                   7442: #      NRETURN
                   7443: #
                   7444: l$nrt:                         # entry point
                   7445:        movl    $scnrt,r6       # point to string /nreturn/
                   7446:        jmp     retrn           # jump to common return routine
                   7447:        #page   
                   7448: #
                   7449: #      RETURN
                   7450: #
                   7451: l$rtn:                         # entry point
                   7452:        movl    $scrtn,r6       # point to string /return/
                   7453:        jmp     retrn           # jump to common return routine
                   7454:        #page   
                   7455: #
                   7456: #      UNDEFINED LABEL
                   7457: #
                   7458: l$und:                         # entry point
                   7459:        jmp     er_038          # goto undefined label
                   7460:        #title  s p i t b o l -- block action routines
                   7461: #
                   7462: #      THE FIRST WORD OF EVERY BLOCK IN DYNAMIC STORAGE AND THE
                   7463: #      VRGET, VRSTO AND VRTRA FIELDS OF A VRBLK CONTAIN A
                   7464: #      POINTER TO AN ENTRY POINT IN THE PROGRAM. ALL SUCH ENTRY
                   7465: #      POINTS ARE IN THE FOLLOWING SECTION EXCEPT THOSE FOR
                   7466: #      PATTERN BLOCKS WHICH ARE IN THE PATTERN MATCHING SEGMENT
                   7467: #      LATER ON (LABELS OF THE FORM P$XXX), AND DOPE VECTORS
                   7468: #      (D$XXX) WHICH ARE IN THE DOPE VECTOR SECTION FOLLOWING
                   7469: #      THE PATTERN ROUTINES (DOPE VECTORS ARE USED FOR CMBLKS).
                   7470: #
                   7471: #      THE ENTRY POINTS IN THIS SECTION HAVE LABELS OF THE
                   7472: #      FORM B$XXY WHERE XX IS THE TWO CHARACTER BLOCK TYPE FOR
                   7473: #      THE CORRESPONDING BLOCK AND Y IS ANY LETTER.
                   7474: #
                   7475: #      IN SOME CASES, THE POINTERS SERVE NO OTHER PURPOSE THAN
                   7476: #      TO IDENTIFY THE BLOCK TYPE. IN THIS CASE THE ROUTINE
                   7477: #      IS NEVER EXECUTED AND THUS NO CODE IS ASSEMBLED.
                   7478: #
                   7479: #      FOR EACH OF THESE ENTRY POINTS CORRESPONDING TO A BLOCK
                   7480: #      AN ENTRY POINT IDENTIFICATION IS ASSEMBLED (BL$XX).
                   7481: #
                   7482: #      THE EXACT ENTRY CONDITIONS DEPEND ON THE MANNER IN
                   7483: #      WHICH THE ROUTINE IS ACCESSED AND ARE DOCUMENTED WITH
                   7484: #      THE INDIVIDUAL ROUTINES AS REQUIRED.
                   7485: #
                   7486: #      THE ORDER OF THESE ROUTINES IS ALPHABETICAL WITH THE
                   7487: #      FOLLOWING EXCEPTIONS.
                   7488: #
                   7489: #      THE ROUTINES FOR SEBLK AND EXBLK ENTRIES OCCUR FIRST SO
                   7490: #      THAT EXPRESSIONS CAN BE QUICKLY IDENTIFIED FROM THE FACT
                   7491: #      THAT THEIR ROUTINES LIE BEFORE THE SYMBOL B$E$$.
                   7492: #
                   7493: #      THESE ARE IMMEDIATELY FOLLOWED BY THE ROUTINE FOR A TRBLK
                   7494: #      SO THAT THE TEST AGAINST THE SYMBOL B$T$$ CHECKS FOR
                   7495: #      TRAPPED VALUES OR EXPRESSION VALUES (SEE PROCEDURE EVALP)
                   7496: #
                   7497: #      THE PATTERN ROUTINES LIE AFTER THIS SECTION SO THAT
                   7498: #      PATTERNS ARE IDENTIFIED WITH ROUTINES STARTING AT OR
                   7499: #      AFTER THE INITIAL INSTRUCTION IN THESE ROUTINES (P$AAA).
                   7500: #
                   7501: #      THE SYMBOL B$AAA DEFINES THE FIRST LOCATION FOR BLOCK
                   7502: #      ROUTINES AND THE SYMBOL P$YYY (AT THE END OF THE PATTERN
                   7503: #      MATCH ROUTINES SECTION) DEFINES THE LAST SUCH ENTRY POINT
                   7504: #
                   7505:        .align  2
                   7506:        .word   bl$$i
                   7507: b$aaa:                         # entry point of first block routine
                   7508:        #page   
                   7509: #
                   7510: #      EXBLK
                   7511: #
                   7512: #      THE ROUTINE FOR AN EXBLK LOADS THE EXPRESSION ONTO
                   7513: #      THE STACK AS A VALUE.
                   7514: #
                   7515: #      (XR)                  POINTER TO EXBLK
                   7516: #
                   7517:        .align  2
                   7518:        .word   bl$ex
                   7519: b$exl:                         # entry point (exblk)
                   7520:        jmp     exixr           # stack xr and obey next code word
                   7521:        #page   
                   7522: #
                   7523: #      SEBLK
                   7524: #
                   7525: #      THE ROUTINE FOR SEBLK IS ACCESSED FROM THE GENERATED
                   7526: #      CODE TO LOAD THE EXPRESSION VALUE ONTO THE STACK.
                   7527: #
                   7528:        .align  2
                   7529:        .word   bl$se
                   7530: b$sel:                         # entry point (seblk)
                   7531:        jmp     exixr           # stack xr and obey next code word
                   7532: #
                   7533: #      DEFINE SYMBOL WHICH MARKS END OF ENTRIES FOR EXPRESSIONS
                   7534: #
                   7535:        .align  2
                   7536:        .word   bl$$i
                   7537: b$e$$:                         # entry point
                   7538:        #page   
                   7539: #
                   7540: #      TRBLK
                   7541: #
                   7542: #      THE ROUTINE FOR A TRBLK IS NEVER EXECUTED
                   7543: #
                   7544:        .align  2
                   7545:        .word   bl$tr
                   7546: b$trt:                         # entry point (trblk)
                   7547: #
                   7548: #      DEFINE SYMBOL MARKING END OF TRAP AND EXPRESSION BLOCKS
                   7549: #
                   7550:        .align  2
                   7551:        .word   bl$$i
                   7552: b$t$$:                         # end of trblk,seblk,exblk entries
                   7553:        #page   
                   7554: #
                   7555: #      ARBLK
                   7556: #
                   7557: #      THE ROUTINE FOR ARBLK IS NEVER EXECUTED
                   7558: #
                   7559:        .align  2
                   7560:        .word   bl$ar
                   7561: b$art:                         # entry point (arblk)
                   7562:        #page   
                   7563: #
                   7564: #      BCBLK
                   7565: #
                   7566: #      THE ROUTINE FOR A BCBLK IS NEVER EXECUTED
                   7567: #
                   7568: #      (XR)                  POINTER TO BCBLK
                   7569: #
                   7570:        .align  2
                   7571:        .word   bl$bc
                   7572: b$bct:                         # entry point (bcblk)
                   7573:        #page   
                   7574: #
                   7575: #      BFBLK
                   7576: #
                   7577: #      THE ROUTINE FOR A BFBLK IS NEVER EXECUTED
                   7578: #
                   7579: #      (XR)                  POINTER TO BFBLK
                   7580: #
                   7581:        .align  2
                   7582:        .word   bl$bf
                   7583: b$bft:                         # entry point (bfblk)
                   7584:        #page   
                   7585: #
                   7586: #      CCBLK
                   7587: #
                   7588: #      THE ROUTINE FOR CCBLK IS NEVER ENTERED
                   7589: #
                   7590:        .align  2
                   7591:        .word   bl$cc
                   7592: b$cct:                         # entry point (ccblk)
                   7593:        #page   
                   7594: #
                   7595: #      CDBLK
                   7596: #
                   7597: #      THE CDBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE.
                   7598: #      THERE ARE TWO CASES DEPENDING ON THE FORM OF CDFAL.
                   7599: #
                   7600: #      ENTRY FOR COMPLEX FAILURE CODE AT CDFAL
                   7601: #
                   7602: #      (XR)                  POINTER TO CDBLK
                   7603: #
                   7604:        .align  2
                   7605:        .word   bl$cd
                   7606: b$cdc:                         # entry point (cdblk)
                   7607: bcdc0: movl    flptr,sp        # pop garbage off stack
                   7608:        movl    4*cdfal(r9),(sp)# set failure offset
                   7609:        jmp     stmgo           # enter stmt
                   7610:        #page   
                   7611: #
                   7612: #      CDBLK (CONTINUED)
                   7613: #
                   7614: #      ENTRY FOR SIMPLE FAILURE CODE AT CDFAL
                   7615: #
                   7616: #      (XR)                  POINTER TO CDBLK
                   7617: #
                   7618:        .align  2
                   7619:        .word   bl$cd
                   7620: b$cds:                         # entry point (cdblk)
                   7621: bcds0: movl    flptr,sp        # pop garbage off stack
                   7622:        movl    $4*cdfal,(sp)   # set failure offset
                   7623:        jmp     stmgo           # enter stmt
                   7624:        #page   
                   7625: #
                   7626: #      CMBLK
                   7627: #
                   7628: #      THE ROUTINE FOR A CMBLK IS NEVER EXECUTED
                   7629: #
                   7630:        .align  2
                   7631:        .word   bl$cm
                   7632: b$cmt:                         # entry point (cmblk)
                   7633:        #page   
                   7634: #
                   7635: #      CTBLK
                   7636: #
                   7637: #      THE ROUTINE FOR A CTBLK IS NEVER EXECUTED
                   7638: #
                   7639:        .align  2
                   7640:        .word   bl$ct
                   7641: b$ctt:                         # entry point (ctblk)
                   7642:        #page   
                   7643: #
                   7644: #      DFBLK
                   7645: #
                   7646: #      THE ROUTINE FOR A DFBLK IS ACCESSED FROM THE O$FNC ENTRY
                   7647: #      TO CALL A DATATYPE FUNCTION AND BUILD A PDBLK.
                   7648: #
                   7649: #      (XL)                  POINTER TO DFBLK
                   7650: #
                   7651:        .align  2
                   7652:        .word   bl$df
                   7653: b$dfc:                         # entry point
                   7654:        movl    4*dfpdl(r10),r6 # load length of pdblk
                   7655:        jsb     alloc           # allocate pdblk
                   7656:        movl    $b$pdt,(r9)     # store type word
                   7657:        movl    r10,4*pddfp(r9) # store dfblk pointer
                   7658:        movl    r9,r8           # save pointer to pdblk
                   7659:        addl2   r6,r9           # point past pdblk
                   7660:        movl    4*fargs(r10),r6 # set to count fields
                   7661: #
                   7662: #      LOOP TO ACQUIRE FIELD VALUES FROM STACK
                   7663: #
                   7664: bdfc1: movl    (sp)+,-(r9)     # move a field value
                   7665:        sobgtr  r6,bdfc1        # loop till all moved
                   7666:        movl    r8,r9           # recall pointer to pdblk
                   7667:        jmp     exsid           # exit setting id field
                   7668:        #page   
                   7669: #
                   7670: #      EFBLK
                   7671: #
                   7672: #      THE ROUTINE FOR AN EFBLK IS PASSED CONTROL FORM THE O$FNC
                   7673: #      ENTRY TO CALL AN EXTERNAL FUNCTION.
                   7674: #
                   7675: #      (XL)                  POINTER TO EFBLK
                   7676: #
                   7677:        .align  2
                   7678:        .word   bl$ef
                   7679: b$efc:                         # entry point (efblk)
                   7680:        movl    4*fargs(r10),r8 # load number of arguments
                   7681:        moval   0[r8],r8        # convert to offset
                   7682:        movl    r10,-(sp)       # save pointer to efblk
                   7683:        movl    sp,r10          # copy pointer to arguments
                   7684: #
                   7685: #      LOOP TO CONVERT ARGUMENTS
                   7686: #
                   7687: befc1: addl2   $4,r10          # point to next entry
                   7688:        movl    (sp),r9         # load pointer to efblk
                   7689:        subl2   $4,r8           # decrement eftar offset
                   7690:        addl2   r8,r9           # point to next eftar entry
                   7691:        movl    4*eftar(r9),r9  # load eftar entry
                   7692:        casel   r9,$0,$4                # switch on type
                   7693: 5:             
                   7694:        .word   befc7-5b        # no conversion needed
                   7695:        .word   befc2-5b        # string
                   7696:        .word   befc3-5b        # integer
                   7697:        .word   befc4-5b        # real
                   7698:        #esw                    # end of switch on type
                   7699: #
                   7700: #      HERE TO CONVERT TO STRING
                   7701: #
                   7702: befc2: movl    (r10),-(sp)     # stack arg ptr
                   7703:        jsb     gtstg           # convert argument to string
                   7704:        .long   er_039          # external function argument is not string
                   7705:        jmp     befc6           # jump to merge
                   7706:        #page   
                   7707: #
                   7708: #      EFBLK (CONTINUED)
                   7709: #
                   7710: #      HERE TO CONVERT AN INTEGER
                   7711: #
                   7712: befc3: movl    (r10),r9        # load next argument
                   7713:        movl    r8,befof        # save offset
                   7714:        jsb     gtint           # convert to integer
                   7715:        .long   er_040          # external function argument is not integer
                   7716:        jmp     befc5           # merge with real case
                   7717: #
                   7718: #      HERE TO CONVERT A REAL
                   7719: #
                   7720: befc4: movl    (r10),r9        # load next argument
                   7721:        movl    r8,befof        # save offset
                   7722:        jsb     gtrea           # convert to real
                   7723:        .long   er_265          # external function argument is not real
                   7724: #
                   7725: #      INTEGER CASE MERGES HERE
                   7726: #
                   7727: befc5: movl    befof,r8        # restore offset
                   7728: #
                   7729: #      STRING MERGES HERE
                   7730: #
                   7731: befc6: movl    r9,(r10)        # store converted result
                   7732: #
                   7733: #      NO CONVERSION MERGES HERE
                   7734: #
                   7735: befc7: tstl    r8              # loop back if more to go
                   7736:        bnequ   befc1
                   7737: #
                   7738: #      HERE AFTER CONVERTING ALL THE ARGUMENTS
                   7739: #
                   7740:        movl    (sp)+,r10       # restore efblk pointer
                   7741:        movl    4*fargs(r10),r6 # get number of args
                   7742:        jsb     sysex           # call routine to call external fnc
                   7743:        .long   exfal           # fail if failure
                   7744:        #page   
                   7745: #
                   7746: #      EFBLK (CONTINUED)
                   7747: #
                   7748: #      RETURN HERE WITH RESULT IN XR
                   7749: #
                   7750: #      FIRST DEFEND AGAINST NON-STANDARD NULL STRING RETURNED
                   7751: #
                   7752:        movl    4*efrsl(r10),r7 # get result type id
                   7753:        bnequ   befa8           # branch if not unconverted
                   7754:        cmpl    (r9),$b$scl     # jump if not a string
                   7755:        bnequ   befc8
                   7756:        tstl    4*sclen(r9)     # return null if null
                   7757:        bnequ   0f
                   7758:        jmp     exnul
                   7759: 0:             
                   7760: #
                   7761: #      HERE IF CONVERTED RESULT TO CHECK FOR NULL STRING
                   7762: #
                   7763: befa8: cmpl    r7,$num01       # 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: #      RETURN IF RESULT IS IN DYNAMIC STORAGE
                   7771: #
                   7772: befc8: cmpl    r9,dnamb        # jump if not in dynamic storage
                   7773:        blssu   befc9
                   7774:        cmpl    r9,dnamp        # return result if already dynamic
                   7775:        bgtru   0f
                   7776:        jmp     exixr
                   7777: 0:             
                   7778: #
                   7779: #      HERE WE COPY A RESULT INTO THE DYNAMIC REGION
                   7780: #
                   7781: befc9: movl    (r9),r6         # get possible type word
                   7782:        tstl    r7              # jump if unconverted result
                   7783:        beqlu   bef11
                   7784:        movl    $b$scl,r6       # string
                   7785:        cmpl    r7,$num01       # yes jump
                   7786:        beqlu   bef10
                   7787:        movl    $b$icl,r6       # integer
                   7788:        cmpl    r7,$num02       # yes jump
                   7789:        beqlu   bef10
                   7790:        movl    $b$rcl,r6       # real
                   7791: #
                   7792: #      STORE TYPE WORD IN RESULT
                   7793: #
                   7794: bef10: movl    r6,(r9)         # stored before copying to dynamic
                   7795: #
                   7796: #      MERGE FOR UNCONVERTED RESULT
                   7797: #
                   7798: bef11: jsb     blkln           # get length of block
                   7799:        movl    r9,r10          # copy address of old block
                   7800:        jsb     alloc           # allocate dynamic block same size
                   7801:        movl    r9,-(sp)        # set pointer to new block as result
                   7802:        jsb     sbmvw           # copy old block to dynamic block
                   7803:        jmp     exits           # exit with result on stack
                   7804:        #page   
                   7805: #
                   7806: #      EVBLK
                   7807: #
                   7808: #      THE ROUTINE FOR AN EVBLK IS NEVER EXECUTED
                   7809: #
                   7810:        .align  2
                   7811:        .word   bl$ev
                   7812: b$evt:                         # entry point (evblk)
                   7813:        #page   
                   7814: #
                   7815: #      FFBLK
                   7816: #
                   7817: #      THE ROUTINE FOR AN FFBLK IS EXECUTED FROM THE O$FNC ENTRY
                   7818: #      TO CALL A FIELD FUNCTION AND EXTRACT A FIELD VALUE/NAME.
                   7819: #
                   7820: #      (XL)                  POINTER TO FFBLK
                   7821: #
                   7822:        .align  2
                   7823:        .word   bl$ff
                   7824: b$ffc:                         # entry point (ffblk)
                   7825:        movl    r10,r9          # copy ffblk pointer
                   7826:        movl    (r3)+,r8        # load next code word
                   7827:        movl    (sp),r10        # load pdblk pointer
                   7828:        cmpl    (r10),$b$pdt    # jump if not pdblk at all
                   7829:        bnequ   bffc2
                   7830:        movl    4*pddfp(r10),r6 # load dfblk pointer from pdblk
                   7831: #
                   7832: #      LOOP TO FIND CORRECT FFBLK FOR THIS PDBLK
                   7833: #
                   7834: bffc1: cmpl    r6,4*ffdfp(r9)  # jump if this is the correct ffblk
                   7835:        beqlu   bffc3
                   7836:        movl    4*ffnxt(r9),r9  # else link to next ffblk on chain
                   7837:        bnequ   bffc1           # loop back if another entry to check
                   7838: #
                   7839: #      HERE FOR BAD ARGUMENT
                   7840: #
                   7841: bffc2: jmp     er_041          # field function argument is wrong datatype
                   7842:        #page   
                   7843: #
                   7844: #      FFBLK (CONTINUED)
                   7845: #
                   7846: #      HERE AFTER LOCATING CORRECT FFBLK
                   7847: #
                   7848: bffc3: movl    4*ffofs(r9),r6  # load field offset
                   7849:        cmpl    r8,$ofne$       # jump if called by name
                   7850:        beqlu   bffc5
                   7851:        addl2   r6,r10          # else point to value field
                   7852:        movl    (r10),r9        # load value
                   7853:        cmpl    (r9),$b$trt     # jump if not trapped
                   7854:        bnequ   bffc4
                   7855:        subl2   r6,r10          # else restore name base,offset
                   7856:        movl    r8,(sp)         # save next code word over pdblk ptr
                   7857:        jsb     acess           # access value
                   7858:        .long   exfal           # fail if access fails
                   7859:        movl    (sp),r8         # restore next code word
                   7860: #
                   7861: #      HERE AFTER GETTING VALUE IN (XR)
                   7862: #
                   7863: bffc4: movl    r9,(sp)         # store value on stack (over pdblk)
                   7864:        movl    r8,r9           # copy next code word
                   7865:        movl    (r9),r10        # load entry address
                   7866:        movl    r10,r11         # jump to routine for next code word
                   7867:        jmp     (r11)
                   7868: #
                   7869: #      HERE IF CALLED BY NAME
                   7870: #
                   7871: bffc5: movl    r6,-(sp)        # store name offset (base is set)
                   7872:        jmp     exits           # exit with name on stack
                   7873:        #page   
                   7874: #
                   7875: #      ICBLK
                   7876: #
                   7877: #      THE ROUTINE FOR ICBLK IS EXECUTED FROM THE GENERATED
                   7878: #      CODE TO LOAD AN INTEGER VALUE ONTO THE STACK.
                   7879: #
                   7880: #      (XR)                  POINTER TO ICBLK
                   7881: #
                   7882:        .align  2
                   7883:        .word   bl$ic
                   7884: b$icl:                         # entry point (icblk)
                   7885:        jmp     exixr           # stack xr and obey next code word
                   7886:        #page   
                   7887: #
                   7888: #      KVBLK
                   7889: #
                   7890: #      THE ROUTINE FOR A KVBLK IS NEVER EXECUTED.
                   7891: #
                   7892:        .align  2
                   7893:        .word   bl$kv
                   7894: b$kvt:                         # entry point (kvblk)
                   7895:        #page   
                   7896: #
                   7897: #      NMBLK
                   7898: #
                   7899: #      THE ROUTINE FOR A NMBLK IS EXECUTED FROM THE GENERATED
                   7900: #      CODE FOR THE CASE OF LOADING A NAME ONTO THE STACK
                   7901: #      WHERE THE NAME IS THAT OF A NATURAL VARIABLE WHICH CAN
                   7902: #      BE PREEVALUATED AT COMPILE TIME.
                   7903: #
                   7904: #      (XR)                  POINTER TO NMBLK
                   7905: #
                   7906:        .align  2
                   7907:        .word   bl$nm
                   7908: b$nml:                         # entry point (nmblk)
                   7909:        jmp     exixr           # stack xr and obey next code word
                   7910:        #page   
                   7911: #
                   7912: #      PDBLK
                   7913: #
                   7914: #      THE ROUTINE FOR A PDBLK IS NEVER EXECUTED
                   7915: #
                   7916:        .align  2
                   7917:        .word   bl$pd
                   7918: b$pdt:                         # entry point (pdblk)
                   7919:        #page   
                   7920: #
                   7921: #      PFBLK
                   7922: #
                   7923: #      THE ROUTINE FOR A PFBLK IS EXECUTED FROM THE ENTRY O$FNC
                   7924: #      TO CALL A PROGRAM DEFINED FUNCTION.
                   7925: #
                   7926: #      (XL)                  POINTER TO PFBLK
                   7927: #
                   7928: #      THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING
                   7929: #      CONTROL TO THE PROGRAM DEFINED FUNCTION.
                   7930: #
                   7931: #                            SAVED VALUE OF FIRST ARGUMENT
                   7932: #                            .
                   7933: #                            SAVED VALUE OF LAST ARGUMENT
                   7934: #                            SAVED VALUE OF FIRST LOCAL
                   7935: #                            .
                   7936: #                            SAVED VALUE OF LAST LOCAL
                   7937: #                            SAVED VALUE OF FUNCTION NAME
                   7938: #                            SAVED CODE BLOCK PTR (R$COD)
                   7939: #                            SAVED CODE POINTER (-R$COD)
                   7940: #                            SAVED VALUE OF FLPRT
                   7941: #                            SAVED VALUE OF FLPTR
                   7942: #                            POINTER TO PFBLK
                   7943: #      FLPTR --------------- ZERO (TO BE OVERWRITTEN WITH OFFS)
                   7944: #
                   7945:        .align  2
                   7946:        .word   bl$pf
                   7947: b$pfc:                         # entry point (pfblk)
                   7948:        movl    r10,bpfpf       # save pfblk ptr (need not be reloc)
                   7949:        movl    r10,r9          # copy for the moment
                   7950:        movl    4*pfvbl(r9),r10 # point to vrblk for function
                   7951: #
                   7952: #      LOOP TO FIND OLD VALUE OF FUNCTION
                   7953: #
                   7954: bpf01: movl    r10,r7          # save pointer
                   7955:        movl    4*vrval(r10),r10# load value
                   7956:        cmpl    (r10),$b$trt    # loop if trblk
                   7957:        beqlu   bpf01
                   7958: #
                   7959: #      SET VALUE TO NULL AND SAVE OLD FUNCTION VALUE
                   7960: #
                   7961:        movl    r10,bpfsv       # save old value
                   7962:        movl    r7,r10          # point back to block with value
                   7963:        movl    $nulls,4*vrval(r10) # set value to null
                   7964:        movl    4*fargs(r9),r6  # load number of arguments
                   7965:        addl2   $4*pfarg,r9     # point to pfarg entries
                   7966:        tstl    r6              # jump if no arguments
                   7967:        beqlu   bpf04
                   7968:        movl    sp,r10          # ptr to last arg
                   7969:        moval   0[r6],r6        # convert no. of args to bytes offset
                   7970:        addl2   r6,r10          # point before first arg
                   7971:        movl    r10,bpfxt       # remember arg pointer
                   7972:        #page   
                   7973: #
                   7974: #      PFBLK (CONTINUED)
                   7975: #
                   7976: #      LOOP TO SAVE OLD ARGUMENT VALUES AND SET NEW ONES
                   7977: #
                   7978: bpf02: movl    (r9)+,r10       # load vrblk ptr for next argument
                   7979: #
                   7980: #      LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE
                   7981: #
                   7982: bpf03: movl    r10,r8          # save pointer
                   7983:        movl    4*vrval(r10),r10# load next value
                   7984:        cmpl    (r10),$b$trt    # loop back if trblk
                   7985:        beqlu   bpf03
                   7986: #
                   7987: #      SAVE OLD VALUE AND GET NEW VALUE
                   7988: #
                   7989:        movl    r10,r6          # keep old value
                   7990:        movl    bpfxt,r10       # point before next stacked arg
                   7991:        movl    -(r10),r7       # load argument (new value)
                   7992:        movl    r6,(r10)        # save old value
                   7993:        movl    r10,bpfxt       # keep arg ptr for next time
                   7994:        movl    r8,r10          # point back to block with value
                   7995:        movl    r7,4*vrval(r10) # set new value
                   7996:        cmpl    sp,bpfxt        # loop if not all done
                   7997:        bnequ   bpf02
                   7998: #
                   7999: #      NOW PROCESS LOCALS
                   8000: #
                   8001: bpf04: movl    bpfpf,r10       # restore pfblk pointer
                   8002:        movl    4*pfnlo(r10),r6 # load number of locals
                   8003:        beqlu   bpf07           # jump if no locals
                   8004:        movl    $nulls,r7       # get null constant
                   8005:                                # set local counter
                   8006: #
                   8007: #      LOOP TO PROCESS LOCALS
                   8008: #
                   8009: bpf05: movl    (r9)+,r10       # load vrblk ptr for next local
                   8010: #
                   8011: #      LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE
                   8012: #
                   8013: bpf06: movl    r10,r8          # save pointer
                   8014:        movl    4*vrval(r10),r10# load next value
                   8015:        cmpl    (r10),$b$trt    # loop back if trblk
                   8016:        beqlu   bpf06
                   8017: #
                   8018: #      SAVE OLD VALUE AND SET NULL AS NEW VALUE
                   8019: #
                   8020:        movl    r10,-(sp)       # stack old value
                   8021:        movl    r8,r10          # point back to block with value
                   8022:        movl    r7,4*vrval(r10) # set null as new value
                   8023:        sobgtr  r6,bpf05        # loop till all locals processed
                   8024:        #page   
                   8025: #
                   8026: #      PFBLK (CONTINUED)
                   8027: #
                   8028: #      HERE AFTER PROCESSING ARGUMENTS AND LOCALS
                   8029: #
                   8030: bpf07: clrl    r9              # zero reg xr in case
                   8031:        tstl    kvpfl           # skip if profiling is off
                   8032:        beqlu   bpf7c
                   8033:        cmpl    kvpfl,$num02    # branch on type of profile
                   8034:        beqlu   bpf7a
                   8035: #
                   8036: #      HERE IF &PROFILE = 1
                   8037: #
                   8038:        jsb     systm           # get current time
                   8039:        movl    r5,pfetm        # save for a sec
                   8040:        subl2   pfstm,r5        # find time used by caller
                   8041:        jsb     icbld           # build into an icblk
                   8042:        movl    pfetm,r5        # reload current time
                   8043:        jmp     bpf7b           # merge
                   8044: #
                   8045: #       HERE IF &PROFILE = 2
                   8046: #
                   8047: bpf7a: movl    pfstm,r5        # get start time of calling stmt
                   8048:        jsb     icbld           # assemble an icblk round it
                   8049:        jsb     systm           # get now time
                   8050: #
                   8051: #      BOTH TYPES OF PROFILE MERGE HERE
                   8052: #
                   8053: bpf7b: movl    r5,pfstm        # set start time of 1st func stmt
                   8054:        movl    sp,pffnc        # flag function entry
                   8055: #
                   8056: #      NO PROFILING MERGES HERE
                   8057: #
                   8058: bpf7c: movl    r9,-(sp)        # stack icblk ptr (or zero)
                   8059:        movl    r$cod,r6        # load old code block pointer
                   8060:        movl    r3,r7           # get code pointer
                   8061:        subl2   r6,r7           # make code pointer into offset
                   8062:        movl    bpfpf,r10       # recall pfblk pointer
                   8063:        movl    bpfsv,-(sp)     # stack old value of function name
                   8064:        movl    r6,-(sp)        # stack code block pointer
                   8065:        movl    r7,-(sp)        # stack code offset
                   8066:        movl    flprt,-(sp)     # stack old flprt
                   8067:        movl    flptr,-(sp)     # stack old failure pointer
                   8068:        movl    r10,-(sp)       # stack pointer to pfblk
                   8069:        clrl    -(sp)           # dummy zero entry for fail return
                   8070:        jsb     sbchk           # check for stack overflow
                   8071:        movl    sp,flptr        # set new fail return value
                   8072:        movl    sp,flprt        # set new flprt
                   8073:        movl    kvtra,r6        # load trace value
                   8074:        addl2   kvftr,r6        # add ftrace value
                   8075:        bnequ   bpf09           # jump if tracing possible
                   8076:        incl    kvfnc           # else bump fnclevel
                   8077: #
                   8078: #      HERE TO ACTUALLY JUMP TO FUNCTION
                   8079: #
                   8080: bpf08: movl    4*pfcod(r10),r9 # point to code
                   8081:        movl    (r9),r11        # off to execute function
                   8082:        jmp     (r11)
                   8083: #
                   8084: #      HERE IF TRACING IS POSSIBLE
                   8085: #
                   8086: bpf09: movl    4*pfctr(r10),r9 # load possible call trace trblk
                   8087:        movl    4*pfvbl(r10),r10# load vrblk pointer for function
                   8088:        movl    $4*vrval,r6     # set name offset for variable
                   8089:        tstl    kvtra           # jump if trace mode is off
                   8090:        beqlu   bpf10
                   8091:        tstl    r9              # or if there is no call trace
                   8092:        beqlu   bpf10
                   8093: #
                   8094: #      HERE IF CALL TRACED
                   8095: #
                   8096:        decl    kvtra           # decrement trace count
                   8097:        tstl    4*trfnc(r9)     # jump if print trace
                   8098:        beqlu   bpf11
                   8099:        jsb     trxeq           # execute function type trace
                   8100:        #page   
                   8101: #
                   8102: #      PFBLK (CONTINUED)
                   8103: #
                   8104: #      HERE TO TEST FOR FTRACE TRACE
                   8105: #
                   8106: bpf10: tstl    kvftr           # jump if ftrace is off
                   8107:        beqlu   bpf16
                   8108:        decl    kvftr           # else decrement ftrace
                   8109: #
                   8110: #      HERE FOR PRINT TRACE
                   8111: #
                   8112: bpf11: jsb     prtsn           # print statement number
                   8113:        jsb     prtnm           # print function name
                   8114:        movl    $ch$pp,r6       # load left paren
                   8115:        jsb     prtch           # print left paren
                   8116:        movl    4*1(sp),r10     # recover pfblk pointer
                   8117:        tstl    4*fargs(r10)    # skip if no arguments
                   8118:        beqlu   bpf15
                   8119:        clrl    r7              # else set argument counter
                   8120:        jmp     bpf13           # jump into loop
                   8121: #
                   8122: #      LOOP TO PRINT ARGUMENT VALUES
                   8123: #
                   8124: bpf12: movl    $ch$cm,r6       # load comma
                   8125:        jsb     prtch           # print to separate from last arg
                   8126: #
                   8127: #      MERGE HERE FIRST TIME (NO COMMA REQUIRED)
                   8128: #
                   8129: bpf13: movl    r7,(sp)         # save arg ctr (over failoffs is ok)
                   8130:        moval   0[r7],r7        # convert to byte offset
                   8131:        addl2   r7,r10          # point to next argument pointer
                   8132:        movl    4*pfarg(r10),r9 # load next argument vrblk ptr
                   8133:        subl2   r7,r10          # restore pfblk pointer
                   8134:        movl    4*vrval(r9),r9  # load next value
                   8135:        jsb     prtvl           # print argument value
                   8136:        #page   
                   8137: #
                   8138: #      HERE AFTER DEALING WITH ONE ARGUMENT
                   8139: #
                   8140:        movl    (sp),r7         # restore argument counter
                   8141:        incl    r7              # increment argument counter
                   8142:        cmpl    r7,4*fargs(r10) # loop if more to print
                   8143:        blssu   bpf12
                   8144: #
                   8145: #      MERGE HERE IN NO ARGS CASE TO PRINT PAREN
                   8146: #
                   8147: bpf15: movl    $ch$rp,r6       # load right paren
                   8148:        jsb     prtch           # print to terminate output
                   8149:        jsb     prtnl           # terminate print line
                   8150: #
                   8151: #      MERGE HERE TO EXIT WITH TEST FOR FNCLEVEL TRACE
                   8152: #
                   8153: bpf16: incl    kvfnc           # increment fnclevel
                   8154:        movl    r$fnc,r10       # load ptr to possible trblk
                   8155:        jsb     ktrex           # call keyword trace routine
                   8156: #
                   8157: #      CALL FUNCTION AFTER TRACE TESTS COMPLETE
                   8158: #
                   8159:        movl    4*1(sp),r10     # restore pfblk pointer
                   8160:        jmp     bpf08           # jump back to execute function
                   8161:        #page   
                   8162: #
                   8163: #      RCBLK
                   8164: #
                   8165: #      THE ROUTINE FOR AN RCBLK IS EXECUTED FROM THE GENERATED
                   8166: #      CODE TO LOAD A REAL VALUE ONTO THE STACK.
                   8167: #
                   8168: #      (XR)                  POINTER TO RCBLK
                   8169: #
                   8170:        .align  2
                   8171:        .word   bl$rc
                   8172: b$rcl:                         # entry point (rcblk)
                   8173:        jmp     exixr           # stack xr and obey next code word
                   8174:        #page   
                   8175: #
                   8176: #      SCBLK
                   8177: #
                   8178: #      THE ROUTINE FOR AN SCBLK IS EXECUTED FROM THE GENERATED
                   8179: #      CODE TO LOAD A STRING VALUE ONTO THE STACK.
                   8180: #
                   8181: #      (XR)                  POINTER TO SCBLK
                   8182: #
                   8183:        .align  2
                   8184:        .word   bl$sc
                   8185: b$scl:                         # entry point (scblk)
                   8186:        jmp     exixr           # stack xr and obey next code word
                   8187:        #page   
                   8188: #
                   8189: #      TBBLK
                   8190: #
                   8191: #      THE ROUTINE FOR A TBBLK IS NEVER EXECUTED
                   8192: #
                   8193:        .align  2
                   8194:        .word   bl$tb
                   8195: b$tbt:                         # entry point (tbblk)
                   8196:        #page   
                   8197: #
                   8198: #      TEBLK
                   8199: #
                   8200: #      THE ROUTINE FOR A TEBLK IS NEVER EXECUTED
                   8201: #
                   8202:        .align  2
                   8203:        .word   bl$te
                   8204: b$tet:                         # entry point (teblk)
                   8205:        #page   
                   8206: #
                   8207: #      VCBLK
                   8208: #
                   8209: #      THE ROUTINE FOR A VCBLK IS NEVER EXECUTED
                   8210: #
                   8211:        .align  2
                   8212:        .word   bl$vc
                   8213: b$vct:                         # entry point (vcblk)
                   8214:        #page   
                   8215: #
                   8216: #      VRBLK
                   8217: #
                   8218: #      THE VRBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE.
                   8219: #      THERE ARE SIX ENTRIES FOR VRBLK COVERING VARIOUS CASES
                   8220: #
                   8221:        .align  2
                   8222:        .word   bl$$i
                   8223: b$vr$:                         # mark start of vrblk entry points
                   8224: #
                   8225: #      ENTRY FOR VRGET (TRAPPED CASE). THIS ROUTINE IS CALLED
                   8226: #      FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE.
                   8227: #      THIS ENTRY POINT IS USED IF AN ACCESS TRACE OR INPUT
                   8228: #      ASSOCIATION IS CURRENTLY ACTIVE.
                   8229: #
                   8230: #      (XR)                  POINTER TO VRGET FIELD OF VRBLK
                   8231: #
                   8232:        .align  2
                   8233:        .word   bl$$i
                   8234: b$vra:                         # entry point
                   8235:        movl    r9,r10          # copy name base (vrget = 0)
                   8236:        movl    $4*vrval,r6     # set name offset
                   8237:        jsb     acess           # access value
                   8238:        .long   exfal           # fail if access fails
                   8239:        jmp     exixr           # else exit with result in xr
                   8240:        #page   
                   8241: #
                   8242: #      VRBLK (CONTINUED)
                   8243: #
                   8244: #      ENTRY FOR VRSTO (ERROR CASE. THIS ROUTINE IS CALLED FROM
                   8245: #      THE EXECUTED CODE FOR AN ATTEMPT TO MODIFY THE VALUE
                   8246: #      OF A PROTECTED (PATTERN VALUED) NATURAL VARIABLE.
                   8247: #
                   8248: b$vre:                         # entry point
                   8249:        jmp     er_042          # attempt to change value of protected variable
                   8250:        #page   
                   8251: #
                   8252: #      VRBLK (CONTINUED)
                   8253: #
                   8254: #      ENTRY FOR VRTRA (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8255: #      FROM THE EXECUTED CODE TO TRANSFER TO A LABEL.
                   8256: #
                   8257: #      (XR)                  POINTER TO VRTRA FIELD OF VRBLK
                   8258: #
                   8259: b$vrg:                         # entry point
                   8260:        movl    4*vrlbo(r9),r9  # load code pointer
                   8261:        movl    (r9),r10        # load entry address
                   8262:        movl    r10,r11         # jump to routine for next code word
                   8263:        jmp     (r11)
                   8264:        #page   
                   8265: #
                   8266: #      VRBLK (CONTINUED)
                   8267: #
                   8268: #      ENTRY FOR VRGET (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8269: #      FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE.
                   8270: #
                   8271: #      (XR)                  POINTS TO VRGET FIELD OF VRBLK
                   8272: #
                   8273: b$vrl:                         # entry point
                   8274:        movl    4*vrval(r9),-(sp)# load value onto stack (vrget = 0)
                   8275:        jmp     exits           # obey next code word
                   8276:        #page   
                   8277: #
                   8278: #      VRBLK (CONTINUED)
                   8279: #
                   8280: #      ENTRY FOR VRSTO (UNTRAPPED CASE). THIS ROUTINE IS CALLED
                   8281: #      FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE.
                   8282: #
                   8283: #      (XR)                  POINTER TO VRSTO FIELD OF VRBLK
                   8284: #
                   8285: b$vrs:                         # entry point
                   8286:        movl    (sp),4*vrvlo(r9)# store value, leave on stack
                   8287:        jmp     exits           # obey next code word
                   8288:        #page   
                   8289: #
                   8290: #      VRBLK (CONTINUED)
                   8291: #
                   8292: #      VRTRA (TRAPPED CASE). THIS ROUTINE IS CALLED FROM THE
                   8293: #      GENERATED CODE TO TRANSFER TO A LABEL WHEN A LABEL
                   8294: #      TRACE IS CURRENTLY ACTIVE.
                   8295: #
                   8296: b$vrt:                         # entry point
                   8297:        subl2   $4*vrtra,r9     # point back to start of vrblk
                   8298:        movl    r9,r10          # copy vrblk pointer
                   8299:        movl    $4*vrval,r6     # set name offset
                   8300:        movl    4*vrlbl(r10),r9 # load pointer to trblk
                   8301:        tstl    kvtra           # jump if trace is off
                   8302:        beqlu   bvrt2
                   8303:        decl    kvtra           # else decrement trace count
                   8304:        tstl    4*trfnc(r9)     # jump if print trace case
                   8305:        beqlu   bvrt1
                   8306:        jsb     trxeq           # else execute full trace
                   8307:        jmp     bvrt2           # merge to jump to label
                   8308: #
                   8309: #      HERE FOR PRINT TRACE -- PRINT COLON ( LABEL NAME )
                   8310: #
                   8311: bvrt1: jsb     prtsn           # print statement number
                   8312:        movl    r10,r9          # copy vrblk pointer
                   8313:        movl    $ch$cl,r6       # colon
                   8314:        jsb     prtch           # print it
                   8315:        movl    $ch$pp,r6       # left paren
                   8316:        jsb     prtch           # print it
                   8317:        jsb     prtvn           # print label name
                   8318:        movl    $ch$rp,r6       # right paren
                   8319:        jsb     prtch           # print it
                   8320:        jsb     prtnl           # terminate line
                   8321:        movl    4*vrlbl(r10),r9 # point back to trblk
                   8322: #
                   8323: #      MERGE HERE TO JUMP TO LABEL
                   8324: #
                   8325: bvrt2: movl    4*trlbl(r9),r9  # load pointer to actual code
                   8326:        movl    (r9),r11        # execute statement at label
                   8327:        jmp     (r11)
                   8328:        #page   
                   8329: #
                   8330: #      VRBLK (CONTINUED)
                   8331: #
                   8332: #      ENTRY FOR VRSTO (TRAPPED CASE). THIS ROUTINE IS CALLED
                   8333: #      FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE.
                   8334: #      THIS ENTRY IS USED WHEN A VALUE TRACE OR OUTPUT
                   8335: #      ASSOCIATION IS CURRENTLY ACTIVE.
                   8336: #
                   8337: #      (XR)                  POINTER TO VRSTO FIELD OF VRBLK
                   8338: #
                   8339: b$vrv:                         # entry point
                   8340:        movl    (sp),r7         # load value (leave copy on stack)
                   8341:        subl2   $4*vrsto,r9     # point to vrblk
                   8342:        movl    r9,r10          # copy vrblk pointer
                   8343:        movl    $4*vrval,r6     # set offset
                   8344:        jsb     asign           # call assignment routine
                   8345:        .long   exfal           # fail if assignment fails
                   8346:        jmp     exits           # else return with result on stack
                   8347:        #page   
                   8348: #
                   8349: #      XNBLK
                   8350: #
                   8351: #      THE ROUTINE FOR AN XNBLK IS NEVER EXECUTED
                   8352: #
                   8353:        .align  2
                   8354:        .word   bl$xn
                   8355: b$xnt:                         # entry point (xnblk)
                   8356:        #page   
                   8357: #
                   8358: #      XRBLK
                   8359: #
                   8360: #      THE ROUTINE FOR AN XRBLK IS NEVER EXECUTED
                   8361: #
                   8362:        .align  2
                   8363:        .word   bl$xr
                   8364: b$xrt:                         # entry point (xrblk)
                   8365: #
                   8366: #      MARK ENTRY ADDRESS PAST LAST BLOCK ACTION ROUTINE
                   8367: #
                   8368:        .align  2
                   8369:        .word   bl$$i
                   8370: b$yyy:                         # last block routine entry point
                   8371:        #title  s p i t b o l -- pattern matching routines
                   8372: #
                   8373: #      THE FOLLOWING SECTION CONSISTS OF THE PATTERN MATCHING
                   8374: #      ROUTINES. ALL PATTERN NODES CONTAIN A POINTER (PCODE)
                   8375: #      TO ONE OF THE ROUTINES IN THIS SECTION (P$XXX).
                   8376: #
                   8377: #      NOTE THAT THIS SECTION FOLLOWS THE B$XXX ROUTINES TO
                   8378: #      ENABLE A FAST TEST FOR THE PATTERN DATATYPE.
                   8379: #
                   8380:        .align  2
                   8381:        .word   bl$$i
                   8382: p$aaa:                         # entry to mark first pattern
                   8383: #
                   8384: #
                   8385: #      THE ENTRY CONDITIONS TO THE MATCH ROUTINE ARE AS FOLLOWS
                   8386: #      (SEE O$PMN, O$PMV, O$PMS AND PROCEDURE MATCH).
                   8387: #
                   8388: #      STACK CONTENTS.
                   8389: #
                   8390: #                            NAME BASE (O$PMN ONLY)
                   8391: #                            NAME OFFSET (O$PMN ONLY)
                   8392: #                            TYPE (0-O$PMN, 1-O$PMV, 2-O$PMS)
                   8393: #      PMHBS --------------- INITIAL CURSOR (ZERO)
                   8394: #                            INITIAL NODE POINTER
                   8395: #      XS ------------------ =NDABO (ANCHORED), =NDUNA (UNANCH)
                   8396: #
                   8397: #      REGISTER VALUES.
                   8398: #
                   8399: #           (XS)             SET AS SHOWN IN STACK DIAGRAM
                   8400: #           (XR)             POINTER TO INITIAL PATTERN NODE
                   8401: #           (WB)             INITIAL CURSOR (ZERO)
                   8402: #
                   8403: #      GLOBAL PATTERN VALUES
                   8404: #
                   8405: #           R$PMS            POINTER TO SUBJECT STRING SCBLK
                   8406: #           PMSSL            LENGTH OF SUBJECT STRING IN CHARS
                   8407: #           PMDFL            DOT FLAG, INITIALLY ZERO
                   8408: #           PMHBS            SET AS SHOWN IN STACK DIAGRAM
                   8409: #
                   8410: #      CONTROL IS PASSED BY BRANCHING THROUGH THE PCODE
                   8411: #      FIELD OF THE INITIAL PATTERN NODE (BRI (XR)).
                   8412:        #page   
                   8413: #
                   8414: #      DESCRIPTION OF ALGORITHM
                   8415: #
                   8416: #      A PATTERN STRUCTURE IS REPRESENTED AS A LINKED GRAPH
                   8417: #      OF NODES WITH THE FOLLOWING STRUCTURE.
                   8418: #
                   8419: #           +------------------------------------+
                   8420: #           I                PCODE               I
                   8421: #           +------------------------------------+
                   8422: #           I                PTHEN               I
                   8423: #           +------------------------------------+
                   8424: #           I                PARM1               I
                   8425: #           +------------------------------------+
                   8426: #           I                PARM2               I
                   8427: #           +------------------------------------+
                   8428: #
                   8429: #      PCODE IS A POINTER TO THE ROUTINE WHICH WILL PERFORM
                   8430: #      THE MATCH OF THIS PARTICULAR NODE TYPE.
                   8431: #
                   8432: #      PTHEN IS A POINTER TO THE SUCCESSOR NODE. I.E. THE NODE
                   8433: #      TO BE MATCHED IF THE ATTEMPT TO MATCH THIS NODE SUCCEEDS.
                   8434: #      IF THIS IS THE LAST NODE OF THE PATTERN PTHEN POINTS
                   8435: #      TO THE DUMMY NODE NDNTH WHICH INITIATES PATTERN EXIT.
                   8436: #
                   8437: #      PARM1, PARM2 ARE PARAMETERS WHOSE USE VARIES WITH THE
                   8438: #      PARTICULAR NODE. THEY ARE ONLY PRESENT IF REQUIRED.
                   8439: #
                   8440: #      ALTERNATIVES ARE HANDLED WITH THE SPECIAL ALTERNATIVE
                   8441: #      NODE WHOSE PARAMETER POINTS TO THE NODE TO BE MATCHED
                   8442: #      IF THERE IS A FAILURE ON THE SUCCESSOR PATH.
                   8443: #
                   8444: #      THE FOLLOWING EXAMPLE ILLUSTRATES THE MANNER IN WHICH
                   8445: #      THE STRUCTURE IS BUILT UP. THE PATTERN IS
                   8446: #
                   8447: #      (A / B / C) (D / E)   WHERE / IS ALTERNATION
                   8448: #
                   8449: #      IN THE DIAGRAM, THE NODE MARKED + REPRESENTS AN
                   8450: #      ALTERNATIVE NODE AND THE DOTTED LINE FROM A + NODE
                   8451: #      REPRESENTS THE PARAMETER POINTER TO THE ALTERNATIVE.
                   8452: #
                   8453: #      +---+     +---+     +---+     +---+
                   8454: #      I + I-----I A I-----I + I-----I D I-----
                   8455: #      +---+     +---+  I  +---+     +---+
                   8456: #        .              I    .
                   8457: #        .              I    .
                   8458: #      +---+     +---+  I  +---+
                   8459: #      I + I-----I B I--I  I E I-----
                   8460: #      +---+     +---+  I  +---+
                   8461: #        .              I
                   8462: #        .              I
                   8463: #      +---+            I
                   8464: #      I C I------------I
                   8465: #      +---+
                   8466:        #page   
                   8467: #
                   8468: #      DURING THE MATCH, THE REGISTERS ARE USED AS FOLLOWS.
                   8469: #
                   8470: #      (XR)                  POINTS TO THE CURRENT NODE
                   8471: #      (XL)                  SCRATCH
                   8472: #      (XS)                  MAIN STACK POINTER
                   8473: #      (WB)                  CURSOR (NUMBER OF CHARS MATCHED)
                   8474: #      (WA,WC)               SCRATCH
                   8475: #
                   8476: #      TO KEEP TRACK OF ALTERNATIVES, THE MAIN STACK IS USED AS
                   8477: #      A HISTORY STACK AND CONTAINS TWO WORD ENTRIES.
                   8478: #
                   8479: #      WORD 1                SAVED CURSOR VALUE
                   8480: #      WORD 2                NODE TO MATCH ON FAILURE
                   8481: #
                   8482: #      WHEN A FAILURE OCCURS, THE MOST RECENT ENTRY ON THIS
                   8483: #      STACK IS POPPED OFF TO RESTORE THE CURSOR AND POINT
                   8484: #      TO THE NODE TO BE MATCHED AS AN ALTERNATIVE. THE ENTRY
                   8485: #      AT THE BOTTOM OF THE STACK POINTS TO THE FOLLOWING
                   8486: #      SPECIAL NODES DEPENDING ON THE SCAN MODE.
                   8487: #
                   8488: #      ANCHORED MODE         THE BOTTOM ENTRY POINTS TO THE
                   8489: #                            SPECIAL NODE NDABO WHICH CAUSES AN
                   8490: #                            ABORT. THE CURSOR VALUE STORED
                   8491: #                            WITH THIS ENTRY IS ALWAYS ZERO.
                   8492: #
                   8493: #      UNANCHORED MODE       THE BOTTOM ENTRY POINTS TO THE
                   8494: #                            SPECIAL NODE NDUNA WHICH MOVES THE
                   8495: #                            ANCHOR POINT AND RESTARTS THE MATCH
                   8496: #                            THE CURSOR SAVED WITH THIS ENTRY
                   8497: #                            IS THE NUMBER OF CHARACTERS WHICH
                   8498: #                            LIE BEFORE THE INITIAL ANCHOR POINT
                   8499: #                            (I.E. THE NUMBER OF ANCHOR MOVES).
                   8500: #                            THIS ENTRY IS THREE WORDS LONG AND
                   8501: #                            ALSO CONTAINS THE INITIAL PATTERN.
                   8502: #
                   8503: #      ENTRIES ARE MADE ON THIS HISTORY STACK BY ALTERNATIVE
                   8504: #      NODES AND BY SOME SPECIAL COMPOUD PATTERNS AS DESCRIBED
                   8505: #      LATER ON. THE FOLLOWING GLOBAL LOCATIONS ARE USED DURING
                   8506: #      PATTERN MATCHING.
                   8507: #
                   8508: #      R$PMS                 POINTER TO SUBJECT STRING
                   8509: #      PMSSL                 LENGTH OF SUBJECT STRING
                   8510: #      PMDFL                 FLAG SET NON-ZERO FOR DOT PATTERNS
                   8511: #      PMHBS                 BASE PTR FOR CURRENT HISTORY STACK
                   8512: #
                   8513: #      THE FOLLOWING EXIT POINTS ARE AVAILABLE TO MATCH ROUTINES
                   8514: #
                   8515: #      SUCCP                 SUCCESS IN MATCHING CURRENT NODE
                   8516: #      FAILP                 FAILURE IN MATCHING CURRENT NODE
                   8517:        #page   
                   8518: #
                   8519: #      COMPOUND PATTERNS
                   8520: #
                   8521: #      SOME PATTERNS HAVE IMPLICIT ALTERNATIVES AND THEIR
                   8522: #      REPRESENTATION IN THE PATTERN STRUCTURE CONSISTS OF A
                   8523: #      LINKED SET OF NODES AS INDICATED BY THESE DIAGRAMS.
                   8524: #
                   8525: #      AS BEFORE, THE + REPRESENTS AN ALTERNATIVE NODE AND
                   8526: #      THE DOTTED LINE FROM A + NODE IS THE PARAMETER POINTER
                   8527: #      TO THE ALTERNATIVE PATTERN.
                   8528: #
                   8529: #      ARB
                   8530: #      ---
                   8531: #
                   8532: #           +---+            THIS NODE (P$ARB) MATCHES NULL
                   8533: #           I B I-----       AND STACKS CURSOR, SUCCESSOR PTR,
                   8534: #           +---+            CURSOR (COPY) AND A PTR TO NDARC.
                   8535: #
                   8536: #
                   8537: #
                   8538: #
                   8539: #      BAL
                   8540: #      ---
                   8541: #
                   8542: #           +---+            THE P$BAL NODE SCANS A BALANCED
                   8543: #           I B I-----       STRING AND THEN STACKS A POINTER
                   8544: #           +---+            TO ITSELF ON THE HISTORY STACK.
                   8545:        #page   
                   8546: #
                   8547: #      COMPOUND PATTERN STRUCTURES (CONTINUED)
                   8548: #
                   8549: #
                   8550: #      ARBNO
                   8551: #      -----
                   8552: #
                   8553: #           +---+            THIS ALTERNATIVE NODE MATCHES NULL
                   8554: #      +----I + I-----       THE FIRST TIME AND STACKS A POINTER
                   8555: #      I    +---+            TO THE ARGUMENT PATTERN X.
                   8556: #      I      .
                   8557: #      I      .
                   8558: #      I    +---+            NODE (P$ABA) TO STACK CURSOR
                   8559: #      I    I A I            AND HISTORY STACK BASE PTR.
                   8560: #      I    +---+
                   8561: #      I      I
                   8562: #      I      I
                   8563: #      I    +---+            THIS IS THE ARGUMENT PATTERN. AS
                   8564: #      I    I X I            INDICATED, THE SUCCESSOR OF THE
                   8565: #      I    +---+            PATTERN IS THE P$ABC NODE
                   8566: #      I      I
                   8567: #      I      I
                   8568: #      I    +---+            THIS NODE (P$ABC) POPS PMHBS,
                   8569: #      +----I C I            STACKS OLD PMHBS AND PTR TO NDABD
                   8570: #           +---+            (UNLESS OPTIMISATION HAS OCCURRED)
                   8571: #
                   8572: #      STRUCTURE AND EXECUTION OF THIS PATTERN RESEMBLE THOSE OF
                   8573: #      RECURSIVE PATTERN MATCHING AND IMMEDIATE ASSIGNMENT.
                   8574: #      THE ALTERNATIVE NODE AT THE HEAD OF THE STRUCTURE MATCHES
                   8575: #      NULL INITIALLY BUT ON SUBSEQUENT FAILURE ENSURES ATTEMPT
                   8576: #      TO MATCH THE ARGUMENT.  BEFORE THE ARGUMENT IS MATCHED
                   8577: #      P$ABA STACKS THE CURSOR,PMHBS AND A PTR TO P$ABB.  IF
                   8578: #      THE ARGUMENT CANT BE MATCHED , P$ABB REMOVES THIS SPECIAL
                   8579: #      STACK ENTRY AND FAILS.
                   8580: #      IF ARGUMENT IS MATCHED , P$ABC RESTORES THE OUTER PMHBS
                   8581: #      VALUE (SAVED BY P$ABA) .  THEN IF THE ARGUMENT HAS LEFT
                   8582: #      ALTERNATIVES ON STACK IT STACKS THE INNER VALUE OF PMHBS
                   8583: #      AND A PTR TO NDABD. IF ARGUMENT LEFT NOTHING ON THE STACK
                   8584: #      IT OPTIMISES BY REMOVING ITEMS STACKED BY P$ABA.  FINALLY
                   8585: #      A CHECK IS MADE THAT ARGUMENT MATCHED MORE THAN THE NULL
                   8586: #      STRING (CHECK IS INTENDED TO PREVENT USELESS LOOPING).
                   8587: #      IF SO THE SUCCESSOR IS AGAIN THE ALTERNATIVE NODE AT THE
                   8588: #      HEAD OF THE STRUCTURE , ENSURING A POSSIBLE EXTRA ATTEMPT
                   8589: #      TO MATCH THE ARG IF NECESSARY.  IF NOT , THE SUCCESSOR TO
                   8590: #      ALTERNATIVE IS TAKEN SO AS TO TERMINATE THE LOOP.  P$ABD
                   8591: #      RESTORES INNER PMHBS PTR AND FAILS , THUS TRYING TO MATCH
                   8592: #      ALTERNATIVES LEFT BY THE ARBNO ARGUMENT.
                   8593:        #page   
                   8594: #
                   8595: #      COMPOUND PATTERN STRUCTURES (CONTINUED)
                   8596: #
                   8597: #      BREAKX
                   8598: #      ------
                   8599: #
                   8600: #           +---+            THIS NODE IS A BREAK NODE FOR
                   8601: #      +----I B I            THE ARGUMENT TO BREAKX, IDENTICAL
                   8602: #      I    +---+            TO AN ORDINARY BREAK NODE.
                   8603: #      I      I
                   8604: #      I      I
                   8605: #      I    +---+            THIS ALTERNATIVE NODE STACKS A
                   8606: #      I    I + I-----       POINTER TO THE BREAKX NODE TO
                   8607: #      I    +---+            ALLOW FOR SUBSEQUENT FAILURE
                   8608: #      I      .
                   8609: #      I      .
                   8610: #      I    +---+            THIS IS THE BREAKX NODE ITSELF. IT
                   8611: #      +----I X I            MATCHES ONE CHARACTER AND THEN
                   8612: #           +---+            PROCEEDS BACK TO THE BREAK NODE.
                   8613: #
                   8614: #
                   8615: #
                   8616: #
                   8617: #      FENCE
                   8618: #      -----
                   8619: #
                   8620: #           +---+            THE FENCE NODE MATCHES NULL AND
                   8621: #           I F I-----       STACKS A POINTER TO NODE NDABO TO
                   8622: #           +---+            ABORT ON A SUBSEQUENT REMATCH
                   8623: #
                   8624: #
                   8625: #
                   8626: #
                   8627: #      SUCCEED
                   8628: #      -------
                   8629: #
                   8630: #           +---+            THE NODE FOR SUCCEED MATCHES NULL
                   8631: #           I S I-----       AND STACKS A POINTER TO ITSELF
                   8632: #           +---+            TO REPEAT THE MATCH ON A FAILURE.
                   8633:        #page   
                   8634: #
                   8635: #      COMPOUND PATTERNS (CONTINUED)
                   8636: #
                   8637: #      BINARY DOT (PATTERN ASSIGNMENT)
                   8638: #      -------------------------------
                   8639: #
                   8640: #           +---+            THIS NODE (P$PAA) SAVES THE CURRENT
                   8641: #           I A I            CURSOR AND A POINTER TO THE
                   8642: #           +---+            SPECIAL NODE NDPAB ON THE STACK.
                   8643: #             I
                   8644: #             I
                   8645: #           +---+            THIS IS THE STRUCTURE FOR THE
                   8646: #           I X I            PATTERN LEFT ARGUMENT OF THE
                   8647: #           +---+            PATTERN ASSIGNMENT CALL.
                   8648: #             I
                   8649: #             I
                   8650: #           +---+            THIS NODE (P$PAC) SAVES THE CURSOR,
                   8651: #           I C I-----       A PTR TO ITSELF, THE CURSOR (COPY)
                   8652: #           +---+            AND A PTR TO NDPAD ON THE STACK.
                   8653: #
                   8654: #
                   8655: #      THE FUNCTION OF THE MATCH ROUTINE FOR NDPAB (P$PAB)
                   8656: #      IS SIMPLY TO UNSTACK ITSELF AND FAIL BACK ONTO THE STACK.
                   8657: #
                   8658: #      THE MATCH ROUTINE FOR P$PAC ALSO SETS THE GLOBAL PATTERN
                   8659: #      FLAG PMDFL NON-ZERO TO INDICATE THAT PATTERN ASSIGNMENTS
                   8660: #      MAY HAVE OCCURED IN THE PATTERN MATCH
                   8661: #
                   8662: #      IF PMDFL IS SET AT THE END OF THE MATCH (SEE P$NTH), THE
                   8663: #      HISTORY STACK IS SCANNED FOR MATCHING NDPAB-NDPAD PAIRS
                   8664: #      AND THE CORRESPONDING PATTERN ASSIGNMENTS ARE EXECUTED.
                   8665: #
                   8666: #      THE FUNCTION OF THE MATCH ROUTINE FOR NDPAD (P$PAD)
                   8667: #      IS SIMPLY TO REMOVE ITS ENTRY FROM THE STACK AND FAIL.
                   8668: #      THIS INCLUDES REMOVING THE SPECIAL NODE POINTER STORED
                   8669: #      IN ADDITION TO THE STANDARD TWO ENTRIES ON THE STACK.
                   8670:        #page   
                   8671: #
                   8672: #      COMPOUNT PATTERN STRUCTURES (CONTINUED)
                   8673: #
                   8674: #      FENCE (FUNCTION)
                   8675: #      ----------------
                   8676: #
                   8677: #           +---+            THIS NODE (P$FNA) SAVES THE
                   8678: #           I A I            CURRENT HISTORY STACK AND A
                   8679: #           +---+            POINTER TO NDFNB ON THE STACK.
                   8680: #             I
                   8681: #             I
                   8682: #           +---+            THIS IS THE PATTERN STRUCTURE
                   8683: #           I X I            GIVEN AS THE ARGUMENT TO THE
                   8684: #           +---+            FENCE FUNCTION.
                   8685: #             I
                   8686: #             I
                   8687: #           +---+            THIS NODE P$FNC RESTORES THE OUTER
                   8688: #           I C I            HISTORY STACK PTR SAVED IN P$FNA,
                   8689: #           +---+            AND STACKS THE INNER STACK BASE
                   8690: #                            PTR AND A POINTER TO NDFND ON THE
                   8691: #                            STACK.
                   8692: #
                   8693: #      NDFNB (F$FNB) SIMPLY IS THE FAILURE EXIT FOR PATTERN
                   8694: #      ARGUMENT FAILURE, AND IT POPS ITSELF AND FAILS ONTO THE
                   8695: #      STACK.
                   8696: #
                   8697: #      THE MATCH ROUTINE P$FNC ALLOWS FOR AN OPTIMIZATION WHEN
                   8698: #      THE FENCE PATTERN LEAVES NO ALTERNATIVES.  IN THIS CASE,
                   8699: #      THE NDFNB ENTRY IS POPPED, AND THE MATCH CONTINUES.
                   8700: #
                   8701: #      NDFND (P$FND) IS ENTERED WHEN THE PATTERN FAILS AFTER
                   8702: #      GOING THROUGH A NON-OPTIMIZED P$FNC, AND IT POPS THE
                   8703: #      STACK BACK PAST THE INNTER STACK BASE CREATED BY P$FNA
                   8704:        #page   
                   8705: #
                   8706: #      COMPOUND PATTERNS (CONTINUED)
                   8707: #
                   8708: #      EXPRESSION PATTERNS (RECURSIVE PATTERN MATCHES)
                   8709: #      -----------------------------------------------
                   8710: #
                   8711: #      INITIAL ENTRY FOR A PATTERN NODE IS TO THE ROUTINE P$EXA.
                   8712: #      IF THE EVALUATED RESULT OF THE EXPRESSION IS ITSELF A
                   8713: #      PATTERN, THEN THE FOLLOWING STEPS ARE TAKEN TO ARRANGE
                   8714: #      FOR PROPER RECURSIVE PROCESSING.
                   8715: #
                   8716: #      1)   A POINTER TO THE CURRENT NODE (THE P$EXA NODE) IS
                   8717: #           STORED ON THE HISTORY STACK WITH A DUMMY CURSOR.
                   8718: #
                   8719: #      2)   A SPECIAL HISTORY STACK ENTRY IS MADE IN WHICH THE
                   8720: #           NODE POINTER POINTS TO NDEXB, AND THE CURSOR VALUE
                   8721: #           IS THE SAVED VALUE OF PMHBS ON ENTRY TO THIS NODE.
                   8722: #           THE MATCH ROUTINE FOR NDEXB (P$EXB) RESTORES PMHBS
                   8723: #           FROM THIS CURSOR ENTRY, POPS OFF THE P$EXA NODE
                   8724: #           POINTER AND FAILS.
                   8725: #
                   8726: #      3)   THE RESULTING HISTORY STACK POINTER IS SAVED IN
                   8727: #           PMHBS TO ESTABLISH A NEW LEVEL OF HISTORY STACK.
                   8728: #
                   8729: #      AFTER MATCHING A PATTERN, THE END OF MATCH ROUTINE GETS
                   8730: #      CONTROL (P$NTH). THIS ROUTINE PROCEEDS AS FOLLOWS.
                   8731: #
                   8732: #      1)   LOAD THE CURRENT VALUE OF PMHBS AND RECOGNIZE THE
                   8733: #           OUTER LEVEL CASE BY THE FACT THAT THE ASSOCIATED
                   8734: #           CURSOR IN THIS CASE IS THE PATTERN MATCH TYPE CODE
                   8735: #           WHICH IS LESS THAN 3. TERMINATE THE MATCH IN THIS
                   8736: #           CASE AND CONTINUE EXECUTION OF THE PROGRAM.
                   8737: #
                   8738: #      2)   OTHERWISE MAKE A SPECIAL HISTORY STACK ENTRY IN
                   8739: #           WHICH THE NODE POINTER POINTS TO THE SPECIAL NODE
                   8740: #           NDEXC AND THE CURSOR IS THE CURRENT VALUE OF PMHBS.
                   8741: #           THE MATCH ROUTINE FOR NDEXC (P$EXC) RESETS PMHBS TO
                   8742: #           THIS (INNER) VALUE AND AND THEN FAILS.
                   8743: #
                   8744: #      3)   USING THE HISTORY STACK ENTRY MADE ON STARTING THE
                   8745: #           EXPRESSION (ACCESSIBLE WITH THE CURRENT VALUE OF
                   8746: #           PMHBS), RESTORE THE P$EXA NODE POINTER AND THE OLD
                   8747: #           PMHBS SETTING. TAKE THE SUCCESSOR AND CONTINUE.
                   8748: #
                   8749: #      AN OPTIMIZATION IS POSSIBLE IF THE EXPRESSION PATTERN
                   8750: #      MAKES NO ENTRIES ON THE HISTORY STACK. IN THIS CASE,
                   8751: #      INSTEAD OF BUILDING THE P$EXC NODE IN STEP 2, IT IS MORE
                   8752: #      EFFICIENT TO SIMPLY POP OFF THE P$EXB ENTRY AND ITS
                   8753: #      ASSOCIATED NODE POINTER. THE EFFECT IS THE SAME.
                   8754:        #page   
                   8755: #
                   8756: #      COMPOUND PATTERNS (CONTINUED)
                   8757: #
                   8758: #      BINARY DOLLAR (IMMEDIATE ASSIGNMENT)
                   8759: #      ------------------------------------
                   8760: #
                   8761: #           +---+            THIS NODE (P$IMA) STACKS THE CURSOR
                   8762: #           I A I            PMHBS AND A PTR TO NDIMB AND RESETS
                   8763: #           +---+            THE STACK PTR PMHBS.
                   8764: #             I
                   8765: #             I
                   8766: #           +---+            THIS IS THE LEFT STRUCTURE FOR THE
                   8767: #           I X I            PATTERN LEFT ARGUMENT OF THE
                   8768: #           +---+            IMMEDIATE ASSIGNMENT CALL.
                   8769: #             I
                   8770: #             I
                   8771: #           +---+            THIS NODE (P$IMC) PERFORMS THE
                   8772: #           I C I-----       ASSIGNMENT, POPS PMHBS AND STACKS
                   8773: #           +---+            THE OLD PMHBS AND A PTR TO NDIMD.
                   8774: #
                   8775: #
                   8776: #      THE STRUCTURE AND EXECUTION OF THIS PATTERN ARE SIMILAR
                   8777: #      TO THOSE OF THE RECURSIVE EXPRESSION PATTERN MATCHING.
                   8778: #
                   8779: #      THE MATCH ROUTINE FOR NDIMB (P$IMB) RESTORES THE OUTER
                   8780: #      LEVEL VALUE OF PMHBS, UNSTACKS THE SAVED CURSOR AND FAILS
                   8781: #
                   8782: #      THE MATCH ROUTINE P$IMC USES THE CURRENT VALUE OF PMHBS
                   8783: #      TO LOCATE THE P$IMB ENTRY. THIS ENTRY IS USED TO MAKE
                   8784: #      THE ASSIGNMENT AND RESTORE THE OUTER LEVEL VALUE OF
                   8785: #      PMHBS. FINALLY, THE INNER LEVEL VALUE OF PMHBS AND A
                   8786: #      POINTER TO THE SPECIAL NODE NDIMD ARE STACKED.
                   8787: #
                   8788: #      THE MATCH ROUTINE FOR NDIMD (P$IMD) RESTORES THE INNER
                   8789: #      LEVEL VALUE OF PMHBS AND FAILS BACK INTO THE STACK.
                   8790: #
                   8791: #      AN OPTIMIZATION OCCURS IF THE INNER PATTERN MAKES NO
                   8792: #      ENTRIES ON THE HISTORY STACK. IN THIS CASE, P$IMC POPS
                   8793: #      THE P$IMB ENTRY INSTEAD OF MAKING A P$IMD ENTRY.
                   8794:        #page   
                   8795: #
                   8796: #      ARBNO
                   8797: #
                   8798: #      SEE COMPOUND PATTERNS SECTION FOR STUCTURE AND
                   8799: #      ALGORITHM FOR MATCHING THIS NODE TYPE.
                   8800: #
                   8801: #      NO PARAMETERS
                   8802: #
                   8803:        .align  2
                   8804:        .word   bl$p0
                   8805: p$aba:                         # p0blk
                   8806:        movl    r7,-(sp)        # stack cursor
                   8807:        movl    r9,-(sp)        # stack dummy node ptr
                   8808:        movl    pmhbs,-(sp)     # stack old stack base ptr
                   8809:        movl    $ndabb,-(sp)    # stack ptr to node ndabb
                   8810:        movl    sp,pmhbs        # store new stack base ptr
                   8811:        jmp     succp           # succeed
                   8812:        #page   
                   8813: #
                   8814: #      ARBNO (REMOVE P$ABA SPECIAL STACK ENTRY)
                   8815: #
                   8816: #      NO PARAMETERS (DUMMY PATTERN)
                   8817: #
                   8818: p$abb:                         # entry point
                   8819:        movl    r7,pmhbs        # restore history stack base ptr
                   8820:        jmp     flpop           # fail and pop dummy node ptr
                   8821:        #page   
                   8822: #
                   8823: #      ARBNO (CHECK IF ARG MATCHED NULL STRING)
                   8824: #
                   8825: #      NO PARAMETERS (DUMMY PATTERN)
                   8826: #
                   8827:        .align  2
                   8828:        .word   bl$p0
                   8829: p$abc:                         # p0blk
                   8830:        movl    pmhbs,r10       # keep p$abb stack base
                   8831:        movl    4*3(r10),r6     # load initial cursor
                   8832:        movl    4*1(r10),pmhbs  # restore outer stack base ptr
                   8833:        cmpl    r10,sp          # jump if no history stack entries
                   8834:        beqlu   pabc1
                   8835:        movl    r10,-(sp)       # else save inner pmhbs entry
                   8836:        movl    $ndabd,-(sp)    # stack ptr to special node ndabd
                   8837:        jmp     pabc2           # merge
                   8838: #
                   8839: #      OPTIMISE CASE OF NO EXTRA ENTRIES ON STACK FROM ARBNO ARG
                   8840: #
                   8841: pabc1: addl2   $4*num04,sp     # remove ndabb entry and cursor
                   8842: #
                   8843: #      MERGE TO CHECK FOR MATCHING OF NULL STRING
                   8844: #
                   8845: pabc2: cmpl    r6,r7           # allow further attempt if non-null
                   8846:        beqlu   0f
                   8847:        jmp     succp
                   8848: 0:             
                   8849:        movl    4*pthen(r9),r9  # bypass alternative node so as to ..
                   8850:        jmp     succp           # ... refuse further match attempts
                   8851:        #page   
                   8852: #
                   8853: #      ARBNO (TRY FOR ALTERNATIVES IN ARBNO ARGUMENT)
                   8854: #
                   8855: #      NO PARAMETERS (DUMMY PATTERN)
                   8856: #
                   8857: p$abd:                         # entry point
                   8858:        movl    r7,pmhbs        # restore inner stack base ptr
                   8859:        jmp     failp           # and fail
                   8860:        #page   
                   8861: #
                   8862: #      ABORT
                   8863: #
                   8864: #      NO PARAMETERS
                   8865: #
                   8866:        .align  2
                   8867:        .word   bl$p0
                   8868: p$abo:                         # p0blk
                   8869:        jmp     exfal           # signal statement failure
                   8870:        #page   
                   8871: #
                   8872: #      ALTERNATION
                   8873: #
                   8874: #      PARM1                 ALTERNATIVE NODE
                   8875: #
                   8876:        .align  2
                   8877:        .word   bl$p1
                   8878: p$alt:                         # p1blk
                   8879:        movl    r7,-(sp)        # stack cursor
                   8880:        movl    4*parm1(r9),-(sp)# stack pointer to alternative
                   8881:        jsb     sbchk           # check for stack overflow
                   8882:        jmp     succp           # if all ok, then succeed
                   8883:        #page   
                   8884: #
                   8885: #      ANY (ONE CHARACTER ARGUMENT) (1-CHAR STRING ALSO)
                   8886: #
                   8887: #      PARM1                 CHARACTER ARGUMENT
                   8888: #
                   8889:        .align  2
                   8890:        .word   bl$p1
                   8891: p$ans:                         # p1blk
                   8892:        cmpl    r7,pmssl        # fail if no chars left
                   8893:        bnequ   0f
                   8894:        jmp     failp
                   8895: 0:             
                   8896:        movl    r$pms,r10       # else point to subject string
                   8897:        movab   cfp$f(r10)[r7],r10 # point to current character
                   8898:        movzbl  (r10),r6        # load current character
                   8899:        cmpl    r6,4*parm1(r9)  # fail if no match
                   8900:        beqlu   0f
                   8901:        jmp     failp
                   8902: 0:             
                   8903:        incl    r7              # else bump cursor
                   8904:        jmp     succp           # and succeed
                   8905:        #page   
                   8906: #
                   8907: #      ANY (MULTI-CHARACTER ARGUMENT CASE)
                   8908: #
                   8909: #      PARM1                 POINTER TO CTBLK
                   8910: #      PARM2                 BIT MASK TO SELECT BIT IN CTBLK
                   8911: #
                   8912:        .align  2
                   8913:        .word   bl$p2
                   8914: p$any:                         # p2blk
                   8915: #
                   8916: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   8917: #
                   8918: pany1: cmpl    r7,pmssl        # fail if no characters left
                   8919:        bnequ   0f
                   8920:        jmp     failp
                   8921: 0:             
                   8922:        movl    r$pms,r10       # else point to subject string
                   8923:        movab   cfp$f(r10)[r7],r10 # get char ptr to current character
                   8924:        movzbl  (r10),r6        # load current character
                   8925:        movl    4*parm1(r9),r10 # point to ctblk
                   8926:        moval   0[r6],r6        # change to byte offset
                   8927:        addl2   r6,r10          # point to entry in ctblk
                   8928:        movl    4*ctchs(r10),r6 # load word from ctblk
                   8929:        mcoml   4*parm2(r9),r11 # and with selected bit
                   8930:        bicl2   r11,r6
                   8931:        bnequ   0f              # fail if no match
                   8932:        jmp     failp
                   8933: 0:             
                   8934:        incl    r7              # else bump cursor
                   8935:        jmp     succp           # and succeed
                   8936:        #page   
                   8937: #
                   8938: #      ANY (EXPRESSION ARGUMENT)
                   8939: #
                   8940: #      PARM1                 EXPRESSION POINTER
                   8941: #
                   8942:        .align  2
                   8943:        .word   bl$p1
                   8944: p$ayd:                         # p1blk
                   8945:        jsb     evals           # evaluate string argument
                   8946:        .long   er_043          # any evaluated argument is not string
                   8947:        .long   failp           # fail if evaluation failure
                   8948:        .long   pany1           # merge multi-char case if ok
                   8949:        #page   
                   8950: #
                   8951: #      P$ARB                 INITIAL ARB MATCH
                   8952: #
                   8953: #      NO PARAMETERS
                   8954: #
                   8955: #      THE P$ARB NODE IS PART OF A COMPOUND PATTERN STRUCTURE
                   8956: #      FOR AN ARB PATTERN (SEE DESCRIPTION OF COMPOUND PATTERNS)
                   8957: #
                   8958:        .align  2
                   8959:        .word   bl$p0
                   8960: p$arb:                         # p0blk
                   8961:        movl    4*pthen(r9),r9  # load successor pointer
                   8962:        movl    r7,-(sp)        # stack dummy cursor
                   8963:        movl    r9,-(sp)        # stack successor pointer
                   8964:        movl    r7,-(sp)        # stack cursor
                   8965:        movl    $ndarc,-(sp)    # stack ptr to special node ndarc
                   8966:        movl    (r9),r11        # execute next node matching null
                   8967:        jmp     (r11)
                   8968:        #page   
                   8969: #
                   8970: #      P$ARC                 EXTEND ARB MATCH
                   8971: #
                   8972: #      NO PARAMETERS (DUMMY PATTERN)
                   8973: #
                   8974: p$arc:                         # entry point
                   8975:        cmpl    r7,pmssl        # fail and pop stack to successor
                   8976:        bnequ   0f
                   8977:        jmp     flpop
                   8978: 0:             
                   8979:        incl    r7              # else bump cursor
                   8980:        movl    r7,-(sp)        # stack updated cursor
                   8981:        movl    r9,-(sp)        # restack pointer to ndarc node
                   8982:        movl    4*2(sp),r9      # load successor pointer
                   8983:        movl    (r9),r11        # off to reexecute successor node
                   8984:        jmp     (r11)
                   8985:        #page   
                   8986: #
                   8987: #      BAL
                   8988: #
                   8989: #      NO PARAMETERS
                   8990: #
                   8991: #      THE P$BAL NODE IS PART OF THE COMPOUND STRUCTURE BUILT
                   8992: #      FOR BAL (SEE SECTION ON COMPOUND PATTERNS).
                   8993: #
                   8994:        .align  2
                   8995:        .word   bl$p0
                   8996: p$bal:                         # p0blk
                   8997:        clrl    r8              # zero parentheses level counter
                   8998:        movl    r$pms,r10       # point to subject string
                   8999:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9000:        jmp     pbal2           # jump into scan loop
                   9001: #
                   9002: #      LOOP TO SCAN OUT CHARACTERS
                   9003: #
                   9004: pbal1: movzbl  (r10)+,r6       # load next character, bump pointer
                   9005:        incl    r7              # push cursor for character
                   9006:        cmpl    r6,$ch$pp       # jump if left paren
                   9007:        beqlu   pbal3
                   9008:        cmpl    r6,$ch$rp       # jump if right paren
                   9009:        beqlu   pbal4
                   9010:        tstl    r8              # else succeed if at outer level
                   9011:        beqlu   pbal5
                   9012: #
                   9013: #      HERE AFTER PROCESSING ONE CHARACTER
                   9014: #
                   9015: pbal2: cmpl    r7,pmssl        # loop back unless end of string
                   9016:        bnequ   pbal1
                   9017:        jmp     failp           # in which case, fail
                   9018: #
                   9019: #      HERE ON LEFT PAREN
                   9020: #
                   9021: pbal3: incl    r8              # bump paren level
                   9022:        jmp     pbal2           # loop back to check end of string
                   9023: #
                   9024: #      HERE FOR RIGHT PAREN
                   9025: #
                   9026: pbal4: tstl    r8              # fail if no matching left paren
                   9027:        bnequ   0f
                   9028:        jmp     failp
                   9029: 0:             
                   9030:        decl    r8              # else decrement level counter
                   9031:        bnequ   pbal2           # loop back if not at outer level
                   9032: #
                   9033: #      HERE AFTER SUCCESSFULLY SCANNING A BALANCED STRING
                   9034: #
                   9035: pbal5: movl    r7,-(sp)        # stack cursor
                   9036:        movl    r9,-(sp)        # stack ptr to bal node for extend
                   9037:        jmp     succp           # and succeed
                   9038:        #page   
                   9039: #
                   9040: #      BREAK (EXPRESSION ARGUMENT)
                   9041: #
                   9042: #      PARM1                 EXPRESSION POINTER
                   9043: #
                   9044:        .align  2
                   9045:        .word   bl$p1
                   9046: p$bkd:                         # p1blk
                   9047:        jsb     evals           # evaluate string expression
                   9048:        .long   er_044          # break evaluated argument is not string
                   9049:        .long   failp           # fail if evaluation fails
                   9050:        .long   pbrk1           # merge with multi-char case if ok
                   9051:        #page   
                   9052: #
                   9053: #      BREAK (ONE CHARACTER ARGUMENT)
                   9054: #
                   9055: #      PARM1                 CHARACTER ARGUMENT
                   9056: #
                   9057:        .align  2
                   9058:        .word   bl$p1
                   9059: p$bks:                         # p1blk
                   9060:        movl    pmssl,r8        # get subject string length
                   9061:        subl2   r7,r8           # get number of characters left
                   9062:        bnequ   0f              # fail if no characters left
                   9063:        jmp     failp
                   9064: 0:             
                   9065:                                # set counter for chars left
                   9066:        movl    r$pms,r10       # point to subject string
                   9067:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9068: #
                   9069: #      LOOP TO SCAN TILL BREAK CHARACTER FOUND
                   9070: #
                   9071: pbks1: movzbl  (r10)+,r6       # load next char, bump pointer
                   9072:        cmpl    r6,4*parm1(r9)  # succeed if break character found
                   9073:        bnequ   0f
                   9074:        jmp     succp
                   9075: 0:             
                   9076:        incl    r7              # else push cursor
                   9077:        sobgtr  r8,pbks1        # loop back if more to go
                   9078:        jmp     failp           # fail if end of string, no break chr
                   9079:        #page   
                   9080: #
                   9081: #      BREAK (MULTI-CHARACTER ARGUMENT)
                   9082: #
                   9083: #      PARM1                 POINTER TO CTBLK
                   9084: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9085: #
                   9086:        .align  2
                   9087:        .word   bl$p2
                   9088: p$brk:                         # p2blk
                   9089: #
                   9090: #      EXPRESSION ARGUMENT MERGES HERE
                   9091: #
                   9092: pbrk1: movl    pmssl,r8        # load subject string length
                   9093:        subl2   r7,r8           # get number of characters left
                   9094:        bnequ   0f              # fail if no characters left
                   9095:        jmp     failp
                   9096: 0:             
                   9097:                                # set counter for characters left
                   9098:        movl    r$pms,r10       # else point to subject string
                   9099:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9100:        movl    r9,psave        # save node pointer
                   9101: #
                   9102: #      LOOP TO SEARCH FOR BREAK CHARACTER
                   9103: #
                   9104: pbrk2: movzbl  (r10)+,r6       # load next char, bump pointer
                   9105:        movl    4*parm1(r9),r9  # load pointer to ctblk
                   9106:        moval   0[r6],r6        # convert to byte offset
                   9107:        addl2   r6,r9           # point to ctblk entry
                   9108:        movl    4*ctchs(r9),r6  # load ctblk word
                   9109:        movl    psave,r9        # restore node pointer
                   9110:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9111:        bicl2   r11,r6
                   9112:        beqlu   0f              # succeed if break character found
                   9113:        jmp     succp
                   9114: 0:             
                   9115:        incl    r7              # else push cursor
                   9116:        sobgtr  r8,pbrk2        # loop back unless end of string
                   9117:        jmp     failp           # fail if end of string, no break chr
                   9118:        #page   
                   9119: #
                   9120: #      BREAKX (EXTENSION)
                   9121: #
                   9122: #      THIS IS THE ENTRY WHICH CAUSES AN EXTENSION OF A BREAKX
                   9123: #      MATCH WHEN FAILURE OCCURS. SEE SECTION ON COMPOUND
                   9124: #      PATTERNS FOR FULL DETAILS OF BREAKX MATCHING.
                   9125: #
                   9126: #      NO PARAMETERS
                   9127: #
                   9128:        .align  2
                   9129:        .word   bl$p0
                   9130: p$bkx:                         # p0blk
                   9131:        incl    r7              # step cursor past previous break chr
                   9132:        jmp     succp           # succeed to rematch break
                   9133:        #page   
                   9134: #
                   9135: #      BREAKX (EXPRESSION ARGUMENT)
                   9136: #
                   9137: #      SEE SECTION ON COMPOUND PATTERNS FOR FULL STRUCTURE OF
                   9138: #      BREAKX PATTERN. THE ACTUAL CHARACTER MATCHING USES A
                   9139: #      BREAK NODE. HOWEVER, THE ENTRY FOR THE EXPRESSION
                   9140: #      ARGUMENT CASE IS SEPARATED TO GET PROPER ERROR MESSAGES.
                   9141: #
                   9142: #      PARM1                 EXPRESSION POINTER
                   9143: #
                   9144:        .align  2
                   9145:        .word   bl$p1
                   9146: p$bxd:                         # p1blk
                   9147:        jsb     evals           # evaluate string argument
                   9148:        .long   er_045          # breakx evaluated argument is not string
                   9149:        .long   failp           # fail if evaluation fails
                   9150:        .long   pbrk1           # merge with break if all ok
                   9151:        #page   
                   9152: #
                   9153: #      CURSOR ASSIGNMENT
                   9154: #
                   9155: #      PARM1                 NAME BASE
                   9156: #      PARM2                 NAME OFFSET
                   9157: #
                   9158:        .align  2
                   9159:        .word   bl$p2
                   9160: p$cas:                         # p2blk
                   9161:        movl    r9,-(sp)        # save node pointer
                   9162:        movl    r7,-(sp)        # save cursor
                   9163:        movl    4*parm1(r9),r10 # load name base
                   9164:        movl    r7,r5           # load cursor as integer
                   9165:        movl    4*parm2(r9),r7  # load name offset
                   9166:        jsb     icbld           # get icblk for cursor value
                   9167:        movl    r7,r6           # move name offset
                   9168:        movl    r9,r7           # move value to assign
                   9169:        jsb     asinp           # perform assignment
                   9170:        .long   flpop           # fail on assignment failure
                   9171:        movl    (sp)+,r7        # else restore cursor
                   9172:        movl    (sp)+,r9        # restore node pointer
                   9173:        jmp     succp           # and succeed matching null
                   9174:        #page   
                   9175: #
                   9176: #      EXPRESSION NODE (P$EXA, INITIAL ENTRY)
                   9177: #
                   9178: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9179: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9180: #
                   9181: #      PARM1                 EXPRESSION POINTER
                   9182: #
                   9183:        .align  2
                   9184:        .word   bl$p1
                   9185: p$exa:                         # p1blk
                   9186:        jsb     evalp           # evaluate expression
                   9187:        .long   failp           # fail if evaluation fails
                   9188:        cmpl    r6,$p$aaa       # jump if result is not a pattern
                   9189:        blequ   pexa1
                   9190: #
                   9191: #      HERE IF RESULT OF EXPRESSION IS A PATTERN
                   9192: #
                   9193:        movl    r7,-(sp)        # stack dummy cursor
                   9194:        movl    r9,-(sp)        # stack ptr to p$exa node
                   9195:        movl    pmhbs,-(sp)     # stack history stack base ptr
                   9196:        movl    $ndexb,-(sp)    # stack ptr to special node ndexb
                   9197:        movl    sp,pmhbs        # store new stack base pointer
                   9198:        movl    r10,r9          # copy node pointer
                   9199:        movl    (r9),r11        # match first node in expression pat
                   9200:        jmp     (r11)
                   9201: #
                   9202: #      HERE IF RESULT OF EXPRESSION IS NOT A PATTERN
                   9203: #
                   9204: pexa1: cmpl    r6,$b$scl       # jump if it is already a string
                   9205:        beqlu   pexa2
                   9206:        movl    r10,-(sp)       # else stack result
                   9207:        movl    r9,r10          # save node pointer
                   9208:        jsb     gtstg           # convert result to string
                   9209:        .long   er_046          # expression does not evaluate to pattern
                   9210:        movl    r9,r8           # copy string pointer
                   9211:        movl    r10,r9          # restore node pointer
                   9212:        movl    r8,r10          # copy string pointer again
                   9213: #
                   9214: #      MERGE HERE WITH STRING POINTER IN XL
                   9215: #
                   9216: pexa2: tstl    4*sclen(r10)    # just succeed if null string
                   9217:        bnequ   0f
                   9218:        jmp     succp
                   9219: 0:             
                   9220:        jmp     pstr1           # else merge with string circuit
                   9221:        #page   
                   9222: #
                   9223: #      EXPRESSION NODE (P$EXB, REMOVE NDEXB ENTRY)
                   9224: #
                   9225: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9226: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9227: #
                   9228: #      NO PARAMETERS (DUMMY PATTERN)
                   9229: #
                   9230: p$exb:                         # entry point
                   9231:        movl    r7,pmhbs        # restore outer level stack pointer
                   9232:        jmp     flpop           # fail and pop p$exa node ptr
                   9233:        #page   
                   9234: #
                   9235: #      EXPRESSION NODE (P$EXC, REMOVE NDEXC ENTRY)
                   9236: #
                   9237: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9238: #      ALGORITHMS FOR HANDLING EXPRESSION NODES.
                   9239: #
                   9240: #      NO PARAMETERS (DUMMY PATTERN)
                   9241: #
                   9242: p$exc:                         # entry point
                   9243:        movl    r7,pmhbs        # restore inner stack base pointer
                   9244:        jmp     failp           # and fail into expr pattern alternvs
                   9245:        #page   
                   9246: #
                   9247: #      FAIL
                   9248: #
                   9249: #      NO PARAMETERS
                   9250: #
                   9251:        .align  2
                   9252:        .word   bl$p0
                   9253: p$fal:                         # p0blk
                   9254:        jmp     failp           # just signal failure
                   9255:        #page   
                   9256: #
                   9257: #      FENCE
                   9258: #
                   9259: #      SEE COMPOUND PATTERNS SECTION FOR THE STRUCTURE AND
                   9260: #      ALGORITHM FOR MATCHING THIS NODE TYPE.
                   9261: #
                   9262: #      NO PARAMETERS
                   9263: #
                   9264:        .align  2
                   9265:        .word   bl$p0
                   9266: p$fen:                         # p0blk
                   9267:        movl    r7,-(sp)        # stack dummy cursor
                   9268:        movl    $ndabo,-(sp)    # stack ptr to abort node
                   9269:        jmp     succp           # and succeed matching null
                   9270:        #page   
                   9271: #
                   9272: #      FENCE (FUNCTION)
                   9273: #
                   9274: #      SEE COMPOUND PATTERNS COMMENTS AT START OF THIS SECTION
                   9275: #      FOR DETAILS OF SCHEME
                   9276: #
                   9277: #      NO PARAMETERS
                   9278: #
                   9279:        .align  2
                   9280:        .word   bl$p0
                   9281: p$fna:                         # p0blk
                   9282:        movl    pmhbs,-(sp)     # stack current history stack base
                   9283:        movl    $ndfnb,-(sp)    # stack indir ptr to p$fnb (failure)
                   9284:        movl    sp,pmhbs        # begin new history stack
                   9285:        jmp     succp           # succeed
                   9286:        #page   
                   9287: #
                   9288: #      FENCE (FUNCTION) (RESET HISTORY STACK AND FAIL)
                   9289: #
                   9290: #      NO PARAMETERS (DUMMY PATTERN)
                   9291: #
                   9292:        .align  2
                   9293:        .word   bl$p0
                   9294: p$fnb:                         # p0blk
                   9295:        movl    r7,pmhbs        # restore outer pmhbs stack base
                   9296:        jmp     failp           # ...and fail
                   9297:        #page   
                   9298: #
                   9299: #      FENCE (FUNCTION) (MAKE FENCE TRAP ENTRY ON STACK)
                   9300: #
                   9301: #      NO PARAMETERS (DUMMY PATTERN)
                   9302: #
                   9303:        .align  2
                   9304:        .word   bl$p0
                   9305: p$fnc:                         # p0blk
                   9306:        movl    pmhbs,r10       # get inner stack base ptr
                   9307:        movl    4*num01(r10),pmhbs # restore outer stack base
                   9308:        cmpl    r10,sp          # optimize if no alternatives
                   9309:        beqlu   pfnc1
                   9310:        movl    r10,-(sp)       # else stack inner stack base
                   9311:        movl    $ndfnd,-(sp)    # stack ptr to ndfnd
                   9312:        jmp     succp           # succeed
                   9313: #
                   9314: #      HERE WHEN FENCE FUNCTION LEFT NOTHING ON THE STACK
                   9315: #
                   9316: pfnc1: addl2   $4*num02,sp     # pop off p$fnb entry
                   9317:        jmp     succp           # succeed
                   9318:        #page   
                   9319: #
                   9320: #      FENCE (FUNCTION) (SKIP PAST ALTERNATIVES ON FAILURE)
                   9321: #
                   9322: #      NO PARAMETERS (DUMMY PATTERN)
                   9323: #
                   9324:        .align  2
                   9325:        .word   bl$p0
                   9326: p$fnd:                         # p0blk
                   9327:        movl    r7,sp           # pop stack to fence() history base
                   9328:        jmp     flpop           # pop base entry and fail
                   9329:        #page   
                   9330: #
                   9331: #      IMMEDIATE ASSIGNMENT (INITIAL ENTRY, SAVE CURRENT CURSOR)
                   9332: #
                   9333: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9334: #      STRUCTURE AND ALGORITHM FOR MATCHING THIS NODE TYPE.
                   9335: #
                   9336: #      NO PARAMETERS
                   9337: #
                   9338:        .align  2
                   9339:        .word   bl$p0
                   9340: p$ima:                         # p0blk
                   9341:        movl    r7,-(sp)        # stack cursor
                   9342:        movl    r9,-(sp)        # stack dummy node pointer
                   9343:        movl    pmhbs,-(sp)     # stack old stack base pointer
                   9344:        movl    $ndimb,-(sp)    # stack ptr to special node ndimb
                   9345:        movl    sp,pmhbs        # store new stack base pointer
                   9346:        jmp     succp           # and succeed
                   9347:        #page   
                   9348: #
                   9349: #      IMMEDIATE ASSIGNMENT (REMOVE CURSOR MARK ENTRY)
                   9350: #
                   9351: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9352: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9353: #
                   9354: #      NO PARAMETERS (DUMMY PATTERN)
                   9355: #
                   9356: p$imb:                         # entry point
                   9357:        movl    r7,pmhbs        # restore history stack base ptr
                   9358:        jmp     flpop           # fail and pop dummy node ptr
                   9359:        #page   
                   9360: #
                   9361: #      IMMEDIATE ASSIGNMENT (PERFORM ACTUAL ASSIGNMENT)
                   9362: #
                   9363: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9364: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9365: #
                   9366: #      PARM1                 NAME BASE OF VARIABLE
                   9367: #      PARM2                 NAME OFFSET OF VARIABLE
                   9368: #
                   9369:        .align  2
                   9370:        .word   bl$p2
                   9371: p$imc:                         # p2blk
                   9372:        movl    pmhbs,r10       # load pointer to p$imb entry
                   9373:        movl    r7,r6           # copy final cursor
                   9374:        movl    4*3(r10),r7     # load initial cursor
                   9375:        movl    4*1(r10),pmhbs  # restore outer stack base pointer
                   9376:        cmpl    r10,sp          # jump if no history stack entries
                   9377:        beqlu   pimc1
                   9378:        movl    r10,-(sp)       # else save inner pmhbs pointer
                   9379:        movl    $ndimd,-(sp)    # and a ptr to special node ndimd
                   9380:        jmp     pimc2           # merge
                   9381: #
                   9382: #      HERE IF NO ENTRIES MADE ON HISTORY STACK
                   9383: #
                   9384: pimc1: addl2   $4*num04,sp     # remove ndimb entry and cursor
                   9385: #
                   9386: #      MERGE HERE TO PERFORM ASSIGNMENT
                   9387: #
                   9388: pimc2: movl    r6,-(sp)        # save current (final) cursor
                   9389:        movl    r9,-(sp)        # save current node pointer
                   9390:        movl    r$pms,r10       # point to subject string
                   9391:        subl2   r7,r6           # compute substring length
                   9392:        jsb     sbstr           # build substring
                   9393:        movl    r9,r7           # move result
                   9394:        movl    (sp),r9         # reload node pointer
                   9395:        movl    4*parm1(r9),r10 # load name base
                   9396:        movl    4*parm2(r9),r6  # load name offset
                   9397:        jsb     asinp           # perform assignment
                   9398:        .long   flpop           # fail if assignment fails
                   9399:        movl    (sp)+,r9        # else restore node pointer
                   9400:        movl    (sp)+,r7        # restore cursor
                   9401:        jmp     succp           # and succeed
                   9402:        #page   
                   9403: #
                   9404: #      IMMEDIATE ASSIGNMENT (REMOVE NDIMD ENTRY ON FAILURE)
                   9405: #
                   9406: #      SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE
                   9407: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9408: #
                   9409: #      NO PARAMETERS (DUMMY PATTERN)
                   9410: #
                   9411: p$imd:                         # entry point
                   9412:        movl    r7,pmhbs        # restore inner stack base pointer
                   9413:        jmp     failp           # and fail
                   9414:        #page   
                   9415: #
                   9416: #      LEN (INTEGER ARGUMENT)
                   9417: #
                   9418: #      PARM1                 INTEGER ARGUMENT
                   9419: #
                   9420:        .align  2
                   9421:        .word   bl$p1
                   9422: p$len:                         # p1blk
                   9423: #
                   9424: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9425: #
                   9426: plen1: addl2   4*parm1(r9),r7  # push cursor indicated amount
                   9427:        cmpl    r7,pmssl        # succeed if not off end
                   9428:        bgtru   0f
                   9429:        jmp     succp
                   9430: 0:             
                   9431:        jmp     failp           # else fail
                   9432:        #page   
                   9433: #
                   9434: #      LEN (EXPRESSION ARGUMENT)
                   9435: #
                   9436: #      PARM1                 EXPRESSION POINTER
                   9437: #
                   9438:        .align  2
                   9439:        .word   bl$p1
                   9440: p$lnd:                         # p1blk
                   9441:        jsb     evali           # evaluate integer argument
                   9442:        .long   er_047          # len evaluated argument is not integer
                   9443:        .long   er_048          # len evaluated argument is negative or too large
                   9444:        .long   failp           # fail if evaluation fails
                   9445:        .long   plen1           # merge with normal circuit if ok
                   9446:        #page   
                   9447: #
                   9448: #      NOTANY (EXPRESSION ARGUMENT)
                   9449: #
                   9450: #      PARM1                 EXPRESSION POINTER
                   9451: #
                   9452:        .align  2
                   9453:        .word   bl$p1
                   9454: p$nad:                         # p1blk
                   9455:        jsb     evals           # evaluate string argument
                   9456:        .long   er_049          # notany evaluated argument is not string
                   9457:        .long   failp           # fail if evaluation fails
                   9458:        .long   pnay1           # merge with multi-char case if ok
                   9459:        #page   
                   9460: #
                   9461: #      NOTANY (ONE CHARACTER ARGUMENT)
                   9462: #
                   9463: #      PARM1                 CHARACTER ARGUMENT
                   9464: #
                   9465:        .align  2
                   9466:        .word   bl$p1
                   9467: p$nas:                         # entry point
                   9468:        cmpl    r7,pmssl        # fail if no chars left
                   9469:        bnequ   0f
                   9470:        jmp     failp
                   9471: 0:             
                   9472:        movl    r$pms,r10       # else point to subject string
                   9473:        movab   cfp$f(r10)[r7],r10 # point to current character in strin
                   9474:        movzbl  (r10),r6        # load current character
                   9475:        cmpl    r6,4*parm1(r9)  # fail if match
                   9476:        bnequ   0f
                   9477:        jmp     failp
                   9478: 0:             
                   9479:        incl    r7              # else bump cursor
                   9480:        jmp     succp           # and succeed
                   9481:        #page   
                   9482: #
                   9483: #      NOTANY (MULTI-CHARACTER STRING ARGUMENT)
                   9484: #
                   9485: #      PARM1                 POINTER TO CTBLK
                   9486: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9487: #
                   9488:        .align  2
                   9489:        .word   bl$p2
                   9490: p$nay:                         # p2blk
                   9491: #
                   9492: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9493: #
                   9494: pnay1: cmpl    r7,pmssl        # fail if no characters left
                   9495:        bnequ   0f
                   9496:        jmp     failp
                   9497: 0:             
                   9498:        movl    r$pms,r10       # else point to subject string
                   9499:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9500:        movzbl  (r10),r6        # load current character
                   9501:        moval   0[r6],r6        # convert to byte offset
                   9502:        movl    4*parm1(r9),r10 # load pointer to ctblk
                   9503:        addl2   r6,r10          # point to entry in ctblk
                   9504:        movl    4*ctchs(r10),r6 # load entry from ctblk
                   9505:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9506:        bicl2   r11,r6
                   9507:        beqlu   0f              # fail if character is matched
                   9508:        jmp     failp
                   9509: 0:             
                   9510:        incl    r7              # else bump cursor
                   9511:        jmp     succp           # and succeed
                   9512:        #page   
                   9513: #
                   9514: #      END OF PATTERN MATCH
                   9515: #
                   9516: #      THIS ROUTINE IS ENTERED ON SUCCESSFUL COMPLETION.
                   9517: #      SEE DESCRIPTION OF EXPRESSION PATTERNS IN COMPOUND
                   9518: #      PATTERN SECTION FOR HANDLING OF RECURSION IN MATCHING.
                   9519: #
                   9520: #      NO PARAMETERS (DUMMY PATTERN)
                   9521: #
                   9522: p$nth:                         # entry point
                   9523:        movl    pmhbs,r10       # load pointer to base of stack
                   9524:        movl    4*1(r10),r6     # load saved pmhbs (or pattern type)
                   9525:        cmpl    r6,$num02       # jump if outer level (pattern type)
                   9526:        blequ   pnth2
                   9527: #
                   9528: #      HERE WE ARE AT THE END OF MATCHING AN EXPRESSION PATTERN
                   9529: #
                   9530:        movl    r6,pmhbs        # restore outer stack base pointer
                   9531:        movl    4*2(r10),r9     # restore pointer to p$exa node
                   9532:        cmpl    r10,sp          # jump if no history stack entries
                   9533:        beqlu   pnth1
                   9534:        movl    r10,-(sp)       # else stack inner stack base ptr
                   9535:        movl    $ndexc,-(sp)    # stack ptr to special node ndexc
                   9536:        jmp     succp           # and succeed
                   9537: #
                   9538: #      HERE IF NO HISTORY STACK ENTRIES DURING PATTERN
                   9539: #
                   9540: pnth1: addl2   $4*num04,sp     # remove p$exb entry and node ptr
                   9541:        jmp     succp           # and succeed
                   9542: #
                   9543: #      HERE IF END OF MATCH AT OUTER LEVEL
                   9544: #
                   9545: pnth2: movl    r7,pmssl        # save final cursor in safe place
                   9546:        tstl    pmdfl           # jump if no pattern assignments
                   9547:        beqlu   pnth6
                   9548:        #page   
                   9549: #
                   9550: #      END OF PATTERN MATCH (CONTINUED)
                   9551: #
                   9552: #      NOW WE MUST PERFORM PATTERN ASSIGNMENTS. THIS IS DONE BY
                   9553: #      SCANNING THE HISTORY STACK FOR MATCHING NDPAB-NDPAD PAIRS
                   9554: #
                   9555: pnth3: subl2   $4,r10          # point past cursor entry
                   9556:        movl    -(r10),r6       # load node pointer
                   9557:        cmpl    r6,$ndpad       # jump if ndpad entry
                   9558:        beqlu   pnth4
                   9559:        cmpl    r6,$ndpab       # jump if not ndpab entry
                   9560:        bnequ   pnth5
                   9561: #
                   9562: #      HERE FOR NDPAB ENTRY, STACK INITIAL CURSOR
                   9563: #      NOTE THAT THERE MUST BE MORE ENTRIES ON THE STACK.
                   9564: #
                   9565:        movl    4*1(r10),-(sp)  # stack initial cursor
                   9566:        jsb     sbchk           # check for stack overflow
                   9567:        jmp     pnth3           # loop back if ok
                   9568: #
                   9569: #      HERE FOR NDPAD ENTRY. THE STARTING CURSOR FROM THE
                   9570: #      MATCHING NDPAD ENTRY IS NOW THE TOP STACK ENTRY.
                   9571: #
                   9572: pnth4: movl    4*1(r10),r6     # load final cursor
                   9573:        movl    (sp),r7         # load initial cursor from stack
                   9574:        movl    r10,(sp)        # save history stack scan ptr
                   9575:        subl2   r7,r6           # compute length of string
                   9576: #
                   9577: #      BUILD SUBSTRING AND PERFORM ASSIGNMENT
                   9578: #
                   9579:        movl    r$pms,r10       # point to subject string
                   9580:        jsb     sbstr           # construct substring
                   9581:        movl    r9,r7           # copy substring pointer
                   9582:        movl    (sp),r10        # reload history stack scan ptr
                   9583:        movl    4*2(r10),r10    # load pointer to p$pac node with nam
                   9584:        movl    4*parm2(r10),r6 # load name offset
                   9585:        movl    4*parm1(r10),r10# load name base
                   9586:        jsb     asinp           # perform assignment
                   9587:        .long   exfal           # match fails if name eval fails
                   9588:        movl    (sp)+,r10       # else restore history stack ptr
                   9589:        #page   
                   9590: #
                   9591: #      END OF PATTERN MATCH (CONTINUED)
                   9592: #
                   9593: #      HERE CHECK FOR END OF ENTRIES
                   9594: #
                   9595: pnth5: cmpl    r10,sp          # loop if more entries to scan
                   9596:        bnequ   pnth3
                   9597: #
                   9598: #      HERE AFTER DEALING WITH PATTERN ASSIGNMENTS
                   9599: #
                   9600: pnth6: movl    pmhbs,sp        # wipe out history stack
                   9601:        movl    (sp)+,r7        # load initial cursor
                   9602:        movl    (sp)+,r8        # load match type code
                   9603:        movl    pmssl,r6        # load final cursor value
                   9604:        movl    r$pms,r10       # point to subject string
                   9605:        clrl    r$pms           # clear subject string ptr for gbcol
                   9606:        tstl    r8              # jump if call by name
                   9607:        beqlu   pnth7
                   9608:        cmpl    r8,$num02       # exit if statement level call
                   9609:        bnequ   0f
                   9610:        jmp     exits
                   9611: 0:             
                   9612: #
                   9613: #      HERE WE HAVE A CALL BY VALUE, BUILD SUBSTRING
                   9614: #
                   9615:        subl2   r7,r6           # compute length of string
                   9616:        jsb     sbstr           # build substring
                   9617:        jmp     exixr           # and exit with substring value
                   9618: #
                   9619: #      HERE FOR CALL BY NAME, MAKE STACK ENTRIES FOR O$RPL
                   9620: #
                   9621: pnth7: movl    r7,-(sp)        # stack initial cursor
                   9622:        movl    r6,-(sp)        # stack final cursor
                   9623:        tstl    r$pmb           # skip if subject not buffer
                   9624:        beqlu   pnth8
                   9625:        movl    r$pmb,r10       # else get ptr to bcblk instead
                   9626: #
                   9627: #      HERE WITH XL POINTING TO SCBLK OR BCBLK
                   9628: #
                   9629: pnth8: movl    r10,-(sp)       # stack subject pointer
                   9630:        jmp     exits           # exit with special entry on stack
                   9631:        #page   
                   9632: #
                   9633: #      POS (INTEGER ARGUMENT)
                   9634: #
                   9635: #      PARM1                 INTEGER ARGUMENT
                   9636: #
                   9637:        .align  2
                   9638:        .word   bl$p1
                   9639: p$pos:                         # p1blk
                   9640: #
                   9641: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9642: #
                   9643: ppos1: cmpl    r7,4*parm1(r9)  # succeed if at right location
                   9644:        bnequ   0f
                   9645:        jmp     succp
                   9646: 0:             
                   9647:        jmp     failp           # else fail
                   9648:        #page   
                   9649: #
                   9650: #      POS (EXPRESSION ARGUMENT)
                   9651: #
                   9652: #      PARM1                 EXPRESSION POINTER
                   9653: #
                   9654:        .align  2
                   9655:        .word   bl$p1
                   9656: p$psd:                         # p1blk
                   9657:        jsb     evali           # evaluate integer argument
                   9658:        .long   er_050          # pos evaluated argument is not integer
                   9659:        .long   er_051          # pos evaluated argument is negative or too large
                   9660:        .long   failp           # fail if evaluation fails
                   9661:        .long   ppos1           # merge with normal case if ok
                   9662:        #page   
                   9663: #
                   9664: #      PATTERN ASSIGNMENT (INITIAL ENTRY, SAVE CURSOR)
                   9665: #
                   9666: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9667: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9668: #
                   9669: #      NO PARAMETERS
                   9670: #
                   9671:        .align  2
                   9672:        .word   bl$p0
                   9673: p$paa:                         # p0blk
                   9674:        movl    r7,-(sp)        # stack initial cursor
                   9675:        movl    $ndpab,-(sp)    # stack ptr to ndpab special node
                   9676:        jmp     succp           # and succeed matching null
                   9677:        #page   
                   9678: #
                   9679: #      PATTERN ASSIGNMENT (REMOVE SAVED CURSOR)
                   9680: #
                   9681: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9682: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9683: #
                   9684: #      NO PARAMETERS (DUMMY PATTERN)
                   9685: #
                   9686: p$pab:                         # entry point
                   9687:        jmp     failp           # just fail (entry is already popped)
                   9688:        #page   
                   9689: #
                   9690: #      PATTERN ASSIGNMENT (END OF MATCH, MAKE ASSIGN ENTRY)
                   9691: #
                   9692: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9693: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9694: #
                   9695: #      PARM1                 NAME BASE OF VARIABLE
                   9696: #      PARM2                 NAME OFFSET OF VARIABLE
                   9697: #
                   9698:        .align  2
                   9699:        .word   bl$p2
                   9700: p$pac:                         # p2blk
                   9701:        movl    r7,-(sp)        # stack dummy cursor value
                   9702:        movl    r9,-(sp)        # stack pointer to p$pac node
                   9703:        movl    r7,-(sp)        # stack final cursor
                   9704:        movl    $ndpad,-(sp)    # stack ptr to special ndpad node
                   9705:        movl    sp,pmdfl        # set dot flag non-zero
                   9706:        jmp     succp           # and succeed
                   9707:        #page   
                   9708: #
                   9709: #      PATTERN ASSIGNMENT (REMOVE ASSIGN ENTRY)
                   9710: #
                   9711: #      SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND
                   9712: #      ALGORITHMS FOR MATCHING THIS NODE TYPE.
                   9713: #
                   9714: #      NO PARAMETERS (DUMMY NODE)
                   9715: #
                   9716: p$pad:                         # entry point
                   9717:        jmp     flpop           # fail and remove p$pac node
                   9718:        #page   
                   9719: #
                   9720: #      REM
                   9721: #
                   9722: #      NO PARAMETERS
                   9723: #
                   9724:        .align  2
                   9725:        .word   bl$p0
                   9726: p$rem:                         # p0blk
                   9727:        movl    pmssl,r7        # point cursor to end of string
                   9728:        jmp     succp           # and succeed
                   9729:        #page   
                   9730: #
                   9731: #      RPOS (EXPRESSION ARGUMENT)
                   9732: #
                   9733: #      PARM1                 EXPRESSION POINTER
                   9734: #
                   9735:        .align  2
                   9736:        .word   bl$p1
                   9737: p$rpd:                         # p1blk
                   9738:        jsb     evali           # evaluate integer argument
                   9739:        .long   er_052          # rpos evaluated argument is not integer
                   9740:        .long   er_053          # rpos evaluated argument is negative or too large
                   9741:        .long   failp           # fail if evaluation fails
                   9742:        .long   prps1           # merge with normal case if ok
                   9743:        #page   
                   9744: #
                   9745: #      RPOS (INTEGER ARGUMENT)
                   9746: #
                   9747: #      PARM1                 INTEGER ARGUMENT
                   9748: #
                   9749:        .align  2
                   9750:        .word   bl$p1
                   9751: p$rps:                         # p1blk
                   9752: #
                   9753: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9754: #
                   9755: prps1: movl    pmssl,r8        # get length of string
                   9756:        subl2   r7,r8           # get number of characters remaining
                   9757:        cmpl    r8,4*parm1(r9)  # succeed if at right location
                   9758:        bnequ   0f
                   9759:        jmp     succp
                   9760: 0:             
                   9761:        jmp     failp           # else fail
                   9762:        #page   
                   9763: #
                   9764: #      RTAB (INTEGER ARGUMENT)
                   9765: #
                   9766: #      PARM1                 INTEGER ARGUMENT
                   9767: #
                   9768:        .align  2
                   9769:        .word   bl$p1
                   9770: p$rtb:                         # p1blk
                   9771: #
                   9772: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9773: #
                   9774: prtb1: movl    r7,r8           # save initial cursor
                   9775:        movl    pmssl,r7        # point to end of string
                   9776:        cmpl    r7,4*parm1(r9)  # fail if string not long enough
                   9777:        bgequ   0f
                   9778:        jmp     failp
                   9779: 0:             
                   9780:        subl2   4*parm1(r9),r7  # else set new cursor
                   9781:        cmpl    r7,r8           # and succeed if not too far already
                   9782:        blssu   0f
                   9783:        jmp     succp
                   9784: 0:             
                   9785:        jmp     failp           # in which case, fail
                   9786:        #page   
                   9787: #
                   9788: #      RTAB (EXPRESSION ARGUMENT)
                   9789: #
                   9790: #      PARM1                 EXPRESSION POINTER
                   9791: #
                   9792:        .align  2
                   9793:        .word   bl$p1
                   9794: p$rtd:                         # p1blk
                   9795:        jsb     evali           # evaluate integer argument
                   9796:        .long   er_054          # rtab evaluated argument is not integer
                   9797:        .long   er_055          # rtab evaluated argument is negative or too large
                   9798:        .long   failp           # fail if evaluation fails
                   9799:        .long   prtb1           # merge with normal case if success
                   9800:        #page   
                   9801: #
                   9802: #      SPAN (EXPRESSION ARGUMENT)
                   9803: #
                   9804: #      PARM1                 EXPRESSION POINTER
                   9805: #
                   9806:        .align  2
                   9807:        .word   bl$p1
                   9808: p$spd:                         # p1blk
                   9809:        jsb     evals           # evaluate string argument
                   9810:        .long   er_056          # span evaluated argument is not string
                   9811:        .long   failp           # fail if evaluation fails
                   9812:        .long   pspn1           # merge with multi-char case if ok
                   9813:        #page   
                   9814: #
                   9815: #      SPAN (MULTI-CHARACTER ARGUMENT CASE)
                   9816: #
                   9817: #      PARM1                 POINTER TO CTBLK
                   9818: #      PARM2                 BIT MASK TO SELECT BIT COLUMN
                   9819: #
                   9820:        .align  2
                   9821:        .word   bl$p2
                   9822: p$spn:                         # p2blk
                   9823: #
                   9824: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9825: #
                   9826: pspn1: movl    pmssl,r8        # copy subject string length
                   9827:        subl2   r7,r8           # calculate number of characters left
                   9828:        bnequ   0f              # fail if no characters left
                   9829:        jmp     failp
                   9830: 0:             
                   9831:        movl    r$pms,r10       # point to subject string
                   9832:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9833:        movl    r7,psavc        # save initial cursor
                   9834:        movl    r9,psave        # save node pointer
                   9835:                                # set counter for chars left
                   9836: #
                   9837: #      LOOP TO SCAN MATCHING CHARACTERS
                   9838: #
                   9839: pspn2: movzbl  (r10)+,r6       # load next character, bump pointer
                   9840:        moval   0[r6],r6        # convert to byte offset
                   9841:        movl    4*parm1(r9),r9  # point to ctblk
                   9842:        addl2   r6,r9           # point to ctblk entry
                   9843:        movl    4*ctchs(r9),r6  # load ctblk entry
                   9844:        movl    psave,r9        # restore node pointer
                   9845:        mcoml   4*parm2(r9),r11 # and with selected bit
                   9846:        bicl2   r11,r6
                   9847:        beqlu   pspn3           # jump if no match
                   9848:        incl    r7              # else push cursor
                   9849:        sobgtr  r8,pspn2        # loop back unless end of string
                   9850: #
                   9851: #      HERE AFTER SCANNING MATCHING CHARACTERS
                   9852: #
                   9853: pspn3: cmpl    r7,psavc        # succeed if chars matched
                   9854:        beqlu   0f
                   9855:        jmp     succp
                   9856: 0:             
                   9857:        jmp     failp           # else fail if null string matched
                   9858:        #page   
                   9859: #
                   9860: #      SPAN (ONE CHARACTER ARGUMENT)
                   9861: #
                   9862: #      PARM1                 CHARACTER ARGUMENT
                   9863: #
                   9864:        .align  2
                   9865:        .word   bl$p1
                   9866: p$sps:                         # p1blk
                   9867:        movl    pmssl,r8        # get subject string length
                   9868:        subl2   r7,r8           # calculate number of characters left
                   9869:        bnequ   0f              # fail if no characters left
                   9870:        jmp     failp
                   9871: 0:             
                   9872:        movl    r$pms,r10       # else point to subject string
                   9873:        movab   cfp$f(r10)[r7],r10 # point to current character
                   9874:        movl    r7,psavc        # save initial cursor
                   9875:                                # set counter for characters left
                   9876: #
                   9877: #      LOOP TO SCAN MATCHING CHARACTERS
                   9878: #
                   9879: psps1: movzbl  (r10)+,r6       # load next character, bump pointer
                   9880:        cmpl    r6,4*parm1(r9)  # jump if no match
                   9881:        bnequ   psps2
                   9882:        incl    r7              # else push cursor
                   9883:        sobgtr  r8,psps1        # and loop unless end of string
                   9884: #
                   9885: #      HERE AFTER SCANNING MATCHING CHARACTERS
                   9886: #
                   9887: psps2: cmpl    r7,psavc        # succeed if chars matched
                   9888:        beqlu   0f
                   9889:        jmp     succp
                   9890: 0:             
                   9891:        jmp     failp           # fail if null string matched
                   9892:        #page   
                   9893: #
                   9894: #      MULTI-CHARACTER STRING
                   9895: #
                   9896: #      NOTE THAT ONE CHARACTER STRINGS USE THE CIRCUIT FOR
                   9897: #      ONE CHARACTER ANY ARGUMENTS (P$AN1).
                   9898: #
                   9899: #      PARM1                 POINTER TO SCBLK FOR STRING ARG
                   9900: #
                   9901:        .align  2
                   9902:        .word   bl$p1
                   9903: p$str:                         # p1blk
                   9904:        movl    4*parm1(r9),r10 # get pointer to string
                   9905: #
                   9906: #      MERGE HERE AFTER EVALUATING EXPRESSION WITH STRING VALUE
                   9907: #
                   9908: pstr1: movl    r9,psave        # save node pointer
                   9909:        movl    r$pms,r9        # load subject string pointer
                   9910:        movab   cfp$f(r9)[r7],r9# point to current character
                   9911:        addl2   4*sclen(r10),r7 # compute new cursor position
                   9912:        cmpl    r7,pmssl        # fail if past end of string
                   9913:        blequ   0f
                   9914:        jmp     failp
                   9915: 0:             
                   9916:        movl    r7,psavc        # save updated cursor
                   9917:        movl    4*sclen(r10),r6 # get number of chars to compare
                   9918:        movab   cfp$f(r10),r10  # point to chars of test string
                   9919:        jsb     sbcmc           # compare, fail if not equal
                   9920:        .long   failp
                   9921:        .long   failp
                   9922:        movl    psave,r9        # if all matched, restore node ptr
                   9923:        movl    psavc,r7        # restore updated cursor
                   9924:        jmp     succp           # and succeed
                   9925:        #page   
                   9926: #
                   9927: #      SUCCEED
                   9928: #
                   9929: #      SEE SECTION ON COMPOUND PATTERNS FOR DETAILS OF THE
                   9930: #      STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE
                   9931: #
                   9932: #      NO PARAMETERS
                   9933: #
                   9934:        .align  2
                   9935:        .word   bl$p0
                   9936: p$suc:                         # p0blk
                   9937:        movl    r7,-(sp)        # stack cursor
                   9938:        movl    r9,-(sp)        # stack pointer to this node
                   9939:        jmp     succp           # succeed matching null
                   9940:        #page   
                   9941: #
                   9942: #      TAB (INTEGER ARGUMENT)
                   9943: #
                   9944: #      PARM1                 INTEGER ARGUMENT
                   9945: #
                   9946:        .align  2
                   9947:        .word   bl$p1
                   9948: p$tab:                         # p1blk
                   9949: #
                   9950: #      EXPRESSION ARGUMENT CASE MERGES HERE
                   9951: #
                   9952: ptab1: cmpl    r7,4*parm1(r9)  # fail if too far already
                   9953:        blequ   0f
                   9954:        jmp     failp
                   9955: 0:             
                   9956:        movl    4*parm1(r9),r7  # else set new cursor position
                   9957:        cmpl    r7,pmssl        # succeed if not off end
                   9958:        bgtru   0f
                   9959:        jmp     succp
                   9960: 0:             
                   9961:        jmp     failp           # else fail
                   9962:        #page   
                   9963: #
                   9964: #      TAB (EXPRESSION ARGUMENT)
                   9965: #
                   9966: #      PARM1                 EXPRESSION POINTER
                   9967: #
                   9968:        .align  2
                   9969:        .word   bl$p1
                   9970: p$tbd:                         # p1blk
                   9971:        jsb     evali           # evaluate integer argument
                   9972:        .long   er_057          # tab evaluated argument is not integer
                   9973:        .long   er_058          # tab evaluated argument is negative or too large
                   9974:        .long   failp           # fail if evaluation fails
                   9975:        .long   ptab1           # merge with normal case if ok
                   9976:        #page   
                   9977: #
                   9978: #      ANCHOR MOVEMENT
                   9979: #
                   9980: #      NO PARAMETERS (DUMMY NODE)
                   9981: #
                   9982: p$una:                         # entry point
                   9983:        movl    r7,r9           # copy initial pattern node pointer
                   9984:        movl    (sp),r7         # get initial cursor
                   9985:        cmpl    r7,pmssl        # match fails if at end of string
                   9986:        bnequ   0f
                   9987:        jmp     exfal
                   9988: 0:             
                   9989:        incl    r7              # else increment cursor
                   9990:        movl    r7,(sp)         # store incremented cursor
                   9991:        movl    r9,-(sp)        # restack initial node ptr
                   9992:        movl    $nduna,-(sp)    # restack unanchored node
                   9993:        movl    (r9),r11        # rematch first node
                   9994:        jmp     (r11)
                   9995:        #page   
                   9996: #
                   9997: #      END OF PATTERN MATCH ROUTINES
                   9998: #
                   9999: #      THE FOLLOWING ENTRY POINT MARKS THE END OF THE PATTERN
                   10000: #      MATCHING ROUTINES AND ALSO THE END OF THE ENTRY POINTS
                   10001: #      REFERENCED FROM THE FIRST WORD OF BLOCKS IN DYNAMIC STORE
                   10002: #
                   10003:        .align  2
                   10004:        .word   bl$$i
                   10005: p$yyy:                         # mark last entry in pattern section
                   10006:        #title  s p i t b o l -- predefined snobol4 functions
                   10007: #
                   10008: #      THE FOLLOWING SECTION CONTAINS CODING FOR FUNCTIONS
                   10009: #      WHICH ARE PREDEFINED AND AVAILABLE AT THE SNOBOL LEVEL.
                   10010: #
                   10011: #      THESE ROUTINES RECEIVE CONTROL DIRECTLY FROM THE CODE OR
                   10012: #      INDIRECTLY THROUGH THE O$FNC, O$FNS OR CFUNC ROUTINES.
                   10013: #      IN BOTH CASES THE CONDITIONS ON ENTRY ARE AS FOLLOWS
                   10014: #
                   10015: #      THE ARGUMENTS ARE ON THE STACK. THE NUMBER OF ARGUMENTS
                   10016: #      HAS BEEN ADJUSTED TO CORRESPOND TO THE SVBLK SVNAR FIELD.
                   10017: #
                   10018: #      IN CERTAIN FUNCTIONS THE DIRECT CALL IS NOT PERMITTED
                   10019: #      AND IN THESE INSTANCES WE ALSO HAVE.
                   10020: #
                   10021: #      (WA)                  ACTUAL NUMBER OF ARGUMENTS IN CALL
                   10022: #
                   10023: #      CONTROL RETURNS BY PLACING THE FUNCTION RESULT VALUE ON
                   10024: #      ON THE STACK AND CONTINUING EXECUTION WITH THE NEXT
                   10025: #      WORD FROM THE GENERATED CODE.
                   10026: #
                   10027: #      THE NAMES OF THE ENTRY POINTS OF THESE FUNCTIONS ARE OF
                   10028: #      THE FORM S$XXX WHERE XXX IS THE THREE LETTER CODE FOR
                   10029: #      THE SYSTEM VARIABLE NAME. THE FUNCTIONS ARE IN ORDER
                   10030: #      ALPHABETICALLY BY THEIR ENTRY NAMES.
                   10031:        #page   
                   10032: #
                   10033: #      ANY
                   10034: #
                   10035: s$any:                         # entry point
                   10036:        movl    $p$ans,r7       # set pcode for single char case
                   10037:        movl    $p$any,r10      # pcode for multi-char case
                   10038:        movl    $p$ayd,r8       # pcode for expression case
                   10039:        jsb     patst           # call common routine to build node
                   10040:        .long   er_059          # any argument is not string or expression
                   10041:        jmp     exixr           # jump for next code word
                   10042:        #page   
                   10043: #
                   10044: #      APPEND
                   10045: #
                   10046: s$apn:                         # entry point
                   10047:        movl    (sp)+,r10       # get append argument
                   10048:        movl    (sp)+,r9        # get bcblk
                   10049:        cmpl    (r9),$b$bct     # ok if first arg is bcblk
                   10050:        beqlu   sapn1
                   10051:        jmp     er_275          # append first argument is not buffer
                   10052: #
                   10053: #      HERE TO DO THE APPEND
                   10054: #
                   10055: sapn1: jsb     apndb           # do the append
                   10056:        .long   er_276          # append second argument is not string
                   10057:        .long   exfal           # no room - fail
                   10058:        jmp     exnul           # exit with null result
                   10059:        #page   
                   10060: #
                   10061: #      APPLY
                   10062: #
                   10063: #      APPLY DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT
                   10064: #      WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED.
                   10065: #
                   10066: s$app:                         # entry point
                   10067:        tstl    r6              # jump if no arguments
                   10068:        beqlu   sapp3
                   10069:        decl    r6              # else get applied func arg count
                   10070:        movl    r6,r7           # copy
                   10071:        moval   0[r7],r7        # convert to bytes
                   10072:        movl    sp,r10          # copy stack pointer
                   10073:        addl2   r7,r10          # point to function argument on stack
                   10074:        movl    (r10),r9        # load function ptr (apply 1st arg)
                   10075:        tstl    r6              # jump if no args for applied func
                   10076:        beqlu   sapp2
                   10077:        movl    r6,r7           # else set counter for loop
                   10078: #
                   10079: #      LOOP TO MOVE ARGUMENTS UP ON STACK
                   10080: #
                   10081: sapp1: subl2   $4,r10          # point to next argument
                   10082:        movl    (r10),4*1(r10)  # move argument up
                   10083:        sobgtr  r7,sapp1        # loop till all moved
                   10084: #
                   10085: #      MERGE HERE TO CALL FUNCTION (WA = NUMBER OF ARGUMENTS)
                   10086: #
                   10087: sapp2: addl2   $4,sp           # adjust stack ptr for apply 1st arg
                   10088:        jsb     gtnvr           # get variable block addr for func
                   10089:        .long   sapp3           # jump if not natural variable
                   10090:        movl    4*vrfnc(r9),r10 # else point to function block
                   10091:        jmp     cfunc           # go call applied function
                   10092: #
                   10093: #      HERE FOR INVALID FIRST ARGUMENT
                   10094: #
                   10095: sapp3: jmp     er_060          # apply first arg is not natural variable name
                   10096:        #page   
                   10097: #
                   10098: #      ARBNO
                   10099: #
                   10100: #      ARBNO BUILDS A COMPOUND PATTERN. SEE DESCRIPTION AT
                   10101: #      START OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED.
                   10102: #
                   10103: s$abn:                         # entry point
                   10104:        clrl    r9              # set parm1 = 0 for the moment
                   10105:        movl    $p$alt,r7       # set pcode for alternative node
                   10106:        jsb     pbild           # build alternative node
                   10107:        movl    r9,r10          # save ptr to alternative pattern
                   10108:        movl    $p$abc,r7       # pcode for p$abc
                   10109:        clrl    r9              # p0blk
                   10110:        jsb     pbild           # build p$abc node
                   10111:        movl    r10,4*pthen(r9) # put alternative node as successor
                   10112:        movl    r10,r6          # remember alternative node pointer
                   10113:        movl    r9,r10          # copy p$abc node ptr
                   10114:        movl    (sp),r9         # load arbno argument
                   10115:        movl    r6,(sp)         # stack alternative node pointer
                   10116:        jsb     gtpat           # get arbno argument as pattern
                   10117:        .long   er_061          # arbno argument is not pattern
                   10118:        jsb     pconc           # concat arg with p$abc node
                   10119:        movl    r9,r10          # remember ptr to concd patterns
                   10120:        movl    $p$aba,r7       # pcode for p$aba
                   10121:        clrl    r9              # p0blk
                   10122:        jsb     pbild           # build p$aba node
                   10123:        movl    r10,4*pthen(r9) # concatenate nodes
                   10124:        movl    (sp),r10        # recall ptr to alternative node
                   10125:        movl    r9,4*parm1(r10) # point alternative back to argument
                   10126:        jmp     exits           # jump for next code word
                   10127:        #page   
                   10128: #
                   10129: #      ARG
                   10130: #
                   10131: s$arg:                         # entry point
                   10132:        jsb     gtsmi           # get second arg as small integer
                   10133:        .long   er_062          # arg second argument is not integer
                   10134:        .long   exfal           # fail if out of range or negative
                   10135:        movl    r9,r6           # save argument number
                   10136:        movl    (sp)+,r9        # load first argument
                   10137:        jsb     gtnvr           # locate vrblk
                   10138:        .long   sarg1           # jump if not natural variable
                   10139:        movl    4*vrfnc(r9),r9  # else load function block pointer
                   10140:        cmpl    (r9),$b$pfc     # jump if not program defined
                   10141:        bnequ   sarg1
                   10142:        tstl    r6              # fail if arg number is zero
                   10143:        bnequ   0f
                   10144:        jmp     exfal
                   10145: 0:             
                   10146:        cmpl    r6,4*fargs(r9)  # fail if arg number is too large
                   10147:        blequ   0f
                   10148:        jmp     exfal
                   10149: 0:             
                   10150:        moval   0[r6],r6        # else convert to byte offset
                   10151:        addl2   r6,r9           # point to argument selected
                   10152:        movl    4*pfagb(r9),r9  # load argument vrblk pointer
                   10153:        jmp     exvnm           # exit to build nmblk
                   10154: #
                   10155: #      HERE IF 1ST ARGUMENT IS BAD
                   10156: #
                   10157: sarg1: jmp     er_063          # arg first argument is not program function name
                   10158:        #page   
                   10159: #
                   10160: #      ARRAY
                   10161: #
                   10162: s$arr:                         # entry point
                   10163:        movl    (sp)+,r10       # load initial element value
                   10164:        movl    (sp)+,r9        # load first argument
                   10165:        jsb     gtint           # convert first arg to integer
                   10166:        .long   sar02           # jump if not integer
                   10167: #
                   10168: #      HERE FOR INTEGER FIRST ARGUMENT, BUILD VCBLK
                   10169: #
                   10170:        movl    4*icval(r9),r5  # load integer value
                   10171:        bgtr    0f              # jump if zero or neg (bad dimension)
                   10172:        jmp     sar10
                   10173: 0:             
                   10174:        movl    r5,r6           # else convert to one word, test ovfl
                   10175:        bgeq    0f
                   10176:        jmp     sar11
                   10177: 0:             
                   10178:        movl    r6,r7           # copy elements for loop later on
                   10179:        addl2   $vcsi$,r6       # add space for standard fields
                   10180:        moval   0[r6],r6        # convert length to bytes
                   10181:        cmpl    r6,mxlen        # fail if too large
                   10182:        blssu   0f
                   10183:        jmp     sar11
                   10184: 0:             
                   10185:        jsb     alloc           # allocate space for vcblk
                   10186:        movl    $b$vct,(r9)     # store type word
                   10187:        movl    r6,4*vclen(r9)  # set length
                   10188:        movl    r10,r8          # copy default value
                   10189:        movl    r9,r10          # copy vcblk pointer
                   10190:        addl2   $4*vcvls,r10    # point to first element value
                   10191: #
                   10192: #      LOOP TO SET VECTOR ELEMENTS TO DEFAULT VALUE
                   10193: #
                   10194: sar01: movl    r8,(r10)+       # store one value
                   10195:        sobgtr  r7,sar01        # loop till all stored
                   10196:        jmp     exsid           # exit setting idval
                   10197:        #page   
                   10198: #
                   10199: #      ARRAY (CONTINUED)
                   10200: #
                   10201: #      HERE IF FIRST ARGUMENT IS NOT AN INTEGER
                   10202: #
                   10203: sar02: movl    r9,-(sp)        # replace argument on stack
                   10204:        jsb     xscni           # initialize scan of first argument
                   10205:        .long   er_064          # array first argument is not integer or string
                   10206:        .long   exnul           # dummy (unused) null string exit
                   10207:        movl    r$xsc,-(sp)     # save prototype pointer
                   10208:        movl    r10,-(sp)       # save default value
                   10209:        clrl    arcdm           # zero count of dimensions
                   10210:        clrl    arptr           # zero offset to indicate pass one
                   10211:        movl    intv1,r5        # load integer one
                   10212:        movl    r5,arnel        # initialize element count
                   10213: #
                   10214: #      THE FOLLOWING CODE IS EXECUTED TWICE. THE FIRST TIME
                   10215: #      (ARPTR EQ 0), IT IS USED TO COUNT THE NUMBER OF ELEMENTS
                   10216: #      AND NUMBER OF DIMENSIONS. THE SECOND TIME (ARPTR GT 0) IS
                   10217: #      USED TO ACTUALLY FILL IN THE DIM,LBD FIELDS OF THE ARBLK.
                   10218: #
                   10219: sar03: movl    intv1,r5        # load one as default low bound
                   10220:        movl    r5,arsvl        # save as low bound
                   10221:        movl    $ch$cl,r8       # set delimiter one = colon
                   10222:        movl    $ch$cm,r10      # set delimiter two = comma
                   10223:        jsb     xscan           # scan next bound
                   10224:        cmpl    r6,$num01       # jump if not colon
                   10225:        bnequ   sar04
                   10226: #
                   10227: #      HERE WE HAVE A COLON ENDING A LOW BOUND
                   10228: #
                   10229:        jsb     gtint           # convert low bound
                   10230:        .long   er_065          # array first argument lower bound is not integer
                   10231:        movl    4*icval(r9),r5  # load value of low bound
                   10232:        movl    r5,arsvl        # store low bound value
                   10233:        movl    $ch$cm,r8       # set delimiter one = comma
                   10234:        movl    r8,r10          # and delimiter two = comma
                   10235:        jsb     xscan           # scan high bound
                   10236:        #page   
                   10237: #
                   10238: #      ARRAY (CONTINUED)
                   10239: #
                   10240: #      MERGE HERE TO PROCESS UPPER BOUND
                   10241: #
                   10242: sar04: jsb     gtint           # convert high bound to integer
                   10243:        .long   er_066          # array first argument upper bound is not integer
                   10244:        movl    4*icval(r9),r5  # get high bound
                   10245:        subl2   arsvl,r5        # subtract lower bound
                   10246:        bvc     0f
                   10247:        jmp     sar10
                   10248: 0:             
                   10249:        tstl    r5              # bad dimension if negative
                   10250:        bgeq    0f
                   10251:        jmp     sar10
                   10252: 0:             
                   10253:        addl2   intv1,r5        # add 1 to get dimension
                   10254:        bvc     0f
                   10255:        jmp     sar10
                   10256: 0:             
                   10257:        movl    arptr,r10       # load offset (also pass indicator)
                   10258:        beqlu   sar05           # jump if first pass
                   10259: #
                   10260: #      HERE IN SECOND PASS TO STORE LBD AND DIM IN ARBLK
                   10261: #
                   10262:        addl2   (sp),r10        # point to current location in arblk
                   10263:        movl    r5,4*cfp$i(r10) # store dimension
                   10264:        movl    arsvl,r5        # load low bound
                   10265:        movl    r5,(r10)        # store low bound
                   10266:        addl2   $4*ardms,arptr  # bump offset to next bounds
                   10267:        jmp     sar06           # jump to check for end of bounds
                   10268: #
                   10269: #      HERE IN PASS 1
                   10270: #
                   10271: sar05: incl    arcdm           # bump dimension count
                   10272:        mull2   arnel,r5        # multiply dimension by count so far
                   10273:        bvc     0f
                   10274:        jmp     sar11
                   10275: 0:             
                   10276:        movl    r5,arnel        # else store updated element count
                   10277: #
                   10278: #      MERGE HERE AFTER PROCESSING ONE SET OF BOUNDS
                   10279: #
                   10280: sar06: tstl    r6              # loop back unless end of bounds
                   10281:        beqlu   0f
                   10282:        jmp     sar03
                   10283: 0:             
                   10284:        tstl    arptr           # jump if end of pass 2
                   10285:        beqlu   0f
                   10286:        jmp     sar09
                   10287: 0:             
                   10288:        #page   
                   10289: #
                   10290: #      ARRAY (CONTINUED)
                   10291: #
                   10292: #      HERE AT END OF PASS ONE, BUILD ARBLK
                   10293: #
                   10294:        movl    arnel,r5        # get number of elements
                   10295:        movl    r5,r7           # get as addr integer, test ovflo
                   10296:        bgeq    0f
                   10297:        jmp     sar11
                   10298: 0:             
                   10299:        moval   0[r7],r7        # else convert to length in bytes
                   10300:        movl    $4*arsi$,r6     # set size of standard fields
                   10301:        movl    arcdm,r8        # set dimension count to control loop
                   10302: #
                   10303: #      LOOP TO ALLOW SPACE FOR DIMENSIONS
                   10304: #
                   10305: sar07: addl2   $4*ardms,r6     # allow space for one set of bounds
                   10306:        sobgtr  r8,sar07        # loop back till all accounted for
                   10307:        movl    r6,r10          # save size (=arofs)
                   10308: #
                   10309: #      NOW ALLOCATE SPACE FOR ARBLK
                   10310: #
                   10311:        addl2   r7,r6           # add space for elements
                   10312:        addl2   $4,r6           # allow for arpro prototype field
                   10313:        cmpl    r6,mxlen        # fail if too large
                   10314:        blssu   0f
                   10315:        jmp     sar11
                   10316: 0:             
                   10317:        jsb     alloc           # else allocate arblk
                   10318:        movl    (sp),r7         # load default value
                   10319:        movl    r9,(sp)         # save arblk pointer
                   10320:        movl    r6,r8           # save length in bytes
                   10321:        ashl    $-2,r6,r6       # convert length back to words
                   10322:                                # set counter to control loop
                   10323: #
                   10324: #      LOOP TO CLEAR ENTIRE ARBLK TO DEFAULT VALUE
                   10325: #
                   10326: sar08: movl    r7,(r9)+        # set one word
                   10327:        sobgtr  r6,sar08        # loop till all set
                   10328:        #page   
                   10329: #
                   10330: #      ARRAY (CONTINUED)
                   10331: #
                   10332: #      NOW SET INITIAL FIELDS OF ARBLK
                   10333: #
                   10334:        movl    (sp)+,r9        # reload arblk pointer
                   10335:        movl    (sp),r7         # load prototype
                   10336:        movl    $b$art,(r9)     # set type word
                   10337:        movl    r8,4*arlen(r9)  # store length in bytes
                   10338:        clrl    4*idval(r9)     # zero id till we get it built
                   10339:        movl    r10,4*arofs(r9) # set prototype field ptr
                   10340:        movl    arcdm,4*arndm(r9)# set number of dimensions
                   10341:        movl    r9,r8           # save arblk pointer
                   10342:        addl2   r10,r9          # point to prototype field
                   10343:        movl    r7,(r9)         # store prototype ptr in arblk
                   10344:        movl    $4*arlbd,arptr  # set offset for pass 2 bounds scan
                   10345:        movl    r7,r$xsc        # reset string pointer for xscan
                   10346:        movl    r8,(sp)         # store arblk pointer on stack
                   10347:        clrl    xsofs           # reset offset ptr to start of string
                   10348:        jmp     sar03           # jump back to rescan bounds
                   10349: #
                   10350: #      HERE AFTER FILLING IN BOUNDS INFORMATION (END PASS TWO)
                   10351: #
                   10352: sar09: movl    (sp)+,r9        # reload pointer to arblk
                   10353:        jmp     exsid           # exit setting idval
                   10354: #
                   10355: #      HERE FOR BAD DIMENSION
                   10356: #
                   10357: sar10: jmp     er_067          # array dimension is zero,negative or out of range
                   10358: #
                   10359: #      HERE IF ARRAY IS TOO LARGE
                   10360: #
                   10361: sar11: jmp     er_068          # array size exceeds maximum permitted
                   10362:        #page   
                   10363: #
                   10364: #      BUFFER
                   10365: #
                   10366: s$buf:                         # entry point
                   10367:        movl    (sp)+,r10       # get initial value
                   10368:        movl    (sp)+,r9        # get requested allocation
                   10369:        jsb     gtint           # convert to integer
                   10370:        .long   er_269          # buffer first argument is not integer
                   10371:        movl    4*icval(r9),r5  # get value
                   10372:        bleq    sbf01           # branch if negative or zero
                   10373:        movl    r5,r6           # move with overflow check
                   10374:        bgeq    0f
                   10375:        jmp     sbf02
                   10376: 0:             
                   10377:        jsb     alobf           # allocate the buffer
                   10378:        jsb     apndb           # copy it in
                   10379:        .long   er_270          # buffer second argument is not string or buffer
                   10380:        .long   er_271          # buffer initial value too big for allocation
                   10381:        jmp     exsid           # exit setting idval
                   10382: #
                   10383: #      HERE FOR INVALID ALLOCATION SIZE
                   10384: #
                   10385: sbf01: jmp     er_272          # buffer first argument is not positive
                   10386: #
                   10387: #      HERE FOR ALLOCATION SIZE INTEGER OVERFLOW
                   10388: #
                   10389: sbf02: jmp     er_273          # buffer size is too big
                   10390:        #page   
                   10391: #
                   10392: #      BREAK
                   10393: #
                   10394: s$brk:                         # entry point
                   10395:        movl    $p$bks,r7       # set pcode for single char case
                   10396:        movl    $p$brk,r10      # pcode for multi-char case
                   10397:        movl    $p$bkd,r8       # pcode for expression case
                   10398:        jsb     patst           # call common routine to build node
                   10399:        .long   er_069          # break argument is not string or expression
                   10400:        jmp     exixr           # jump for next code word
                   10401:        #page   
                   10402: #
                   10403: #      BREAKX
                   10404: #
                   10405: #      BREAKX IS A COMPOUND PATTERN. SEE DESCRIPTION AT START
                   10406: #      OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED.
                   10407: #
                   10408: s$bkx:                         # entry point
                   10409:        movl    $p$bks,r7       # pcode for single char argument
                   10410:        movl    $p$brk,r10      # pcode for multi-char argument
                   10411:        movl    $p$bxd,r8       # pcode for expression case
                   10412:        jsb     patst           # call common routine to build node
                   10413:        .long   er_070          # breakx argument is not string or expression
                   10414: #
                   10415: #      NOW HOOK BREAKX NODE ON AT FRONT END
                   10416: #
                   10417:        movl    r9,-(sp)        # save ptr to break node
                   10418:        movl    $p$bkx,r7       # set pcode for breakx node
                   10419:        jsb     pbild           # build it
                   10420:        movl    (sp),4*pthen(r9)# set break node as successor
                   10421:        movl    $p$alt,r7       # set pcode for alternation node
                   10422:        jsb     pbild           # build (parm1=alt=breakx node)
                   10423:        movl    r9,r6           # save ptr to alternation node
                   10424:        movl    (sp),r9         # point to break node
                   10425:        movl    r6,4*pthen(r9)  # set alternate node as successor
                   10426:        jmp     exits           # exit with result on stack
                   10427:        #page   
                   10428: #
                   10429: #      CHAR
                   10430: #
                   10431: s$chr:                         # entry point
                   10432:        jsb     gtsmi           # convert arg to integer
                   10433:        .long   er_281          # char argument not integer
                   10434:        .long   schr1           # too big error exit
                   10435:        cmpl    r8,$cfp$a       # see if out of range of host set
                   10436:        bgequ   schr1
                   10437:        movl    $num01,r6       # if not set scblk allocation
                   10438:        movl    r8,r7           # save char code
                   10439:        jsb     alocs           # allocate 1 bau scblk
                   10440:        movl    r9,r10          # copy scblk pointer
                   10441:        movab   cfp$f(r10),r10  # get set to stuff char
                   10442:        movb    r7,(r10)+       # stuff it
                   10443:        clrl    r10             # clear slop in xl
                   10444:        jmp     exixr           # exit with scblk pointer
                   10445: #
                   10446: #      HERE IF CHAR ARGUMENT IS OUT OF RANGE
                   10447: #
                   10448: schr1: jmp     er_282          # char argument not in range
                   10449:        #page   
                   10450: #
                   10451: #      CLEAR
                   10452: #
                   10453: s$clr:                         # entry point
                   10454:        jsb     xscni           # initialize to scan argument
                   10455:        .long   er_071          # clear argument is not string
                   10456:        .long   sclr2           # jump if null
                   10457: #
                   10458: #      LOOP TO SCAN OUT NAMES IN FIRST ARGUMENT. VARIABLES IN
                   10459: #      THE LIST ARE FALGGED BY SETTING VRGET OF VRBLK TO ZERO.
                   10460: #
                   10461: sclr1: movl    $ch$cm,r8       # set delimiter one = comma
                   10462:        movl    r8,r10          # delimiter two = comma
                   10463:        jsb     xscan           # scan next variable name
                   10464:        jsb     gtnvr           # locate vrblk
                   10465:        .long   er_072          # clear argument has null variable name
                   10466:        clrl    4*vrget(r9)     # else flag by zeroing vrget field
                   10467:        tstl    r6              # loop back if stopped by comma
                   10468:        bnequ   sclr1
                   10469: #
                   10470: #      HERE AFTER FLAGGING VARIABLES IN ARGUMENT LIST
                   10471: #
                   10472: sclr2: movl    hshtb,r7        # point to start of hash table
                   10473: #
                   10474: #      LOOP THROUGH SLOTS IN HASH TABLE
                   10475: #
                   10476: sclr3: cmpl    r7,hshte        # exit returning null if none left
                   10477:        bnequ   0f
                   10478:        jmp     exnul
                   10479: 0:             
                   10480:        movl    r7,r9           # else copy slot pointer
                   10481:        addl2   $4,r7           # bump slot pointer
                   10482:        subl2   $4*vrnxt,r9     # set offset to merge into loop
                   10483: #
                   10484: #      LOOP THROUGH VRBLKS ON ONE HASH CHAIN
                   10485: #
                   10486: sclr4: movl    4*vrnxt(r9),r9  # point to next vrblk on chain
                   10487:        beqlu   sclr3           # jump for next bucket if chain end
                   10488:        tstl    4*vrget(r9)     # jump if not flagged
                   10489:        bnequ   sclr5
                   10490:        #page   
                   10491: #
                   10492: #      CLEAR (CONTINUED)
                   10493: #
                   10494: #      HERE FOR FLAGGED VARIABLE, DO NOT SET VALUE TO NULL
                   10495: #
                   10496:        jsb     setvr           # for flagged var, restore vrget
                   10497:        jmp     sclr4           # and loop back for next vrblk
                   10498: #
                   10499: #      HERE TO SET VALUE OF A VARIABLE TO NULL
                   10500: #      PRROTECTED VARIABLES (ARB, ETC) ARE EXEMPT
                   10501: #
                   10502: sclr5: cmpl    4*vrsto(r9),$b$vre # check for protected variable (reg05)
                   10503:        beqlu   sclr4
                   10504:        movl    r9,r10          # copy vrblk pointer (reg05)
                   10505: #
                   10506: #      LOOP TO LOCATE VALUE AT END OF POSSIBLE TRBLK CHAIN
                   10507: #
                   10508: sclr6: movl    r10,r6          # save block pointer
                   10509:        movl    4*vrval(r10),r10# load next value field
                   10510:        cmpl    (r10),$b$trt    # loop back if trapped
                   10511:        beqlu   sclr6
                   10512: #
                   10513: #      NOW STORE THE NULL VALUE
                   10514: #
                   10515:        movl    r6,r10          # restore block pointer
                   10516:        movl    $nulls,4*vrval(r10) # store null constant value
                   10517:        jmp     sclr4           # loop back for next vrblk
                   10518:        #page   
                   10519: #
                   10520: #      CODE
                   10521: #
                   10522: s$cod:                         # entry point
                   10523:        movl    (sp)+,r9        # load argument
                   10524:        jsb     gtcod           # convert to code
                   10525:        .long   exfal           # fail if conversion is impossible
                   10526:        jmp     exixr           # else return code as result
                   10527:        #page   
                   10528: #
                   10529: #      COLLECT
                   10530: #
                   10531: s$col:                         # entry point
                   10532:        movl    (sp)+,r9        # load argument
                   10533:        jsb     gtint           # convert to integer
                   10534:        .long   er_073          # collect argument is not integer
                   10535:        movl    4*icval(r9),r5  # load collect argument
                   10536:        movl    r5,clsvi        # save collect argument
                   10537:        clrl    r7              # set no move up
                   10538:        jsb     gbcol           # perform garbage collection
                   10539:        movl    dname,r6        # point to end of memory
                   10540:        subl2   dnamp,r6        # subtract next location
                   10541:        ashl    $-2,r6,r6       # convert bytes to words
                   10542:        movl    r6,r5           # convert words available as integer
                   10543:        subl2   clsvi,r5        # subtract argument
                   10544:        bvc     0f
                   10545:        jmp     exfal
                   10546: 0:             
                   10547:        tstl    r5              # fail if not enough
                   10548:        bgeq    0f
                   10549:        jmp     exfal
                   10550: 0:             
                   10551:        addl2   clsvi,r5        # else recompute available
                   10552:        jmp     exint           # and exit with integer result
                   10553:        #page   
                   10554: #
                   10555: #      CONVERT
                   10556: #
                   10557: s$cnv:                         # entry point
                   10558:        jsb     gtstg           # convert second argument to string
                   10559:        .long   er_074          # convert second argument is not string
                   10560:        jsb     flstg           # fold lower case to upper case
                   10561:        movl    (sp),r10        # load first argument
                   10562:        cmpl    (r10),$b$pdt    # jump if not program defined
                   10563:        bnequ   scv01
                   10564: #
                   10565: #      HERE FOR PROGRAM DEFINED DATATYPE
                   10566: #
                   10567:        movl    4*pddfp(r10),r10# point to dfblk
                   10568:        movl    4*dfnam(r10),r10# load datatype name
                   10569:        jsb     ident           # compare with second arg
                   10570:        .long   exits           # exit if ident with arg as result
                   10571:        jmp     exfal           # else fail
                   10572: #
                   10573: #      HERE IF NOT PROGRAM DEFINED DATATYPE
                   10574: #
                   10575: scv01: movl    r9,-(sp)        # save string argument
                   10576:        movl    $svctb,r10      # point to table of names to compare
                   10577:        clrl    r7              # initialize counter
                   10578:        movl    r6,r8           # save length of argument string
                   10579: #
                   10580: #      LOOP THROUGH TABLE ENTRIES
                   10581: #
                   10582: scv02: movl    (r10)+,r9       # load next table entry, bump pointer
                   10583:        bnequ   0f              # fail if zero marking end of list
                   10584:        jmp     exfal
                   10585: 0:             
                   10586:        cmpl    r8,4*sclen(r9)  # jump if wrong length
                   10587:        beqlu   0f
                   10588:        jmp     scv05
                   10589: 0:             
                   10590:        movl    r10,cnvtp       # else store table pointer
                   10591:        movab   cfp$f(r9),r9    # point to chars of table entry
                   10592:        movl    (sp),r10        # load pointer to string argument
                   10593:        movab   cfp$f(r10),r10  # point to chars of string arg
                   10594:        movl    r8,r6           # set number of chars to compare
                   10595:        jsb     sbcmc           # compare, jump if no match
                   10596:        .long   scv04
                   10597:        .long   scv04
                   10598:        #page   
                   10599: #
                   10600: #      CONVERT (CONTINUED)
                   10601: #
                   10602: #      HERE WE HAVE A MATCH
                   10603: #
                   10604: scv03: movl    r7,r10          # copy entry number
                   10605:        addl2   $4,sp           # pop string arg off stack
                   10606:        movl    (sp)+,r9        # load first argument
                   10607:        casel   r10,$0,$cnvtt   # jump to appropriate routine
                   10608: 5:             
                   10609:        .word   scv06-5b        # string
                   10610:        .word   scv07-5b        # integer
                   10611:        .word   scv09-5b        # name
                   10612:        .word   scv10-5b        # pattern
                   10613:        .word   scv11-5b        # array
                   10614:        .word   scv19-5b        # table
                   10615:        .word   scv25-5b        # expression
                   10616:        .word   scv26-5b        # code
                   10617:        .word   scv27-5b        # numeric
                   10618:        .word   scv08-5b        # real
                   10619:        .word   scv28-5b        # buffer
                   10620:        #esw                    # end of switch table
                   10621: #
                   10622: #      HERE IF NO MATCH WITH TABLE ENTRY
                   10623: #
                   10624: scv04: movl    cnvtp,r10       # restore table pointer, merge
                   10625: #
                   10626: #      MERGE HERE IF LENGTHS DID NOT MATCH
                   10627: #
                   10628: scv05: incl    r7              # bump entry number
                   10629:        jmp     scv02           # loop back to check next entry
                   10630: #
                   10631: #      HERE TO CONVERT TO STRING
                   10632: #
                   10633: scv06: movl    r9,-(sp)        # replace string argument on stack
                   10634:        jsb     gtstg           # convert to string
                   10635:        .long   exfal           # fail if conversion not possible
                   10636:        jmp     exixr           # else return string
                   10637:        #page   
                   10638: #
                   10639: #      CONVERT (CONTINUED)
                   10640: #
                   10641: #      HERE TO CONVERT TO INTEGER
                   10642: #
                   10643: scv07: jsb     gtint           # convert to integer
                   10644:        .long   exfal           # fail if conversion not possible
                   10645:        jmp     exixr           # else return integer
                   10646: #
                   10647: #      HERE TO CONVERT TO REAL
                   10648: #
                   10649: scv08: jsb     gtrea           # convert to real
                   10650:        .long   exfal           # fail if conversion not possible
                   10651:        jmp     exixr           # else return real
                   10652: #
                   10653: #      HERE TO CONVERT TO NAME
                   10654: #
                   10655: scv09: cmpl    (r9),$b$nml     # return if already a name
                   10656:        bnequ   0f
                   10657:        jmp     exixr
                   10658: 0:             
                   10659:        jsb     gtnvr           # else try string to name convert
                   10660:        .long   exfal           # fail if conversion not possible
                   10661:        jmp     exvnm           # else exit building nmblk for vrblk
                   10662: #
                   10663: #      HERE TO CONVERT TO PATTERN
                   10664: #
                   10665: scv10: jsb     gtpat           # convert to pattern
                   10666:        .long   exfal           # fail if conversion not possible
                   10667:        jmp     exixr           # else return pattern
                   10668: #
                   10669: #      CONVERT TO ARRAY
                   10670: #
                   10671: scv11: jsb     gtarr           # get an array
                   10672:        .long   exfal           # fail if not convertible
                   10673:        jmp     exsid           # exit setting id field
                   10674: #
                   10675: #      CONVERT TO TABLE
                   10676: #
                   10677: scv19: movl    (r9),r6         # load first word of block
                   10678:        movl    r9,-(sp)        # replace arblk pointer on stack
                   10679:        cmpl    r6,$b$tbt       # return arg if already a table
                   10680:        bnequ   0f
                   10681:        jmp     exits
                   10682: 0:             
                   10683:        cmpl    r6,$b$art       # else fail if not an array
                   10684:        beqlu   0f
                   10685:        jmp     exfal
                   10686: 0:             
                   10687:        #page   
                   10688: #
                   10689: #      CONVERT (CONTINUED)
                   10690: #
                   10691: #      HERE TO CONVERT AN ARRAY TO TABLE
                   10692: #
                   10693:        cmpl    4*arndm(r9),$num02 # fail if not 2-dim array
                   10694:        beqlu   0f
                   10695:        jmp     exfal
                   10696: 0:             
                   10697:        movl    4*ardm2(r9),r5  # load dim 2
                   10698:        subl2   intv2,r5        # subtract 2 to compare
                   10699:        beql    0f              # fail if dim2 not 2
                   10700:        jmp     exfal
                   10701: 0:             
                   10702: #
                   10703: #      HERE WE HAVE AN ARBLK OF THE RIGHT SHAPE
                   10704: #
                   10705:        movl    4*ardim(r9),r5  # load dim 1 (number of elements)
                   10706:        movl    r5,r6           # get as one word integer
                   10707:        movl    r6,r7           # copy to control loop
                   10708:        addl2   $tbsi$,r6       # add space for standard fields
                   10709:        moval   0[r6],r6        # convert length to bytes
                   10710:        jsb     alloc           # allocate space for tbblk
                   10711:        movl    r9,r8           # copy tbblk pointer
                   10712:        movl    r9,-(sp)        # save tbblk pointer
                   10713:        movl    $b$tbt,(r9)+    # store type word
                   10714:        clrl    (r9)+           # store zero for idval for now
                   10715:        movl    r6,(r9)+        # store length
                   10716:        movl    $nulls,(r9)+    # null initial lookup value
                   10717: #
                   10718: #      LOOP TO INITIALIZE BUCKET PTRS TO POINT TO TABLE
                   10719: #
                   10720: scv20: movl    r8,(r9)+        # set bucket ptr to point to tbblk
                   10721:        sobgtr  r7,scv20        # loop till all initialized
                   10722:        movl    $4*arvl2,r7     # set offset to first arblk element
                   10723: #
                   10724: #      LOOP TO COPY ELEMENTS FROM ARRAY TO TABLE
                   10725: #
                   10726: scv21: movl    4*1(sp),r10     # point to arblk
                   10727:        cmpl    r7,4*arlen(r10) # jump if all moved
                   10728:        beqlu   scv24
                   10729:        addl2   r7,r10          # else point to current location
                   10730:        addl2   $4*num02,r7     # bump offset
                   10731:        movl    (r10),r9        # load subscript name
                   10732:        subl2   $4,r10          # adjust ptr to merge (trval=1+1)
                   10733:        #page   
                   10734: #
                   10735: #      CONVERT (CONTINUED)
                   10736: #
                   10737: #      LOOP TO CHASE DOWN TRBLK CHAIN FOR VALUE
                   10738: #
                   10739: scv22: movl    4*trval(r10),r10# point to next value
                   10740:        cmpl    (r10),$b$trt    # loop back if trapped
                   10741:        beqlu   scv22
                   10742: #
                   10743: #      HERE WITH NAME IN XR, VALUE IN XL
                   10744: #
                   10745: scv23: movl    r10,-(sp)       # stack value
                   10746:        movl    4*1(sp),r10     # load tbblk pointer
                   10747:        jsb     tfind           # build teblk (note wb gt 0 by name)
                   10748:        .long   exfal           # fail if acess fails
                   10749:        movl    (sp)+,4*teval(r10) # store value in teblk
                   10750:        jmp     scv21           # loop back for next element
                   10751: #
                   10752: #      HERE AFTER MOVING ALL ELEMENTS TO TBBLK
                   10753: #
                   10754: scv24: movl    (sp)+,r9        # load tbblk pointer
                   10755:        addl2   $4,sp           # pop arblk pointer
                   10756:        jmp     exsid           # exit setting idval
                   10757: #
                   10758: #      CONVERT TO EXPRESSION
                   10759: #
                   10760: scv25: jsb     gtexp           # convert to expression
                   10761:        .long   exfal           # fail if conversion not possible
                   10762:        jmp     exixr           # else return expression
                   10763: #
                   10764: #      CONVERT TO CODE
                   10765: #
                   10766: scv26: jsb     gtcod           # convert to code
                   10767:        .long   exfal           # fail if conversion is not possible
                   10768:        jmp     exixr           # else return code
                   10769: #
                   10770: #      CONVERT TO NUMERIC
                   10771: #
                   10772: scv27: jsb     gtnum           # convert to numeric
                   10773:        .long   exfal           # fail if unconvertible
                   10774:        jmp     exixr           # return number
                   10775:        #page   
                   10776: #
                   10777: #      CONVERT TO BUFFER
                   10778: #
                   10779: scv28: movl    r9,-(sp)        # stack string for procedure
                   10780:        jsb     gtstg           # convert to string
                   10781:        .long   exfal           # fail if conversion not possible
                   10782:        movl    r9,r10          # save string pointer
                   10783:        jsb     alobf           # allocate buffer of same size
                   10784:        jsb     apndb           # copy in the string
                   10785:        .long   invalid$        # already string - cant fail to cnv
                   10786:        .long   invalid$        # must be enough room
                   10787:        jmp     exsid           # exit setting idval field
                   10788:        #page   
                   10789: #
                   10790: #      COPY
                   10791: #
                   10792: s$cop:                         # entry point
                   10793:        jsb     copyb           # copy the block
                   10794:        .long   exits           # return if no idval field
                   10795:        jmp     exsid           # exit setting id value
                   10796:        #page   
                   10797: #
                   10798: #      DATA
                   10799: #
                   10800: s$dat:                         # entry point
                   10801:        jsb     xscni           # prepare to scan argument
                   10802:        .long   er_075          # data argument is not string
                   10803:        .long   er_076          # data argument is null
                   10804: #
                   10805: #      SCAN OUT DATATYPE NAME
                   10806: #
                   10807:        movl    $ch$pp,r8       # delimiter one = left paren
                   10808:        movl    r8,r10          # delimiter two = left paren
                   10809:        jsb     xscan           # scan datatype name
                   10810:        tstl    r6              # skip if left paren found
                   10811:        bnequ   sdat1
                   10812:        jmp     er_077          # data argument is missing a left paren
                   10813: #
                   10814: #      HERE AFTER SCANNING DATATYPE NAME
                   10815: #
                   10816: sdat1: movl    4*sclen(r9),r6  # get length
                   10817:        jsb     flstg           # fold lower case to upper case
                   10818:        movl    r9,r10          # save name ptr
                   10819:        movl    4*sclen(r9),r6  # get length
                   10820:        movab   3+(4*scsi$)(r6),r6 # compute space needed
                   10821:        bicl2   $3,r6
                   10822:        jsb     alost           # request static store for name
                   10823:        movl    r9,-(sp)        # save datatype name
                   10824:        jsb     sbmvw           # copy name to static
                   10825:        movl    (sp),r9         # get name ptr
                   10826:        clrl    r10             # scrub dud register
                   10827:        jsb     gtnvr           # locate vrblk for datatype name
                   10828:        .long   er_078          # data argument has null datatype name
                   10829:        movl    r9,datdv        # save vrblk pointer for datatype
                   10830:        movl    sp,datxs        # store starting stack value
                   10831:        clrl    r7              # zero count of field names
                   10832: #
                   10833: #      LOOP TO SCAN FIELD NAMES AND STACK VRBLK POINTERS
                   10834: #
                   10835: sdat2: movl    $ch$rp,r8       # delimiter one = right paren
                   10836:        movl    $ch$cm,r10      # delimiter two = comma
                   10837:        jsb     xscan           # scan next field name
                   10838:        tstl    r6              # jump if delimiter found
                   10839:        bnequ   sdat3
                   10840:        jmp     er_079          # data argument is missing a right paren
                   10841: #
                   10842: #      HERE AFTER SCANNING OUT ONE FIELD NAME
                   10843: #
                   10844: sdat3: jsb     gtnvr           # locate vrblk for field name
                   10845:        .long   er_080          # data argument has null field name
                   10846:        movl    r9,-(sp)        # stack vrblk pointer
                   10847:        incl    r7              # increment counter
                   10848:        cmpl    r6,$num02       # loop back if stopped by comma
                   10849:        beqlu   sdat2
                   10850:        #page   
                   10851: #
                   10852: #      DATA (CONTINUED)
                   10853: #
                   10854: #      NOW BUILD THE DFBLK
                   10855: #
                   10856:        movl    $dfsi$,r6       # set size of dfblk standard fields
                   10857:        addl2   r7,r6           # add number of fields
                   10858:        moval   0[r6],r6        # convert length to bytes
                   10859:        movl    r7,r8           # preserve no. of fields
                   10860:        jsb     alost           # allocate space for dfblk
                   10861:        movl    r8,r7           # get no of fields
                   10862:        movl    datxs,r10       # point to start of stack
                   10863:        movl    (r10),r8        # load datatype name
                   10864:        movl    r9,(r10)        # save dfblk pointer on stack
                   10865:        movl    $b$dfc,(r9)+    # store type word
                   10866:        movl    r7,(r9)+        # store number of fields (fargs)
                   10867:        movl    r6,(r9)+        # store length (dflen)
                   10868:        subl2   $4*pddfs,r6     # compute pdblk length (for dfpdl)
                   10869:        movl    r6,(r9)+        # store pdblk length (dfpdl)
                   10870:        movl    r8,(r9)+        # store datatype name (dfnam)
                   10871:        movl    r7,r8           # copy number of fields
                   10872: #
                   10873: #      LOOP TO MOVE FIELD NAME VRBLK POINTERS TO DFBLK
                   10874: #
                   10875: sdat4: movl    -(r10),(r9)+    # move one field name vrblk pointer
                   10876:        sobgtr  r8,sdat4        # loop till all moved
                   10877: #
                   10878: #      NOW DEFINE THE DATATYPE FUNCTION
                   10879: #
                   10880:        movl    r6,r8           # copy length of pdblk for later loop
                   10881:        movl    datdv,r9        # point to vrblk
                   10882:        movl    datxs,r10       # point back on stack
                   10883:        movl    (r10),r10       # load dfblk pointer
                   10884:        jsb     dffnc           # define function
                   10885:        #page   
                   10886: #
                   10887: #      DATA (CONTINUED)
                   10888: #
                   10889: #      LOOP TO BUILD FFBLKS
                   10890: #
                   10891: #
                   10892: #      NOTICE THAT THE FFBLKS ARE CONSTRUCTED IN REVERSE ORDER
                   10893: #      SO THAT THE REQUIRED OFFSETS CAN BE OBTAINED FROM
                   10894: #      SUCCESSIVE DECREMENTATION OF THE PDBLK LENGTH (IN WC).
                   10895: #
                   10896: sdat5: movl    $4*ffsi$,r6     # set length of ffblk
                   10897:        jsb     alloc           # allocate space for ffblk
                   10898:        movl    $b$ffc,(r9)     # set type word
                   10899:        movl    $num01,4*fargs(r9) # store fargs (always one)
                   10900:        movl    datxs,r10       # point back on stack
                   10901:        movl    (r10),4*ffdfp(r9)# copy dfblk ptr to ffblk
                   10902:        subl2   $4,r8           # decrement old dfpdl to get next ofs
                   10903:        movl    r8,4*ffofs(r9)  # set offset to this field
                   10904:        clrl    4*ffnxt(r9)     # tentatively set zero forward ptr
                   10905:        movl    r9,r10          # copy ffblk pointer for dffnc
                   10906:        movl    (sp),r9         # load vrblk pointer for field
                   10907:        movl    4*vrfnc(r9),r9  # load current function pointer
                   10908:        cmpl    (r9),$b$ffc     # skip if not currently a field func
                   10909:        bnequ   sdat6
                   10910: #
                   10911: #      HERE WE MUST CHAIN AN OLD FFBLK PTR TO PRESERVE IT IN THE
                   10912: #      CASE OF MULTIPLE FIELD FUNCTIONS WITH THE SAME NAME
                   10913: #
                   10914:        movl    r9,4*ffnxt(r10) # link new ffblk to previous chain
                   10915: #
                   10916: #      MERGE HERE TO DEFINE FIELD FUNCTION
                   10917: #
                   10918: sdat6: movl    (sp)+,r9        # load vrblk pointer
                   10919:        jsb     dffnc           # define field function
                   10920:        cmpl    sp,datxs        # loop back till all done
                   10921:        bnequ   sdat5
                   10922:        addl2   $4,sp           # pop dfblk pointer
                   10923:        jmp     exnul           # return with null result
                   10924:        #page   
                   10925: #
                   10926: #      DATATYPE
                   10927: #
                   10928: s$dtp:                         # entry point
                   10929:        movl    (sp)+,r9        # load argument
                   10930:        jsb     dtype           # get datatype
                   10931:        jmp     exixr           # and return it as result
                   10932:        #page   
                   10933: #
                   10934: #      DATE
                   10935: #
                   10936: s$dte:                         # entry point
                   10937:        jsb     sysdt           # call system date routine
                   10938:        movl    4*1(r10),r6     # load length for sbstr
                   10939:        bnequ   0f              # return null if length is zero
                   10940:        jmp     exnul
                   10941: 0:             
                   10942:        clrl    r7              # set zero offset
                   10943:        jsb     sbstr           # use sbstr to build scblk
                   10944:        jmp     exixr           # return date string
                   10945:        #page   
                   10946: #
                   10947: #      DEFINE
                   10948: #
                   10949: s$def:                         # entry point
                   10950:        movl    (sp)+,r9        # load second argument
                   10951:        clrl    deflb           # zero label pointer in case null
                   10952:        cmpl    r9,$nulls       # jump if null second argument
                   10953:        beqlu   sdf01
                   10954:        jsb     gtnvr           # else find vrblk for label
                   10955:        .long   sdf13           # jump if not a variable name
                   10956:        movl    r9,deflb        # else set specified entry
                   10957: #
                   10958: #      SCAN FUNCTION NAME
                   10959: #
                   10960: sdf01: jsb     xscni           # prepare to scan first argument
                   10961:        .long   er_081          # define first argument is not string
                   10962:        .long   er_082          # define first argument is null
                   10963:        movl    $ch$pp,r8       # delimiter one = left paren
                   10964:        movl    r8,r10          # delimiter two = left paren
                   10965:        jsb     xscan           # scan out function name
                   10966:        tstl    r6              # jump if left paren found
                   10967:        bnequ   sdf02
                   10968:        jmp     er_083          # define first argument is missing a left paren
                   10969: #
                   10970: #      HERE AFTER SCANNING OUT FUNCTION NAME
                   10971: #
                   10972: sdf02: jsb     gtnvr           # get variable name
                   10973:        .long   er_084          # define first argument has null function name
                   10974:        movl    r9,defvr        # save vrblk pointer for function nam
                   10975:        clrl    r7              # zero count of arguments
                   10976:        movl    sp,defxs        # save initial stack pointer
                   10977:        tstl    deflb           # jump if second argument given
                   10978:        bnequ   sdf03
                   10979:        movl    r9,deflb        # else default is function name
                   10980: #
                   10981: #      LOOP TO SCAN ARGUMENT NAMES AND STACK VRBLK POINTERS
                   10982: #
                   10983: sdf03: movl    $ch$rp,r8       # delimiter one = right paren
                   10984:        movl    $ch$cm,r10      # delimiter two = comma
                   10985:        jsb     xscan           # scan out next argument name
                   10986:        tstl    r6              # skip if delimiter found
                   10987:        bnequ   sdf04
                   10988:        jmp     er_085          # null arg name or missing ) in define first arg.
                   10989:        #page   
                   10990: #
                   10991: #      DEFINE (CONTINUED)
                   10992: #
                   10993: #      HERE AFTER SCANNING AN ARGUMENT NAME
                   10994: #
                   10995: sdf04: cmpl    r9,$nulls       # skip if non-null
                   10996:        bnequ   sdf05
                   10997:        tstl    r7              # ignore null if case of no arguments
                   10998:        beqlu   sdf06
                   10999: #
                   11000: #      HERE AFTER DEALING WITH THE CASE OF NO ARGUMENTS
                   11001: #
                   11002: sdf05: jsb     gtnvr           # get vrblk pointer
                   11003:        .long   sdf03           # loop back to ignore null name
                   11004:        movl    r9,-(sp)        # stack argument vrblk pointer
                   11005:        incl    r7              # increment counter
                   11006:        cmpl    r6,$num02       # loop back if stopped by a comma
                   11007:        beqlu   sdf03
                   11008: #
                   11009: #      HERE AFTER SCANNING OUT FUNCTION ARGUMENT NAMES
                   11010: #
                   11011: sdf06: movl    r7,defna        # save number of arguments
                   11012:        clrl    r7              # zero count of locals
                   11013: #
                   11014: #      LOOP TO SCAN LOCAL NAMES AND STACK VRBLK POINTERS
                   11015: #
                   11016: sdf07: movl    $ch$cm,r8       # set delimiter one = comma
                   11017:        movl    r8,r10          # set delimiter two = comma
                   11018:        jsb     xscan           # scan out next local name
                   11019:        cmpl    r9,$nulls       # skip if non-null
                   11020:        bnequ   sdf08
                   11021:        tstl    r7              # ignore null if case of no locals
                   11022:        beqlu   sdf09
                   11023: #
                   11024: #      HERE AFTER SCANNING OUT A LOCAL NAME
                   11025: #
                   11026: sdf08: jsb     gtnvr           # get vrblk pointer
                   11027:        .long   sdf07           # loop back to ignore null name
                   11028:        incl    r7              # if ok, increment count
                   11029:        movl    r9,-(sp)        # stack vrblk pointer
                   11030:        tstl    r6              # loop back if stopped by a comma
                   11031:        bnequ   sdf07
                   11032:        #page   
                   11033: #
                   11034: #      DEFINE (CONTINUED)
                   11035: #
                   11036: #      HERE AFTER SCANNING LOCALS, BUILD PFBLK
                   11037: #
                   11038: sdf09: movl    r7,r6           # copy count of locals
                   11039:        addl2   defna,r6        # add number of arguments
                   11040:        movl    r6,r8           # set sum args+locals as loop count
                   11041:        addl2   $pfsi$,r6       # add space for standard fields
                   11042:        moval   0[r6],r6        # convert length to bytes
                   11043:        jsb     alloc           # allocate space for pfblk
                   11044:        movl    r9,r10          # save pointer to pfblk
                   11045:        movl    $b$pfc,(r9)+    # store first word
                   11046:        movl    defna,(r9)+     # store number of arguments
                   11047:        movl    r6,(r9)+        # store length (pflen)
                   11048:        movl    defvr,(r9)+     # store vrblk ptr for function name
                   11049:        movl    r7,(r9)+        # store number of locals
                   11050:        clrl    (r9)+           # deal with label later
                   11051:        clrl    (r9)+           # zero pfctr
                   11052:        clrl    (r9)+           # zero pfrtr
                   11053:        tstl    r8              # skip if no args or locals
                   11054:        beqlu   sdf11
                   11055:        movl    r10,r6          # keep pfblk pointer
                   11056:        movl    defxs,r10       # point before arguments
                   11057:                                # get count of args+locals for loop
                   11058: #
                   11059: #      LOOP TO MOVE LOCALS AND ARGS TO PFBLK
                   11060: #
                   11061: sdf10: movl    -(r10),(r9)+    # store one entry and bump pointers
                   11062:        sobgtr  r8,sdf10        # loop till all stored
                   11063:        movl    r6,r10          # recover pfblk pointer
                   11064:        #page   
                   11065: #
                   11066: #      DEFINE (CONTINUED)
                   11067: #
                   11068: #      NOW DEAL WITH LABEL
                   11069: #
                   11070: sdf11: movl    defxs,sp        # pop stack
                   11071:        movl    deflb,r9        # point to vrblk for label
                   11072:        movl    4*vrlbl(r9),r9  # load label pointer
                   11073:        cmpl    (r9),$b$trt     # skip if not trapped
                   11074:        bnequ   sdf12
                   11075:        movl    4*trlbl(r9),r9  # else point to real label
                   11076: #
                   11077: #      HERE AFTER LOCATING REAL LABEL POINTER
                   11078: #
                   11079: sdf12: cmpl    r9,$stndl       # jump if label is not defined
                   11080:        beqlu   sdf13
                   11081:        movl    r9,4*pfcod(r10) # else store label pointer
                   11082:        movl    defvr,r9        # point back to vrblk for function
                   11083:        jsb     dffnc           # define function
                   11084:        jmp     exnul           # and exit returning null
                   11085: #
                   11086: #      HERE FOR ERRONEOUS LABEL
                   11087: #
                   11088: sdf13: jmp     er_086          # define function entry point is not defined label
                   11089:        #page   
                   11090: #
                   11091: #      DETACH
                   11092: #
                   11093: s$det:                         # entry point
                   11094:        movl    (sp)+,r9        # load argument
                   11095:        jsb     gtvar           # locate variable
                   11096:        .long   er_087          # detach argument is not appropriate name
                   11097:        jsb     dtach           # detach i/o association from name
                   11098:        jmp     exnul           # return null result
                   11099:        #page   
                   11100: #
                   11101: #      DIFFER
                   11102: #
                   11103: s$dif:                         # entry point
                   11104:        movl    (sp)+,r9        # load second argument
                   11105:        movl    (sp)+,r10       # load first argument
                   11106:        jsb     ident           # call ident comparison routine
                   11107:        .long   exfal           # fail if ident
                   11108:        jmp     exnul           # return null if differ
                   11109:        #page   
                   11110: #
                   11111: #      DUMP
                   11112: #
                   11113: s$dmp:                         # entry point
                   11114:        jsb     gtsmi           # load dump arg as small integer
                   11115:        .long   er_088          # dump argument is not integer
                   11116:        .long   er_089          # dump argument is negative or too large
                   11117:        jsb     dumpr           # else call dump routine
                   11118:        jmp     exnul           # and return null as result
                   11119:        #page   
                   11120: #
                   11121: #      DUPL
                   11122: #
                   11123: s$dup:                         # entry point
                   11124:        jsb     gtsmi           # get second argument as small intege
                   11125:        .long   er_090          # dupl second argument is not integer
                   11126:        .long   sdup7           # jump if negative ot too big
                   11127:        movl    r9,r7           # save duplication factor
                   11128:        jsb     gtstg           # get first arg as string
                   11129:        .long   sdup4           # jump if not a string
                   11130: #
                   11131: #      HERE FOR CASE OF DUPLICATION OF A STRING
                   11132: #
                   11133:        movl    r6,r5           # acquire length as integer
                   11134:        movl    r5,dupsi        # save for the moment
                   11135:        movl    r7,r5           # get duplication factor as integer
                   11136:        mull2   dupsi,r5        # form product
                   11137:        bvs     sdup3
                   11138:        tstl    r5              # return null if result length = 0
                   11139:        bneq    0f
                   11140:        jmp     exnul
                   11141: 0:             
                   11142:        movl    r5,r6           # get as addr integer, check ovflo
                   11143:        bgeq    0f
                   11144:        jmp     sdup3
                   11145: 0:             
                   11146: #
                   11147: #      MERGE HERE WITH RESULT LENGTH IN WA
                   11148: #
                   11149: sdup1: movl    r9,r10          # save string pointer
                   11150:        jsb     alocs           # allocate space for string
                   11151:        movl    r9,-(sp)        # save as result pointer
                   11152:        movl    r10,r8          # save pointer to argument string
                   11153:        movab   cfp$f(r9),r9    # prepare to store chars of result
                   11154:                                # set counter to control loop
                   11155: #
                   11156: #      LOOP THROUGH DUPLICATIONS
                   11157: #
                   11158: sdup2: movl    r8,r10          # point back to argument string
                   11159:        movl    4*sclen(r10),r6 # get number of characters
                   11160:        movab   cfp$f(r10),r10  # point to chars in argument string
                   11161:        jsb     sbmvc           # move characters to result string
                   11162:        sobgtr  r7,sdup2        # loop till all duplications done
                   11163:        jmp     exits           # then exit for next code word
                   11164:        #page   
                   11165: #
                   11166: #      DUPL (CONTINUED)
                   11167: #
                   11168: #      HERE IF TOO LARGE, SET MAX LENGTH AND LET ALOCS CATCH IT
                   11169: #
                   11170: sdup3: movl    dname,r6        # set impossible length for alocs
                   11171:        jmp     sdup1           # merge back
                   11172: #
                   11173: #      HERE IF NOT A STRING
                   11174: #
                   11175: sdup4: jsb     gtpat           # convert argument to pattern
                   11176:        .long   er_091          # dupl first argument is not string or pattern
                   11177: #
                   11178: #      HERE TO DUPLICATE A PATTERN ARGUMENT
                   11179: #
                   11180:        movl    r9,-(sp)        # store pattern on stack
                   11181:        movl    $ndnth,r9       # start off with null pattern
                   11182:        tstl    r7              # null pattern is result if dupfac=0
                   11183:        beqlu   sdup6
                   11184:        movl    r7,-(sp)        # preserve loop count
                   11185: #
                   11186: #      LOOP TO DUPLICATE BY SUCCESSIVE CONCATENATION
                   11187: #
                   11188: sdup5: movl    r9,r10          # copy current value as right argumnt
                   11189:        movl    4*1(sp),r9      # get a new copy of left
                   11190:        jsb     pconc           # concatenate
                   11191:        decl    (sp)            # count down
                   11192:        bnequ   sdup5           # loop
                   11193:        addl2   $4,sp           # pop loop count
                   11194: #
                   11195: #      HERE TO EXIT AFTER CONSTRUCTING PATTERN
                   11196: #
                   11197: sdup6: movl    r9,(sp)         # store result on stack
                   11198:        jmp     exits           # exit with result on stack
                   11199: #
                   11200: #      FAIL IF SECOND ARG IS OUT OF RANGE
                   11201: #
                   11202: sdup7: addl2   $4,sp           # pop first argument
                   11203:        jmp     exfal           # fail
                   11204:        #page   
                   11205: #
                   11206: #      EJECT
                   11207: #
                   11208: s$ejc:                         # entry point
                   11209:        jsb     iofcb           # call fcblk routine
                   11210:        .long   er_092          # eject argument is not a suitable name
                   11211:        .long   sejc1           # null argument
                   11212:        jsb     sysef           # call eject file function
                   11213:        .long   er_093          # eject file does not exist
                   11214:        .long   er_094          # eject file does not permit page eject
                   11215:        .long   er_095          # eject caused non-recoverable output error
                   11216:        jmp     exnul           # return null as result
                   11217: #
                   11218: #      HERE TO EJECT STANDARD OUTPUT FILE
                   11219: #
                   11220: sejc1: jsb     sysep           # call routine to eject printer
                   11221:        jmp     exnul           # exit with null result
                   11222:        #page   
                   11223: #
                   11224: #      ENDFILE
                   11225: #
                   11226: s$enf:                         # entry point
                   11227:        jsb     iofcb           # call fcblk routine
                   11228:        .long   er_096          # endfile argument is not a suitable name
                   11229:        .long   er_097          # endfile argument is null
                   11230:        jsb     sysen           # call endfile routine
                   11231:        .long   er_098          # endfile file does not exist
                   11232:        .long   er_099          # endfile file does not permit endfile
                   11233:        .long   er_100          # endfile caused non-recoverable output error
                   11234:        movl    r10,r7          # remember vrblk ptr from iofcb call
                   11235: #
                   11236: #      LOOP TO FIND TRTRF BLOCK
                   11237: #
                   11238: senf1: movl    r10,r9          # copy pointer
                   11239:        movl    4*trval(r9),r9  # chain along
                   11240:        cmpl    (r9),$b$trt     # skip out if chain end
                   11241:        beqlu   0f
                   11242:        jmp     exnul
                   11243: 0:             
                   11244:        cmpl    4*trtyp(r9),$trtfc # loop if not found
                   11245:        bnequ   senf1
                   11246:        movl    4*trval(r9),4*trval(r10) # remove trtrf
                   11247:        movl    4*trtrf(r9),enfch# point to head of iochn
                   11248:        movl    4*trfpt(r9),r8  # point to fcblk
                   11249:        movl    r7,r9           # filearg1 vrblk from iofcb
                   11250:        jsb     setvr           # reset it
                   11251:        movl    $r$fcb,r10      # ptr to head of fcblk chain
                   11252:        subl2   $4*num02,r10    # adjust ready to enter loop
                   11253: #
                   11254: #      FIND FCBLK
                   11255: #
                   11256: senf2: movl    r10,r9          # copy ptr
                   11257:        movl    4*2(r10),r10    # get next link
                   11258:        beqlu   senf4           # stop if chain end
                   11259:        cmpl    4*3(r10),r8     # jump if fcblk found
                   11260:        beqlu   senf3
                   11261:        jmp     senf2           # loop
                   11262: #
                   11263: #      REMOVE FCBLK
                   11264: #
                   11265: senf3: movl    4*2(r10),4*2(r9)# delete fcblk from chain
                   11266: #
                   11267: #      LOOP WHICH DETACHES ALL VBLS ON IOCHN CHAIN
                   11268: #
                   11269: senf4: movl    enfch,r10       # get chain head
                   11270:        bnequ   0f              # finished if chain end
                   11271:        jmp     exnul
                   11272: 0:             
                   11273:        movl    4*trtrf(r10),enfch # chain along
                   11274:        movl    4*ionmo(r10),r6 # name offset
                   11275:        movl    4*ionmb(r10),r10# name base
                   11276:        jsb     dtach           # detach name
                   11277:        jmp     senf4           # loop till done
                   11278:        #page   
                   11279: #
                   11280: #      EQ
                   11281: #
                   11282: s$eqf:                         # entry point
                   11283:        jsb     acomp           # call arithmetic comparison routine
                   11284:        .long   er_101          # eq first argument is not numeric
                   11285:        .long   er_102          # eq second argument is not numeric
                   11286:        .long   exfal           # fail if lt
                   11287:        .long   exnul           # return null if eq
                   11288:        .long   exfal           # fail if gt
                   11289:        #page   
                   11290: #
                   11291: #      EVAL
                   11292: #
                   11293: s$evl:                         # entry point
                   11294:        movl    (sp)+,r9        # load argument
                   11295:        jsb     gtexp           # convert to expression
                   11296:        .long   er_103          # eval argument is not expression
                   11297:        movl    (r3)+,r8        # load next code word
                   11298:        cmpl    r8,$ofne$       # jump if called by value
                   11299:        bnequ   sevl1
                   11300:        movl    r3,r10          # copy code pointer
                   11301:        movl    (r10),r6        # get next code word
                   11302:        cmpl    r6,$ornm$       # by name unless expression
                   11303:        bnequ   sevl2
                   11304:        tstl    4*1(sp) # jump if by name
                   11305:        bnequ   sevl2
                   11306: #
                   11307: #      HERE IF CALLED BY VALUE
                   11308: #
                   11309: sevl1: clrl    r7              # set flag for by value
                   11310:        movl    r8,-(sp)        # save code word
                   11311:        jsb     evalx           # evaluate expression by value
                   11312:        .long   exfal           # fail if evaluation fails
                   11313:        movl    r9,r10          # copy result
                   11314:        movl    (sp),r9         # reload next code word
                   11315:        movl    r10,(sp)        # stack result
                   11316:        movl    (r9),r11        # jump to execute next code word
                   11317:        jmp     (r11)
                   11318: #
                   11319: #      HERE IF CALLED BY NAME
                   11320: #
                   11321: sevl2: movl    $num01,r7       # set flag for by name
                   11322:        jsb     evalx           # evaluate expression by name
                   11323:        .long   exfal           # fail if evaluation fails
                   11324:        jmp     exnam           # exit with name
                   11325:        #page   
                   11326: #
                   11327: #      EXIT
                   11328: #
                   11329: s$ext:                         # entry point
                   11330:        clrl    r7              # clear amount of static shift
                   11331:        jsb     gbcol           # compact memory by collecting
                   11332:        jsb     gtstg           # convert arg to string
                   11333:        .long   er_104          # exit argument is not suitable integer or string
                   11334:        movl    r9,r10          # copy string ptr
                   11335:        jsb     gtint           # check it is integer
                   11336:        .long   sext1           # skip if unconvertible
                   11337:        clrl    r10             # note it is integer
                   11338:        movl    4*icval(r9),r5  # get integer arg
                   11339:        movl    r$fcb,r7        # get fcblk chain header
                   11340: #
                   11341: #      MERGE TO CALL OSINT EXIT ROUTINE
                   11342: #
                   11343: sext1: movl    $headv,r9       # point to v.v string
                   11344:        jsb     sysxi           # call external routine
                   11345:        .long   er_105          # exit action not available in this implementation
                   11346:        .long   er_106          # exit action caused irrecoverable error
                   11347:        tstl    r5              # return if argument 0
                   11348:        bneq    0f
                   11349:        jmp     exnul
                   11350: 0:             
                   11351:        clrl    gbcnt           # resuming execution so reset
                   11352:        tstl    r5              # skip if positive
                   11353:        bgtr    sext2
                   11354:        mnegl   r5,r5           # make positive
                   11355: #
                   11356: #      CHECK FOR OPTION RESPECIFICATION
                   11357: #
                   11358: sext2: movl    r5,r8           # get value in work reg
                   11359:        cmpl    r8,$num03       # skip if was 3
                   11360:        beqlu   sext3
                   11361:        movl    r8,-(sp)        # save value
                   11362:        clrl    r8              # set to read options
                   11363:        jsb     prpar           # read syspp options
                   11364:        movl    (sp)+,r8        # restore value
                   11365: #
                   11366: #      DEAL WITH HEADER OPTION (FIDDLED BY PRPAR)
                   11367: #
                   11368: sext3: movl    sp,headp        # assume no headers
                   11369:        cmpl    r8,$num01       # skip if not 1
                   11370:        bnequ   sext4
                   11371:        clrl    headp           # request header printing
                   11372: #
                   11373: #      ALMOST READY TO RESUME RUNNING
                   11374: #
                   11375: sext4: jsb     systm           # get execution time start (sgd11)
                   11376:        movl    r5,timsx        # save as initial time
                   11377:        movl    kvstc,r5        # reset to ensure ...
                   11378:        movl    r5,kvstl        # ... correct execution stats
                   11379:        jmp     exnul           # resume execution
                   11380:        #page   
                   11381: #
                   11382: #      FIELD
                   11383: #
                   11384: s$fld:                         # entry point
                   11385:        jsb     gtsmi           # get second argument (field number)
                   11386:        .long   er_107          # field second argument is not integer
                   11387:        .long   exfal           # fail if out of range
                   11388:        movl    r9,r7           # else save integer value
                   11389:        movl    (sp)+,r9        # load first argument
                   11390:        jsb     gtnvr           # point to vrblk
                   11391:        .long   sfld1           # jump (error) if not variable name
                   11392:        movl    4*vrfnc(r9),r9  # else point to function block
                   11393:        cmpl    (r9),$b$dfc     # error if not datatype function
                   11394:        bnequ   sfld1
                   11395: #
                   11396: #      HERE IF FIRST ARGUMENT IS A DATATYPE FUNCTION NAME
                   11397: #
                   11398:        tstl    r7              # fail if argument number is zero
                   11399:        bnequ   0f
                   11400:        jmp     exfal
                   11401: 0:             
                   11402:        cmpl    r7,4*fargs(r9)  # fail if too large
                   11403:        blequ   0f
                   11404:        jmp     exfal
                   11405: 0:             
                   11406:        moval   0[r7],r7        # else convert to byte offset
                   11407:        addl2   r7,r9           # point to field name
                   11408:        movl    4*dfflb(r9),r9  # load vrblk pointer
                   11409:        jmp     exvnm           # exit to build nmblk
                   11410: #
                   11411: #      HERE FOR BAD FIRST ARGUMENT
                   11412: #
                   11413: sfld1: jmp     er_108          # field first argument is not datatype name
                   11414:        #page   
                   11415: #
                   11416: #      FENCE
                   11417: #
                   11418: s$fnc:                         # entry point
                   11419:        movl    $p$fnc,r7       # set pcode for p$fnc
                   11420:        clrl    r9              # p0blk
                   11421:        jsb     pbild           # build p$fnc node
                   11422:        movl    r9,r10          # save pointer to it
                   11423:        movl    (sp)+,r9        # get argument
                   11424:        jsb     gtpat           # convert to pattern
                   11425:        .long   er_259          # fence argument is not pattern
                   11426:        jsb     pconc           # concatenate to p$fnc node
                   11427:        movl    r9,r10          # save ptr to concatenated pattern
                   11428:        movl    $p$fna,r7       # set for p$fna pcode
                   11429:        clrl    r9              # p0blk
                   11430:        jsb     pbild           # construct p$fna node
                   11431:        movl    r10,4*pthen(r9) # set pattern as pthen
                   11432:        movl    r9,-(sp)        # set as result
                   11433:        jmp     exits           # do next code word
                   11434:        #page   
                   11435: #
                   11436: #      GE
                   11437: #
                   11438: s$gef:                         # entry point
                   11439:        jsb     acomp           # call arithmetic comparison routine
                   11440:        .long   er_109          # ge first argument is not numeric
                   11441:        .long   er_110          # ge second argument is not numeric
                   11442:        .long   exfal           # fail if lt
                   11443:        .long   exnul           # return null if eq
                   11444:        .long   exnul           # return null if gt
                   11445:        #page   
                   11446: #
                   11447: #      GT
                   11448: #
                   11449: s$gtf:                         # entry point
                   11450:        jsb     acomp           # call arithmetic comparison routine
                   11451:        .long   er_111          # gt first argument is not numeric
                   11452:        .long   er_112          # gt second argument is not numeric
                   11453:        .long   exfal           # fail if lt
                   11454:        .long   exfal           # fail if eq
                   11455:        .long   exnul           # return null if gt
                   11456:        #page   
                   11457: #
                   11458: #      HOST
                   11459: #
                   11460: s$hst:                         # entry point
                   11461:        movl    (sp)+,r9        # get third arg
                   11462:        movl    (sp)+,r10       # get second arg
                   11463:        movl    (sp)+,r6        # get first arg
                   11464:        jsb     syshs           # enter syshs routine
                   11465:        .long   er_254          # erroneous argument for host
                   11466:        .long   er_255          # error during execution of host
                   11467:        .long   shst1           # store host string
                   11468:        .long   exnul           # return null result
                   11469:        .long   exixr           # return xr
                   11470:        .long   exfal           # fail return
                   11471: #
                   11472: #      RETURN HOST STRING
                   11473: #
                   11474: shst1: tstl    r10             # null string if syshs uncooperative
                   11475:        bnequ   0f
                   11476:        jmp     exnul
                   11477: 0:             
                   11478:        movl    4*sclen(r10),r6 # length
                   11479:        clrl    r7              # zero offset
                   11480:        jsb     sbstr           # build copy of string
                   11481:        movl    r9,-(sp)        # stack the result
                   11482:        jmp     exits           # return result on stack
                   11483:        #page   
                   11484: #
                   11485: #      IDENT
                   11486: #
                   11487: s$idn:                         # entry point
                   11488:        movl    (sp)+,r9        # load second argument
                   11489:        movl    (sp)+,r10       # load first argument
                   11490:        jsb     ident           # call ident comparison routine
                   11491:        .long   exnul           # return null if ident
                   11492:        jmp     exfal           # fail if differ
                   11493:        #page   
                   11494: #
                   11495: #      INPUT
                   11496: #
                   11497: s$inp:                         # entry point
                   11498:        clrl    r7              # input flag
                   11499:        jsb     ioput           # call input/output assoc. routine
                   11500:        .long   er_113          # input third argument is not a string
                   11501:        .long   er_114          # inappropriate second argument for input
                   11502:        .long   er_115          # inappropriate first argument for input
                   11503:        .long   er_116          # inappropriate file specification for input
                   11504:        .long   exfal           # fail if file does not exist
                   11505:        .long   er_117          # input file cannot be read
                   11506:        jmp     exnul           # return null string
                   11507:        #page   
                   11508: #
                   11509: #      INSERT
                   11510: #
                   11511: s$ins:                         # entry point
                   11512:        movl    (sp)+,r10       # get string arg
                   11513:        jsb     gtsmi           # get replace length
                   11514:        .long   er_277          # insert third argument not integer
                   11515:        .long   exfal           # fail if out of range
                   11516:        movl    r8,r7           # copy to proper reg
                   11517:        jsb     gtsmi           # get replace position
                   11518:        .long   er_278          # insert second argument not integer
                   11519:        .long   exfal           # fail if out of range
                   11520:        tstl    r8              # fail if zero
                   11521:        bnequ   0f
                   11522:        jmp     exfal
                   11523: 0:             
                   11524:        decl    r8              # decrement to get offset
                   11525:        movl    r8,r6           # put in proper register
                   11526:        movl    (sp)+,r9        # get buffer
                   11527:        cmpl    (r9),$b$bct     # press on if type ok
                   11528:        beqlu   sins1
                   11529:        jmp     er_279          # insert first argument not buffer
                   11530: #
                   11531: #      HERE WHEN EVERYTHING LOADED UP
                   11532: #
                   11533: sins1: jsb     insbf           # call to insert
                   11534:        .long   er_280          # insert fourth argument not a string
                   11535:        .long   exfal           # fail if out of range
                   11536:        jmp     exnul           # else ok - exit with null
                   11537:        #page   
                   11538: #
                   11539: #      INTEGER
                   11540: #
                   11541: s$int:                         # entry point
                   11542:        movl    (sp)+,r9        # load argument
                   11543:        jsb     gtnum           # convert to numeric
                   11544:        .long   exfal           # fail if non-numeric
                   11545:        cmpl    r6,$b$icl       # return null if integer
                   11546:        bnequ   0f
                   11547:        jmp     exnul
                   11548: 0:             
                   11549:        jmp     exfal           # fail if real
                   11550:        #page   
                   11551: #
                   11552: #      ITEM
                   11553: #
                   11554: #      ITEM DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT
                   11555: #      WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED.
                   11556: #
                   11557: s$itm:                         # entry point
                   11558: #
                   11559: #      DEAL WITH CASE OF NO ARGS
                   11560: #
                   11561:        tstl    r6              # jump if at least one arg
                   11562:        bnequ   sitm1
                   11563:        movl    $nulls,-(sp)    # else supply garbage null arg
                   11564:        movl    $num01,r6       # and fix argument count
                   11565: #
                   11566: #      CHECK FOR NAME/VALUE CASES
                   11567: #
                   11568: sitm1: movl    r3,r9           # get current code pointer
                   11569:        movl    (r9),r10        # load next code word
                   11570:        decl    r6              # get number of subscripts
                   11571:        movl    r6,r9           # copy for arref
                   11572:        cmpl    r10,$ofne$      # jump if called by name
                   11573:        beqlu   sitm2
                   11574: #
                   11575: #      HERE IF CALLED BY VALUE
                   11576: #
                   11577:        clrl    r7              # set code for call by value
                   11578:        jmp     arref           # off to array reference routine
                   11579: #
                   11580: #      HERE FOR CALL BY NAME
                   11581: #
                   11582: sitm2: movl    sp,r7           # set code for call by name
                   11583:        movl    (r3)+,r6        # load and ignore ofne$ call
                   11584:        jmp     arref           # off to array reference routine
                   11585:        #page   
                   11586: #
                   11587: #      LE
                   11588: #
                   11589: s$lef:                         # entry point
                   11590:        jsb     acomp           # call arithmetic comparison routine
                   11591:        .long   er_118          # le first argument is not numeric
                   11592:        .long   er_119          # le second argument is not numeric
                   11593:        .long   exnul           # return null if lt
                   11594:        .long   exnul           # return null if eq
                   11595:        .long   exfal           # fail if gt
                   11596:        #page   
                   11597: #
                   11598: #      LEN
                   11599: #
                   11600: s$len:                         # entry point
                   11601:        movl    $p$len,r7       # set pcode for integer arg case
                   11602:        movl    $p$lnd,r6       # set pcode for expr arg case
                   11603:        jsb     patin           # call common routine to build node
                   11604:        .long   er_120          # len argument is not integer or expression
                   11605:        .long   er_121          # len argument is negative or too large
                   11606:        jmp     exixr           # return pattern node
                   11607:        #page   
                   11608: #
                   11609: #      LEQ
                   11610: #
                   11611: s$leq:                         # entry point
                   11612:        jsb     lcomp           # call string comparison routine
                   11613:        .long   er_122          # leq first argument is not string
                   11614:        .long   er_123          # leq second argument is not string
                   11615:        .long   exfal           # fail if llt
                   11616:        .long   exnul           # return null if leq
                   11617:        .long   exfal           # fail if lgt
                   11618:        #page   
                   11619: #
                   11620: #      LGE
                   11621: #
                   11622: s$lge:                         # entry point
                   11623:        jsb     lcomp           # call string comparison routine
                   11624:        .long   er_124          # lge first argument is not string
                   11625:        .long   er_125          # lge second argument is not string
                   11626:        .long   exfal           # fail if llt
                   11627:        .long   exnul           # return null if leq
                   11628:        .long   exnul           # return null if lgt
                   11629:        #page   
                   11630: #
                   11631: #      LGT
                   11632: #
                   11633: s$lgt:                         # entry point
                   11634:        jsb     lcomp           # call string comparison routine
                   11635:        .long   er_126          # lgt first argument is not string
                   11636:        .long   er_127          # lgt second argument is not string
                   11637:        .long   exfal           # fail if llt
                   11638:        .long   exfal           # fail if leq
                   11639:        .long   exnul           # return null if lgt
                   11640:        #page   
                   11641: #
                   11642: #      LLE
                   11643: #
                   11644: s$lle:                         # entry point
                   11645:        jsb     lcomp           # call string comparison routine
                   11646:        .long   er_128          # lle first argument is not string
                   11647:        .long   er_129          # lle second argument is not string
                   11648:        .long   exnul           # return null if llt
                   11649:        .long   exnul           # return null if leq
                   11650:        .long   exfal           # fail if lgt
                   11651:        #page   
                   11652: #
                   11653: #      LLT
                   11654: #
                   11655: s$llt:                         # entry point
                   11656:        jsb     lcomp           # call string comparison routine
                   11657:        .long   er_130          # llt first argument is not string
                   11658:        .long   er_131          # llt second argument is not string
                   11659:        .long   exnul           # return null if llt
                   11660:        .long   exfal           # fail if leq
                   11661:        .long   exfal           # fail if lgt
                   11662:        #page   
                   11663: #
                   11664: #      LNE
                   11665: #
                   11666: s$lne:                         # entry point
                   11667:        jsb     lcomp           # call string comparison routine
                   11668:        .long   er_132          # lne first argument is not string
                   11669:        .long   er_133          # lne second argument is not string
                   11670:        .long   exnul           # return null if llt
                   11671:        .long   exfal           # fail if leq
                   11672:        .long   exnul           # return null if lgt
                   11673:        #page   
                   11674: #
                   11675: #      LOCAL
                   11676: #
                   11677: s$loc:                         # entry point
                   11678:        jsb     gtsmi           # get second argument (local number)
                   11679:        .long   er_134          # local second argument is not integer
                   11680:        .long   exfal           # fail if out of range
                   11681:        movl    r9,r7           # save local number
                   11682:        movl    (sp)+,r9        # load first argument
                   11683:        jsb     gtnvr           # point to vrblk
                   11684:        .long   sloc1           # jump if not variable name
                   11685:        movl    4*vrfnc(r9),r9  # else load function pointer
                   11686:        cmpl    (r9),$b$pfc     # jump if not program defined
                   11687:        bnequ   sloc1
                   11688: #
                   11689: #      HERE IF WE HAVE A PROGRAM DEFINED FUNCTION NAME
                   11690: #
                   11691:        tstl    r7              # fail if second arg is zero
                   11692:        bnequ   0f
                   11693:        jmp     exfal
                   11694: 0:             
                   11695:        cmpl    r7,4*pfnlo(r9)  # or too large
                   11696:        blequ   0f
                   11697:        jmp     exfal
                   11698: 0:             
                   11699:        addl2   4*fargs(r9),r7  # else adjust offset to include args
                   11700:        moval   0[r7],r7        # convert to bytes
                   11701:        addl2   r7,r9           # point to local pointer
                   11702:        movl    4*pfagb(r9),r9  # load vrblk pointer
                   11703:        jmp     exvnm           # exit building nmblk
                   11704: #
                   11705: #      HERE IF FIRST ARGUMENT IS NO GOOD
                   11706: #
                   11707: sloc1: jmp     er_135          # local first arg is not a program function name
                   11708:        #page   
                   11709: #
                   11710: #      LOAD
                   11711: #
                   11712: s$lod:                         # entry point
                   11713:        jsb     gtstg           # load library name
                   11714:        .long   er_136          # load second argument is not string
                   11715:        movl    r9,r10          # save library name
                   11716:        jsb     xscni           # prepare to scan first argument
                   11717:        .long   er_137          # load first argument is not string
                   11718:        .long   er_138          # load first argument is null
                   11719:        movl    r10,-(sp)       # stack library name
                   11720:        movl    $ch$pp,r8       # set delimiter one = left paren
                   11721:        movl    r8,r10          # set delimiter two = left paren
                   11722:        jsb     xscan           # scan function name
                   11723:        movl    r9,-(sp)        # save ptr to function name
                   11724:        tstl    r6              # jump if left paren found
                   11725:        bnequ   slod1
                   11726:        jmp     er_139          # load first argument is missing a left paren
                   11727: #
                   11728: #      HERE AFTER SUCCESSFULLY SCANNING FUNCTION NAME
                   11729: #
                   11730: slod1: jsb     gtnvr           # locate vrblk
                   11731:        .long   er_140          # load first argument has null function name
                   11732:        movl    r9,lodfn        # save vrblk pointer
                   11733:        clrl    lodna           # zero count of arguments
                   11734: #
                   11735: #      LOOP TO SCAN ARGUMENT DATATYPE NAMES
                   11736: #
                   11737: slod2: movl    $ch$rp,r8       # delimiter one is right paren
                   11738:        movl    $ch$cm,r10      # delimiter two is comma
                   11739:        jsb     xscan           # scan next argument name
                   11740:        incl    lodna           # bump argument count
                   11741:        tstl    r6              # jump if ok delimiter was found
                   11742:        bnequ   slod3
                   11743:        jmp     er_141          # load first argument is missing a right paren
                   11744:        #page   
                   11745: #
                   11746: #      LOAD (CONTINUED)
                   11747: #
                   11748: #      COME HERE TO ANALYZE THE DATATYPE POINTER IN (XR). THIS
                   11749: #      CODE IS USED BOTH FOR ARGUMENTS (WA=1,2) AND FOR THE
                   11750: #      RESULT DATATYPE (WITH WA SET TO ZERO).
                   11751: #
                   11752: slod3: movl    r9,-(sp)        # stack datatype name pointer
                   11753:        movl    $num01,r7       # set string code in case
                   11754:        movl    $scstr,r10      # point to /string/
                   11755:        jsb     ident           # check for match
                   11756:        .long   slod4           # jump if match
                   11757:        movl    (sp),r9         # else reload name
                   11758:        addl2   r7,r7           # set code for integer (2)
                   11759:        movl    $scint,r10      # point to /integer/
                   11760:        jsb     ident           # check for match
                   11761:        .long   slod4           # jump if match
                   11762:        movl    (sp),r9         # else reload string pointer
                   11763:        incl    r7              # set code for real (3)
                   11764:        movl    $screa,r10      # point to /real/
                   11765:        jsb     ident           # check for match
                   11766:        .long   slod4           # jump if match
                   11767:        clrl    r7              # else get code for no convert
                   11768: #
                   11769: #      MERGE HERE WITH PROPER DATATYPE CODE IN WB
                   11770: #
                   11771: slod4: movl    r7,(sp)         # store code on stack
                   11772:        cmpl    r6,$num02       # loop back if arg stopped by comma
                   11773:        beqlu   slod2
                   11774:        tstl    r6              # jump if that was the result type
                   11775:        beqlu   slod5
                   11776: #
                   11777: #      HERE WE SCAN OUT THE RESULT TYPE (ARG STOPPED BY ) )
                   11778: #
                   11779:        movl    mxlen,r8        # set dummy (impossible) delimiter 1
                   11780:        movl    r8,r10          # and delimiter two
                   11781:        jsb     xscan           # scan result name
                   11782:        clrl    r6              # set code for processing result
                   11783:        jmp     slod3           # jump back to process result name
                   11784:        #page   
                   11785: #
                   11786: #      LOAD (CONTINUED)
                   11787: #
                   11788: #      HERE AFTER PROCESSING ALL ARGS AND RESULT
                   11789: #
                   11790: slod5: movl    lodna,r6        # get number of arguments
                   11791:        movl    r6,r8           # copy for later
                   11792:        moval   0[r6],r6        # convert length to bytes
                   11793:        addl2   $4*efsi$,r6     # add space for standard fields
                   11794:        jsb     alloc           # allocate efblk
                   11795:        movl    $b$efc,(r9)     # set type word
                   11796:        movl    r8,4*fargs(r9)  # set number of arguments
                   11797:        clrl    4*efuse(r9)     # set use count (dffnc will set to 1)
                   11798:        clrl    4*efcod(r9)     # zero code pointer for now
                   11799:        movl    (sp)+,4*efrsl(r9)# store result type code
                   11800:        movl    lodfn,4*efvar(r9)# store function vrblk pointer
                   11801:        movl    r6,4*eflen(r9)  # store efblk length
                   11802:        movl    r9,r7           # save efblk pointer
                   11803:        addl2   r6,r9           # point past end of efblk
                   11804:                                # set number of arguments for loop
                   11805: #
                   11806: #      LOOP TO SET ARGUMENT TYPE CODES FROM STACK
                   11807: #
                   11808: slod6: movl    (sp)+,-(r9)     # store one type code from stack
                   11809:        sobgtr  r8,slod6        # loop till all stored
                   11810: #
                   11811: #      NOW LOAD THE EXTERNAL FUNCTION AND PERFORM DEFINITION
                   11812: #
                   11813:        movl    (sp)+,r9        # load function string name
                   11814:        movl    (sp),r10        # load library name
                   11815:        movl    r7,(sp)         # store efblk pointer
                   11816:        jsb     sysld           # call function to load external func
                   11817:        .long   er_142          # load function does not exist
                   11818:        .long   er_143          # load function caused input error during load
                   11819:        movl    (sp)+,r10       # recall efblk pointer
                   11820:        movl    r9,4*efcod(r10) # store code pointer
                   11821:        movl    lodfn,r9        # point to vrblk for function
                   11822:        jsb     dffnc           # perform function definition
                   11823:        jmp     exnul           # return null result
                   11824:        #page   
                   11825: #
                   11826: #      LPAD
                   11827: #
                   11828: s$lpd:                         # entry point
                   11829:        jsb     gtstg           # get pad character
                   11830:        .long   er_144          # lpad third argument not a string
                   11831:        movab   cfp$f(r9),r9    # point to character (null is blank)
                   11832:        movzbl  (r9),r7         # load pad character
                   11833:        jsb     gtsmi           # get pad length
                   11834:        .long   er_145          # lpad second argument is not integer
                   11835:        .long   slpd3           # skip if negative or large
                   11836: #
                   11837: #      MERGE TO CHECK FIRST ARG
                   11838: #
                   11839: slpd1: jsb     gtstg           # get first argument (string to pad)
                   11840:        .long   er_146          # lpad first argument is not string
                   11841:        cmpl    r6,r8           # return 1st arg if too long to pad
                   11842:        blssu   0f
                   11843:        jmp     exixr
                   11844: 0:             
                   11845:        movl    r9,r10          # else move ptr to string to pad
                   11846: #
                   11847: #      NOW WE ARE READY FOR THE PAD
                   11848: #
                   11849: #      (XL)                  POINTER TO STRING TO PAD
                   11850: #      (WB)                  PAD CHARACTER
                   11851: #      (WC)                  LENGTH TO PAD STRING TO
                   11852: #
                   11853:        movl    r8,r6           # copy length
                   11854:        jsb     alocs           # allocate scblk for new string
                   11855:        movl    r9,-(sp)        # save as result
                   11856:        movl    4*sclen(r10),r6 # load length of argument
                   11857:        subl2   r6,r8           # calculate number of pad characters
                   11858:        movab   cfp$f(r9),r9    # point to chars in result string
                   11859:                                # set counter for pad loop
                   11860: #
                   11861: #      LOOP TO PERFORM PAD
                   11862: #
                   11863: slpd2: movb    r7,(r9)+        # store pad character, bump ptr
                   11864:        sobgtr  r8,slpd2        # loop till all pad chars stored
                   11865:        #csc    r9              # complete store characters
                   11866: #
                   11867: #      NOW COPY STRING
                   11868: #
                   11869:        tstl    r6              # exit if null string
                   11870:        bnequ   0f
                   11871:        jmp     exits
                   11872: 0:             
                   11873:        movab   cfp$f(r10),r10  # else point to chars in argument
                   11874:        jsb     sbmvc           # move characters to result string
                   11875:        jmp     exits           # jump for next code word
                   11876: #
                   11877: #      HERE IF 2ND ARG IS NEGATIVE OR LARGE
                   11878: #
                   11879: slpd3: clrl    r8              # zero pad count
                   11880:        jmp     slpd1           # merge
                   11881:        #page   
                   11882: #
                   11883: #      LT
                   11884: #
                   11885: s$ltf:                         # entry point
                   11886:        jsb     acomp           # call arithmetic comparison routine
                   11887:        .long   er_147          # lt first argument is not numeric
                   11888:        .long   er_148          # lt second argument is not numeric
                   11889:        .long   exnul           # return null if lt
                   11890:        .long   exfal           # fail if eq
                   11891:        .long   exfal           # fail if gt
                   11892:        #page   
                   11893: #
                   11894: #      NE
                   11895: #
                   11896: s$nef:                         # entry point
                   11897:        jsb     acomp           # call arithmetic comparison routine
                   11898:        .long   er_149          # ne first argument is not numeric
                   11899:        .long   er_150          # ne second argument is not numeric
                   11900:        .long   exnul           # return null if lt
                   11901:        .long   exfal           # fail if eq
                   11902:        .long   exnul           # return null if gt
                   11903:        #page   
                   11904: #
                   11905: #      NOTANY
                   11906: #
                   11907: s$nay:                         # entry point
                   11908:        movl    $p$nas,r7       # set pcode for single char arg
                   11909:        movl    $p$nay,r10      # pcode for multi-char arg
                   11910:        movl    $p$nad,r8       # set pcode for expr arg
                   11911:        jsb     patst           # call common routine to build node
                   11912:        .long   er_151          # notany argument is not string or expression
                   11913:        jmp     exixr           # jump for next code word
                   11914:        #page   
                   11915: #
                   11916: #      OPSYN
                   11917: #
                   11918: s$ops:                         # entry point
                   11919:        jsb     gtsmi           # load third argument
                   11920:        .long   er_152          # opsyn third argument is not integer
                   11921:        .long   er_153          # opsyn third argument is negative or too large
                   11922:        movl    r8,r7           # if ok, save third argumnet
                   11923:        movl    (sp)+,r9        # load second argument
                   11924:        jsb     gtnvr           # locate variable block
                   11925:        .long   er_154          # opsyn second arg is not natural variable name
                   11926:        movl    4*vrfnc(r9),r10 # if ok, load function block pointer
                   11927:        tstl    r7              # jump if operator opsyn case
                   11928:        bnequ   sops2
                   11929: #
                   11930: #      HERE FOR FUNCTION OPSYN (THIRD ARG ZERO)
                   11931: #
                   11932:        movl    (sp)+,r9        # load first argument
                   11933:        jsb     gtnvr           # get vrblk pointer
                   11934:        .long   er_155          # opsyn first arg is not natural variable name
                   11935: #
                   11936: #      MERGE HERE TO PERFORM FUNCTION DEFINITION
                   11937: #
                   11938: sops1: jsb     dffnc           # call function definer
                   11939:        jmp     exnul           # exit with null result
                   11940: #
                   11941: #      HERE FOR OPERATOR OPSYN (THIRD ARG NON-ZERO)
                   11942: #
                   11943: sops2: jsb     gtstg           # get operator name
                   11944:        .long   sops5           # jump if not string
                   11945:        cmpl    r6,$num01       # error if not one char long
                   11946:        bnequ   sops5
                   11947:        movab   cfp$f(r9),r9    # else point to character
                   11948:        movzbl  (r9),r8         # load character name
                   11949:        #page   
                   11950: #
                   11951: #      OPSYN (CONTINUED)
                   11952: #
                   11953: #      NOW SET TO SEARCH FOR MATCHING UNARY OR BINARY OPERATOR
                   11954: #      NAME AS APPROPRIATE. NOTE THAT THERE ARE =OPBUN UNDEFINED
                   11955: #      BINARY OPERATORS AND =OPUUN UNDEFINED UNARY OPERATORS.
                   11956: #
                   11957:        movl    $r$uub,r6       # point to unop pointers in case
                   11958:        movl    $opnsu,r9       # point to names of unary operators
                   11959:        addl2   $opbun,r7       # add no. of undefined binary ops
                   11960:        cmpl    r7,$opuun       # jump if unop (third arg was 1)
                   11961:        beqlu   sops3
                   11962:        movl    $r$uba,r6       # else point to binary operator ptrs
                   11963:        movl    $opsnb,r9       # point to names of binary operators
                   11964:        movl    $opbun,r7       # set number of undefined binops
                   11965: #
                   11966: #      MERGE HERE TO CHECK LIST (WB = NUMBER TO CHECK)
                   11967: #
                   11968: sops3:                         # set counter to control loop
                   11969: #
                   11970: #      LOOP TO SEARCH FOR NAME MATCH
                   11971: #
                   11972: sops4: cmpl    r8,(r9)         # jump if names match
                   11973:        beqlu   sops6
                   11974:        addl2   $4,r6           # else push pointer to function ptr
                   11975:        addl2   $4,r9           # bump pointer
                   11976:        sobgtr  r7,sops4        # loop back till all checked
                   11977: #
                   11978: #      HERE IF BAD OPERATOR NAME
                   11979: #
                   11980: sops5: jmp     er_156          # opsyn first arg is not correct operator name
                   11981: #
                   11982: #      COME HERE ON FINDING A MATCH IN THE OPERATOR NAME TABLE
                   11983: #
                   11984: sops6: movl    r6,r9           # copy pointer to function block ptr
                   11985:        subl2   $4*vrfnc,r9     # make it look like dummy vrblk
                   11986:        jmp     sops1           # merge back to define operator
                   11987:        #page   
                   11988: #
                   11989: #      OUTPUT
                   11990: #
                   11991: s$oup:                         # entry point
                   11992:        movl    $num03,r7       # output flag
                   11993:        jsb     ioput           # call input/output assoc. routine
                   11994:        .long   er_157          # output third argument is not a string
                   11995:        .long   er_158          # inappropriate second argument for output
                   11996:        .long   er_159          # inappropriate first argument for output
                   11997:        .long   er_160          # inappropriate file specification for output
                   11998:        .long   exfal           # fail if file does not exist
                   11999:        .long   er_161          # output file cannot be written to
                   12000:        jmp     exnul           # return null string
                   12001:        #page   
                   12002: #
                   12003: #      POS
                   12004: #
                   12005: s$pos:                         # entry point
                   12006:        movl    $p$pos,r7       # set pcode for integer arg case
                   12007:        movl    $p$psd,r6       # set pcode for expression arg case
                   12008:        jsb     patin           # call common routine to build node
                   12009:        .long   er_162          # pos argument is not integer or expression
                   12010:        .long   er_163          # pos argument is negative or too large
                   12011:        jmp     exixr           # return pattern node
                   12012:        #page   
                   12013: #
                   12014: #      PROTOTYPE
                   12015: #
                   12016: s$pro:                         # entry point
                   12017:        movl    (sp)+,r9        # load argument
                   12018:        movl    4*tblen(r9),r7  # length if table, vector (=vclen)
                   12019:        ashl    $-2,r7,r7       # convert to words
                   12020:        movl    (r9),r6         # load type word of argument block
                   12021:        cmpl    r6,$b$art       # jump if array
                   12022:        beqlu   spro4
                   12023:        cmpl    r6,$b$tbt       # jump if table
                   12024:        beqlu   spro1
                   12025:        cmpl    r6,$b$vct       # jump if vector
                   12026:        beqlu   spro3
                   12027:        cmpl    r6,$b$bct       # jump if buffer
                   12028:        beqlu   spr05
                   12029:        jmp     er_164          # prototype argument is not valid object
                   12030: #
                   12031: #      HERE FOR TABLE
                   12032: #
                   12033: spro1: subl2   $tbsi$,r7       # subtract standard fields
                   12034: #
                   12035: #      MERGE FOR VECTOR
                   12036: #
                   12037: spro2: movl    r7,r5           # convert to integer
                   12038:        jmp     exint           # exit with integer result
                   12039: #
                   12040: #      HERE FOR VECTOR
                   12041: #
                   12042: spro3: subl2   $vcsi$,r7       # subtract standard fields
                   12043:        jmp     spro2           # merge
                   12044: #
                   12045: #      HERE FOR ARRAY
                   12046: #
                   12047: spro4: addl2   4*arofs(r9),r9  # point to prototype field
                   12048:        movl    (r9),r9         # load prototype
                   12049:        jmp     exixr           # return prototype as result
                   12050: #
                   12051: #      HERE FOR BUFFER
                   12052: #
                   12053: spr05: movl    4*bcbuf(r9),r9  # point to bfblk
                   12054:        movl    4*bfalc(r9),r5  # load allocated length
                   12055:        jmp     exint           # exit with integer allocation
                   12056:        #page   
                   12057: #
                   12058: #      REMDR
                   12059: #
                   12060: s$rmd:                         # entry point
                   12061:        clrl    r7              # set positive flag
                   12062:        movl    (sp),r9         # load second argument
                   12063:        jsb     gtint           # convert to integer
                   12064:        .long   er_165          # remdr second argument is not integer
                   12065:        jsb     arith           # convert args
                   12066:        .long   srm01           # first arg not integer
                   12067:        .long   invalid$        # second arg checked above
                   12068:        .long   srm01           # first arg real
                   12069:        movl    4*icval(r9),r5  # load left argument value
                   12070:        ashq    $-32,r4,r4      # get remainder
                   12071:        ediv    4*icval(r10),r4,r11,r5
                   12072:        bvs     0f
                   12073:        jmp     exint
                   12074: 0:             
                   12075:        jmp     er_167          # remdr caused integer overflow
                   12076: #
                   12077: #      FAIL FIRST ARGUMENT
                   12078: #
                   12079: srm01: jmp     er_166          # remdr first argument is not integer
                   12080:        #page   
                   12081: #
                   12082: #      REPLACE
                   12083: #
                   12084: #      THE ACTUAL REPLACE OPERATION USES AN SCBLK WHOSE CFP$A
                   12085: #      CHARS CONTAIN THE TRANSLATED VERSIONS OF ALL THE CHARS.
                   12086: #      THE TABLE POINTER IS REMEMBERED FROM CALL TO CALL AND
                   12087: #      THE TABLE IS ONLY BUILT WHEN THE ARGUMENTS CHANGE.
                   12088: #
                   12089: s$rpl:                         # entry point
                   12090:        jsb     gtstg           # load third argument as string
                   12091:        .long   er_168          # replace third argument is not string
                   12092:        movl    r9,r10          # save third arg ptr
                   12093:        jsb     gtstg           # get second argument
                   12094:        .long   er_169          # replace second argument is not string
                   12095: #
                   12096: #      CHECK TO SEE IF THIS IS THE SAME TABLE AS LAST TIME
                   12097: #
                   12098:        cmpl    r9,r$ra2        # jump if 2nd argument different
                   12099:        bnequ   srpl1
                   12100:        cmpl    r10,r$ra3       # jump if args same as last time
                   12101:        bnequ   0f
                   12102:        jmp     srpl4
                   12103: 0:             
                   12104: #
                   12105: #      HERE WE BUILD A NEW REPLACE TABLE (NOTE WA = 2ND ARG LEN)
                   12106: #
                   12107: srpl1: movl    4*sclen(r10),r7 # load 3rd argument length
                   12108:        cmpl    r6,r7           # jump if arguments not same length
                   12109:        beqlu   0f
                   12110:        jmp     srpl5
                   12111: 0:             
                   12112:        tstl    r7              # jump if null 2nd argument
                   12113:        bnequ   0f
                   12114:        jmp     srpl5
                   12115: 0:             
                   12116:        movl    r10,r$ra3       # save third arg for next time in
                   12117:        movl    r9,r$ra2        # save second arg for next time in
                   12118:        movl    kvalp,r10       # point to alphabet string
                   12119:        movl    4*sclen(r10),r6 # load alphabet scblk length
                   12120:        movl    r$rpt,r9        # point to current table (if any)
                   12121:        bnequ   srpl2           # jump if we already have a table
                   12122: #
                   12123: #      HERE WE ALLOCATE A NEW TABLE
                   12124: #
                   12125:        jsb     alocs           # allocate new table
                   12126:        movl    r8,r6           # keep scblk length
                   12127:        movl    r9,r$rpt        # save table pointer for next time
                   12128: #
                   12129: #      MERGE HERE WITH POINTER TO NEW TABLE BLOCK IN (XR)
                   12130: #
                   12131: srpl2: movab   3+(4*scsi$)(r6),r6 # compute length of scblk
                   12132:        bicl2   $3,r6
                   12133:        jsb     sbmvw           # copy to get initial table values
                   12134:        #page   
                   12135: #
                   12136: #      REPLACE (CONTINUED)
                   12137: #
                   12138: #      NOW WE MUST PLUG SELECTED ENTRIES AS REQUIRED. NOTE THAT
                   12139: #      WE ARE SHORT OF INDEX REGISTERS FOR THE FOLLOWING LOOP.
                   12140: #      HENCE THE NEED TO REPEATEDLY RE-INITIALISE CHAR PTR XL
                   12141: #
                   12142:        movl    r$ra2,r10       # point to second argument
                   12143:                                # number of chars to plug
                   12144:        clrl    r8              # zero char offset
                   12145:        movl    r$ra3,r9        # point to 3rd arg
                   12146:        movab   cfp$f(r9),r9    # get char ptr for 3rd arg
                   12147: #
                   12148: #      LOOP TO PLUG CHARS
                   12149: #
                   12150: srpl3: movl    r$ra2,r10       # point to 2nd arg
                   12151:        movab   cfp$f(r10)[r8],r10 # point to next char
                   12152:        incl    r8              # increment offset
                   12153:        movzbl  (r10),r6        # get next char
                   12154:        movl    r$rpt,r10       # point to translate table
                   12155:        movab   cfp$f(r10)[r6],r10 # convert char to offset into table
                   12156:        movzbl  (r9)+,r6        # get translated char
                   12157:        movb    r6,(r10)        # store in table
                   12158:        #csc    r10             # complete store characters
                   12159:        sobgtr  r7,srpl3        # loop till done
                   12160:        #page   
                   12161: #
                   12162: #      REPLACE (CONTINUED)
                   12163: #
                   12164: #      HERE TO PERFORM TRANSLATE
                   12165: #
                   12166: srpl4: jsb     gtstg           # get first argument
                   12167:        .long   er_170          # replace first argument is not string
                   12168:        tstl    r6              # return null if null argument
                   12169:        bnequ   0f
                   12170:        jmp     exnul
                   12171: 0:             
                   12172:        movl    r9,r10          # copy pointer
                   12173:        movl    r6,r8           # save length
                   12174:        movab   3+(4*schar)(r6),r6 # get scblk length
                   12175:        bicl2   $3,r6
                   12176:        jsb     alloc           # allocate space for copy
                   12177:        movl    r9,r7           # save address of copy
                   12178:        jsb     sbmvw           # move scblk contents to copy
                   12179:        movl    r$rpt,r9        # point to replace table
                   12180:        movab   cfp$f(r9),r9    # point to chars of table
                   12181:        movl    r7,r10          # point to string to translate
                   12182:        movab   cfp$f(r10),r10  # point to chars of string
                   12183:        movl    r8,r6           # set number of chars to translate
                   12184:        jsb     sbtrc           # perform translation
                   12185:        movl    r7,-(sp)        # stack new string as result
                   12186:        jmp     exits           # return with result on stack
                   12187: #
                   12188: #      ERROR POINT
                   12189: #
                   12190: srpl5: jmp     er_171          # null or unequally long 2nd, 3rd args to replace
                   12191:        #page   
                   12192: #
                   12193: #      REWIND
                   12194: #
                   12195: s$rew:                         # entry point
                   12196:        jsb     iofcb           # call fcblk routine
                   12197:        .long   er_172          # rewind argument is not a suitable name
                   12198:        .long   er_173          # rewind argument is null
                   12199:        jsb     sysrw           # call system rewind function
                   12200:        .long   er_174          # rewind file does not exist
                   12201:        .long   er_175          # rewind file does not permit rewind
                   12202:        .long   er_176          # rewind caused non-recoverable error
                   12203:        jmp     exnul           # exit with null result if no error
                   12204:        #page   
                   12205: #
                   12206: #      REVERSE
                   12207: #
                   12208: s$rvs:                         # entry point
                   12209:        jsb     gtstg           # load string argument
                   12210:        .long   er_177          # reverse argument is not string
                   12211:        tstl    r6              # return argument if null
                   12212:        bnequ   0f
                   12213:        jmp     exixr
                   12214: 0:             
                   12215:        movl    r9,r10          # else save pointer to string arg
                   12216:        jsb     alocs           # allocate space for new scblk
                   12217:        movl    r9,-(sp)        # store scblk ptr on stack as result
                   12218:        movab   cfp$f(r9),r9    # prepare to store in new scblk
                   12219:        movab   cfp$f(r10)[r8],r10 # point past last char in argument
                   12220:                                # set loop counter
                   12221: #
                   12222: #      LOOP TO MOVE CHARS IN REVERSE ORDER
                   12223: #
                   12224: srvs1: movzbl  -(r10),r7       # load next char from argument
                   12225:        movb    r7,(r9)+        # store in result
                   12226:        sobgtr  r8,srvs1        # loop till all moved
                   12227:        #csc    r9              # complete store characters
                   12228:        jmp     exits           # and then jump for next code word
                   12229:        #page   
                   12230: #
                   12231: #      RPAD
                   12232: #
                   12233: s$rpd:                         # entry point
                   12234:        jsb     gtstg           # get pad character
                   12235:        .long   er_178          # rpad third argument is not string
                   12236:        movab   cfp$f(r9),r9    # point to character (null is blank)
                   12237:        movzbl  (r9),r7         # load pad character
                   12238:        jsb     gtsmi           # get pad length
                   12239:        .long   er_179          # rpad second argument is not integer
                   12240:        .long   srpd3           # skip if negative or large
                   12241: #
                   12242: #      MERGE TO CHECK FIRST ARG.
                   12243: #
                   12244: srpd1: jsb     gtstg           # get first argument (string to pad)
                   12245:        .long   er_180          # rpad first argument is not string
                   12246:        cmpl    r6,r8           # return 1st arg if too long to pad
                   12247:        blssu   0f
                   12248:        jmp     exixr
                   12249: 0:             
                   12250:        movl    r9,r10          # else move ptr to string to pad
                   12251: #
                   12252: #      NOW WE ARE READY FOR THE PAD
                   12253: #
                   12254: #      (XL)                  POINTER TO STRING TO PAD
                   12255: #      (WB)                  PAD CHARACTER
                   12256: #      (WC)                  LENGTH TO PAD STRING TO
                   12257: #
                   12258:        movl    r8,r6           # copy length
                   12259:        jsb     alocs           # allocate scblk for new string
                   12260:        movl    r9,-(sp)        # save as result
                   12261:        movl    4*sclen(r10),r6 # load length of argument
                   12262:        subl2   r6,r8           # calculate number of pad characters
                   12263:        movab   cfp$f(r9),r9    # point to chars in result string
                   12264:                                # set counter for pad loop
                   12265: #
                   12266: #      COPY ARGUMENT STRING
                   12267: #
                   12268:        tstl    r6              # jump if argument is null
                   12269:        beqlu   srpd2
                   12270:        movab   cfp$f(r10),r10  # else point to argument chars
                   12271:        jsb     sbmvc           # move characters to result string
                   12272: #
                   12273: #      LOOP TO SUPPLY PAD CHARACTERS
                   12274: #
                   12275: srpd2: movb    r7,(r9)+        # store pad character, bump ptr
                   12276:        sobgtr  r8,srpd2        # loop till all pad chars stored
                   12277:        #csc    r9              # complete character storing
                   12278:        jmp     exits           # and exit for next word
                   12279: #
                   12280: #      HERE IF 2ND ARG IS NEGATIVE OR LARGE
                   12281: #
                   12282: srpd3: clrl    r8              # zero pad count
                   12283:        jmp     srpd1           # merge
                   12284:        #page   
                   12285: #
                   12286: #      RTAB
                   12287: #
                   12288: s$rtb:                         # entry point
                   12289:        movl    $p$rtb,r7       # set pcode for integer arg case
                   12290:        movl    $p$rtd,r6       # set pcode for expression arg case
                   12291:        jsb     patin           # call common routine to build node
                   12292:        .long   er_181          # rtab argument is not integer or expression
                   12293:        .long   er_182          # rtab argument is negative or too large
                   12294:        jmp     exixr           # return pattern node
                   12295:        #page   
                   12296: #
                   12297: #      SET
                   12298: #
                   12299: s$set:                         # entry point
                   12300:        movl    (sp)+,r$io2     # save third arg
                   12301:        movl    (sp)+,r$io1     # save second arg
                   12302:        jsb     iofcb           # call fcblk routine
                   12303:        .long   er_291          # set first argument is not a suitable name
                   12304:        .long   er_292          # set first argument is null
                   12305:        movl    r$io1,r7        # load second arg
                   12306:        movl    r$io2,r8        # load third arg
                   12307:        jsb     sysst           # call system set routine
                   12308:        .long   er_293          # inappropriate second argument to set
                   12309:        .long   er_294          # inappropriate third argument to set
                   12310:        .long   er_295          # set file does not exist
                   12311:        .long   er_296          # set file does not permit setting file pointer
                   12312:        .long   er_297          # set caused non-recoverable i/o error
                   12313:        jmp     exnul           # otherwisew return null
                   12314:        #page   
                   12315: #
                   12316: #      TAB
                   12317: #
                   12318: s$tab:                         # entry point
                   12319:        movl    $p$tab,r7       # set pcode for integer arg case
                   12320:        movl    $p$tbd,r6       # set pcode for expression arg case
                   12321:        jsb     patin           # call common routine to build node
                   12322:        .long   er_183          # tab argument is not integer or expression
                   12323:        .long   er_184          # tab argument is negative or too large
                   12324:        jmp     exixr           # return pattern node
                   12325:        #page   
                   12326: #
                   12327: #      RPOS
                   12328: #
                   12329: s$rps:                         # entry point
                   12330:        movl    $p$rps,r7       # set pcode for integer arg case
                   12331:        movl    $p$rpd,r6       # set pcode for expression arg case
                   12332:        jsb     patin           # call common routine to build node
                   12333:        .long   er_185          # rpos argument is not integer or expression
                   12334:        .long   er_186          # rpos argument is negative or too large
                   12335:        jmp     exixr           # return pattern node
                   12336:        #page   
                   12337: #
                   12338: #      RSORT
                   12339: #
                   12340: s$rsr:                         # entry point
                   12341:        movl    sp,r6           # mark as rsort
                   12342:        jsb     sorta           # call sort routine
                   12343:        jmp     exsid           # return, setting idval
                   12344:        #page   
                   12345: #
                   12346: #      SETEXIT
                   12347: #
                   12348: s$stx:                         # entry point
                   12349:        movl    (sp)+,r9        # load argument
                   12350:        movl    stxvr,r6        # load old vrblk pointer
                   12351:        clrl    r10             # load zero in case null arg
                   12352:        cmpl    r9,$nulls       # jump if null argument (reset call)
                   12353:        beqlu   sstx1
                   12354:        jsb     gtnvr           # else get specified vrblk
                   12355:        .long   sstx2           # jump if not natural variable
                   12356:        movl    4*vrlbl(r9),r10 # else load label
                   12357:        cmpl    r10,$stndl      # jump if label is not defined
                   12358:        beqlu   sstx2
                   12359:        cmpl    (r10),$b$trt    # jump if not trapped
                   12360:        bnequ   sstx1
                   12361:        movl    4*trlbl(r10),r10# else load ptr to real label code
                   12362: #
                   12363: #      HERE TO SET/RESET SETEXIT TRAP
                   12364: #
                   12365: sstx1: movl    r9,stxvr        # store new vrblk pointer (or null)
                   12366:        movl    r10,r$sxc       # store new code ptr (or zero)
                   12367:        cmpl    r6,$nulls       # return null if null result
                   12368:        bnequ   0f
                   12369:        jmp     exnul
                   12370: 0:             
                   12371:        movl    r6,r9           # else copy vrblk pointer
                   12372:        jmp     exvnm           # and return building nmblk
                   12373: #
                   12374: #      HERE IF BAD ARGUMENT
                   12375: #
                   12376: sstx2: jmp     er_187          # setexit argument is not label name or null
                   12377:        #page   
                   12378: #
                   12379: #      SORT
                   12380: #
                   12381: s$srt:                         # entry point
                   12382:        clrl    r6              # mark as sort
                   12383:        jsb     sorta           # call sort routine
                   12384:        jmp     exsid           # return, setting idval
                   12385:        #page   
                   12386: #
                   12387: #      SPAN
                   12388: #
                   12389: s$spn:                         # entry point
                   12390:        movl    $p$sps,r7       # set pcode for single char arg
                   12391:        movl    $p$spn,r10      # set pcode for multi-char arg
                   12392:        movl    $p$spd,r8       # set pcode for expression arg
                   12393:        jsb     patst           # call common routine to build node
                   12394:        .long   er_188          # span argument is not string or expression
                   12395:        jmp     exixr           # jump for next code word
                   12396:        #page   
                   12397: #
                   12398: #      SIZE
                   12399: #
                   12400: s$si$:                         # entry point
                   12401:        movl    (sp),r9         # load argument
                   12402:        cmpl    (r9),$b$bct     # branch if not buffer
                   12403:        bnequ   ssi$1
                   12404:        addl2   $4,sp           # else pop argument
                   12405:        movl    4*bclen(r9),r5  # load defined length
                   12406:        jmp     exint           # exit with integer
                   12407: #
                   12408: #      HERE IF NOT BUFFER
                   12409: #
                   12410: ssi$1: jsb     gtstg           # load string argument
                   12411:        .long   er_189          # size argument is not string
                   12412:        movl    r6,r5           # load length as integer
                   12413:        jmp     exint           # exit with integer result
                   12414:        #page   
                   12415: #
                   12416: #      STOPTR
                   12417: #
                   12418: s$stt:                         # entry point
                   12419:        clrl    r10             # indicate stoptr case
                   12420:        jsb     trace           # call trace procedure
                   12421:        .long   er_190          # stoptr first argument is not appropriate name
                   12422:        .long   er_191          # stoptr second argument is not trace type
                   12423:        jmp     exnul           # return null
                   12424:        #page   
                   12425: #
                   12426: #      SUBSTR
                   12427: #
                   12428: s$sub:                         # entry point
                   12429:        jsb     gtsmi           # load third argument
                   12430:        .long   er_192          # substr third argument is not integer
                   12431:        .long   exfal           # jump if negative or too large
                   12432:        movl    r9,sbssv        # save third argument
                   12433:        jsb     gtsmi           # load second argument
                   12434:        .long   er_193          # substr second argument is not integer
                   12435:        .long   exfal           # jump if out of range
                   12436:        movl    r9,r7           # save second argument
                   12437:        bnequ   0f              # jump if second argument zero
                   12438:        jmp     exfal
                   12439: 0:             
                   12440:        decl    r7              # else decrement for ones origin
                   12441:        movl    (sp),r10        # get first arg ptr
                   12442:        cmpl    (r10),$b$bct    # branch if not buffer
                   12443:        bnequ   ssuba
                   12444:        movl    4*bcbuf(r10),r9 # get bfblk ptr
                   12445:        movl    4*bclen(r10),r6 # get length
                   12446:        jmp     ssubb           # merge
                   12447: #
                   12448: #      HERE IF NOT BUFFER TO GET STRING
                   12449: #
                   12450: ssuba: jsb     gtstg           # load first argument
                   12451:        .long   er_194          # substr first argument is not string
                   12452: #
                   12453: #      MERGE WITH BFBLK OR SCBLK PTR IN XR.  WA HAS LENGTH
                   12454: #
                   12455: ssubb: movl    sbssv,r8        # reload third argument
                   12456:        bnequ   ssub1           # skip if third arg given
                   12457:        movl    r6,r8           # else get string length
                   12458:        cmpl    r7,r8           # fail if improper
                   12459:        blequ   0f
                   12460:        jmp     exfal
                   12461: 0:             
                   12462:        subl2   r7,r8           # reduce by offset to start
                   12463: #
                   12464: #      MERGE
                   12465: #
                   12466: ssub1: movl    r6,r10          # save string length
                   12467:        movl    r8,r6           # set length of substring
                   12468:        addl2   r7,r8           # add 2nd arg to 3rd arg
                   12469:        cmpl    r8,r10          # jump if improper substring
                   12470:        blequ   0f
                   12471:        jmp     exfal
                   12472: 0:             
                   12473:        movl    r9,r10          # copy pointer to first arg
                   12474:        jsb     sbstr           # build substring
                   12475:        jmp     exixr           # and jump for next code word
                   12476:        #page   
                   12477: #
                   12478: #      TABLE
                   12479: #
                   12480: s$tbl:                         # entry point
                   12481:        movl    (sp)+,r10       # get initial lookup value
                   12482:        addl2   $4,sp           # pop second argument
                   12483:        jsb     gtsmi           # load argument
                   12484:        .long   er_195          # table argument is not integer
                   12485:        .long   er_196          # table argument is out of range
                   12486:        tstl    r8              # jump if non-zero
                   12487:        bnequ   stbl1
                   12488:        movl    $tbnbk,r8       # else supply default value
                   12489: #
                   12490: #      MERGE HERE WITH NUMBER OF HEADERS IN WA
                   12491: #
                   12492: stbl1: movl    r8,r6           # copy number of headers
                   12493:        addl2   $tbsi$,r6       # adjust for standard fields
                   12494:        moval   0[r6],r6        # convert length to bytes
                   12495:        jsb     alloc           # allocate space for tbblk
                   12496:        movl    r9,r7           # copy pointer to tbblk
                   12497:        movl    $b$tbt,(r9)+    # store type word
                   12498:        clrl    (r9)+           # zero id for the moment
                   12499:        movl    r6,(r9)+        # store length (tblen)
                   12500:        movl    r10,(r9)+       # store initial lookup value
                   12501:                                # set loop counter (num headers)
                   12502: #
                   12503: #      LOOP TO INITIALIZE ALL BUCKET POINTERS
                   12504: #
                   12505: stbl2: movl    r7,(r9)+        # store tbblk ptr in bucket header
                   12506:        sobgtr  r8,stbl2        # loop till all stored
                   12507:        movl    r7,r9           # recall pointer to tbblk
                   12508:        jmp     exsid           # exit setting idval
                   12509:        #page   
                   12510: #
                   12511: #      TIME
                   12512: #
                   12513: s$tim:                         # entry point
                   12514:        jsb     systm           # get timer value
                   12515:        subl2   timsx,r5        # subtract starting time
                   12516:        jmp     exint           # exit with integer value
                   12517:        #page   
                   12518: #
                   12519: #      TRACE
                   12520: #
                   12521: s$tra:                         # entry point
                   12522:        cmpl    4*3(sp),$nulls  # jump if first argument is null
                   12523:        beqlu   str03
                   12524:        movl    (sp)+,r9        # load fourth argument
                   12525:        clrl    r10             # tentatively set zero pointer
                   12526:        cmpl    r9,$nulls       # jump if 4th argument is null
                   12527:        beqlu   str02
                   12528:        jsb     gtnvr           # else point to vrblk
                   12529:        .long   str01           # jump if not variable name
                   12530:        movl    4*vrfnc(r9),r10 # else load function pointer
                   12531:        cmpl    r10,$stndf      # jump if function is defined
                   12532:        bnequ   str02
                   12533: #
                   12534: #      HERE FOR BAD FOURTH ARGUMENT
                   12535: #
                   12536: str01: jmp     er_197          # trace fourth arg is not function name or null
                   12537: #
                   12538: #      HERE WITH FUNCTION POINTER IN XL
                   12539: #
                   12540: str02: movl    (sp)+,r9        # load third argument (tag)
                   12541:        clrl    r7              # set zero as trtyp value for now
                   12542:        jsb     trbld           # build trblk for trace call
                   12543:        movl    r9,r10          # move trblk pointer for trace
                   12544:        jsb     trace           # call trace procedure
                   12545:        .long   er_198          # trace first argument is not appropriate name
                   12546:        .long   er_199          # trace second argument is not trace type
                   12547:        jmp     exnul           # return null
                   12548: #
                   12549: #      HERE TO CALL SYSTEM TRACE TOGGLE ROUTINE
                   12550: #
                   12551: str03: jsb     systt           # call it
                   12552:        addl2   $4*num04,sp     # pop trace arguments
                   12553:        jmp     exnul           # return
                   12554:        #page   
                   12555: #
                   12556: #      TRIM
                   12557: #
                   12558: s$trm:                         # entry point
                   12559:        jsb     gtstg           # load argument as string
                   12560:        .long   er_200          # trim argument is not string
                   12561:        tstl    r6              # return null if argument is null
                   12562:        bnequ   0f
                   12563:        jmp     exnul
                   12564: 0:             
                   12565:        movl    r9,r10          # copy string pointer
                   12566:        movab   3+(4*schar)(r6),r6 # get block length
                   12567:        bicl2   $3,r6
                   12568:        jsb     alloc           # allocate copy same size
                   12569:        movl    r9,r7           # save pointer to copy
                   12570:        jsb     sbmvw           # copy old string block to new
                   12571:        movl    r7,r9           # restore ptr to new block
                   12572:        jsb     trimr           # trim blanks (wb is non-zero)
                   12573:        jmp     exixr           # exit with result in xr
                   12574:        #page   
                   12575: #
                   12576: #      UNLOAD
                   12577: #
                   12578: s$unl:                         # entry point
                   12579:        movl    (sp)+,r9        # load argument
                   12580:        jsb     gtnvr           # point to vrblk
                   12581:        .long   er_201          # unload argument is not natural variable name
                   12582:        movl    $stndf,r10      # get ptr to undefined function
                   12583:        jsb     dffnc           # undefine named function
                   12584:        jmp     exnul           # return null as result
                   12585:        #title  s p i t b o l -- utility procedures
                   12586: #
                   12587: #      THE FOLLOWING SECTION CONTAINS PROCEDURES WHICH ARE
                   12588: #      USED FOR VARIOUS PURPOSES THROUGHOUT THE SYSTEM.
                   12589: #
                   12590: #      EACH PROCEDURE IS PRECEDED BY A DESCRIPTION OF THE
                   12591: #      CALLING SEQUENCE. USUALLY THE ARGUMENTS ARE IN REGISTERS
                   12592: #      BUT ARGUMENTS CAN ALSO OCCUR ON THE STACK AND AS
                   12593: #      PARAMETERS ASSEMBLED AFTER THE JSR INSTRUCTION.
                   12594: #
                   12595: #      THE FOLLOWING CONSIDERATIONS APPLY TO THESE DESCRIPTIONS.
                   12596: #
                   12597: #      1)   THE STACK POINTER (XS) IS NOT CHANGED UNLESS THE
                   12598: #           CHANGE IS EXPLICITLY DOCUMENTED IN THE CALL.
                   12599: #
                   12600: #      2)   REGISTERS WHOSE ENTRY VALUES ARE NOT MENTIONED
                   12601: #           MAY CONTAIN ANY VALUE EXCEPT THAT XL,XR MAY ONLY
                   12602: #           CONTAIN PROPER (COLLECTABLE) POINTER VALUES.
                   12603: #           THIS CONDITION ON XR MEANS THAT THE CALLED ROUTINE
                   12604: #           MAY IF IT CHOOSES PRESERVE XR BY STACKING.
                   12605: #
                   12606: #      3)   REGISTERS NOT MENTIONED ON EXIT CONTAIN THE SAME
                   12607: #           VALUES AS THEY DID ON ENTRY EXCEPT THAT VALUES IN
                   12608: #           XR,XL MAY HAVE BEEN RELOCATED BY THE COLLECTOR.
                   12609: #
                   12610: #      4)   REGISTERS WHICH ARE DESTROYED ON EXIT MAY CONTAIN
                   12611: #           ANY VALUE EXCEPT THAT VALUES IN XL,XR ARE PROPER
                   12612: #           (COLLECTABLE) POINTERS.
                   12613: #
                   12614: #      5)   THE CODE POINTER REGISTER POINTS TO THE CURRENT
                   12615: #           CODE LOCATION ON ENTRY AND IS UNCHANGED ON EXIT.
                   12616: #
                   12617: #      IN THE ABOVE DESCRIPTION, A COLLECTABLE POINTER IS ONE
                   12618: #      WHICH EITHER POINTS OUTSIDE THE DYNAMIC REGION OR
                   12619: #      POINTS TO THE START OF A BLOCK IN THE DYNAMIC REGION.
                   12620: #
                   12621: #      IN THOSE CASES WHERE THE CALLING SEQUENCE CONTAINS
                   12622: #      PARAMETERS WHICH ARE USED AS ALTERNATE RETURN POINTS,
                   12623: #      THESE PARAMETERS MAY BE REPLACED BY ERROR CODES
                   12624: #      ASSEMBLED WITH THE ERR INSTRUCTION. THIS WILL RESULT
                   12625: #      IN THE POSTING OF THE ERROR IF THE RETURN IS TAKEN.
                   12626: #
                   12627: #      THE PROCEDURES ALL HAVE NAMES CONSISTING OF FIVE LETTERS
                   12628: #      AND ARE IN ALPHABETICAL ORDER BY THEIR NAMES.
                   12629:        #page   
                   12630: #
                   12631: #      ACESS - ACCESS VARIABLE VALUE WITH TRACE/INPUT CHECKS
                   12632: #
                   12633: #      ACESS LOADS THE VALUE OF A VARIABLE. TRACE AND INPUT
                   12634: #      ASSOCIATIONS ARE TESTED FOR AND EXECUTED AS REQUIRED.
                   12635: #      ACESS ALSO HANDLES THE SPECIAL CASES OF PSEUDO-VARIABLES.
                   12636: #
                   12637: #      (XL)                  VARIABLE NAME BASE
                   12638: #      (WA)                  VARIABLE NAME OFFSET
                   12639: #      JSR  ACESS            CALL TO ACCESS VALUE
                   12640: #      PPM  LOC              TRANSFER LOC IF ACCESS FAILURE
                   12641: #      (XR)                  VARIABLE VALUE
                   12642: #      (WA,WB,WC)            DESTROYED
                   12643: #      (XL,RA)               DESTROYED
                   12644: #
                   12645: #      FAILURE CAN OCCUR IF AN INPUT ASSOCIATION CAUSES AN END
                   12646: #      OF FILE CONDITION OR IF THE EVALUATION OF AN EXPRESSION
                   12647: #      ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS.
                   12648: #
                   12649: acess: #prc                    # entry point (recursive)
                   12650:        movl    r10,r9          # copy name base
                   12651:        addl2   r6,r9           # point to variable location
                   12652:        movl    (r9),r9         # load variable value
                   12653: #
                   12654: #      LOOP HERE TO CHECK FOR SUCCESSIVE TRBLKS
                   12655: #
                   12656: acs02: cmpl    (r9),$b$trt     # jump if not trapped
                   12657:        beqlu   0f
                   12658:        jmp     acs18
                   12659: 0:             
                   12660: #
                   12661: #      HERE IF TRAPPED
                   12662: #
                   12663:        cmpl    r9,$trbkv       # jump if keyword variable
                   12664:        bnequ   0f
                   12665:        jmp     acs12
                   12666: 0:             
                   12667:        cmpl    r9,$trbev       # jump if not expression variable
                   12668:        bnequ   acs05
                   12669: #
                   12670: #      HERE FOR EXPRESSION VARIABLE, EVALUATE VARIABLE
                   12671: #
                   12672:        movl    4*evexp(r10),r9 # load expression pointer
                   12673:        clrl    r7              # evaluate by value
                   12674:        jsb     evalx           # evaluate expression
                   12675:        .long   acs04           # jump if evaluation failure
                   12676:        jmp     acs02           # check value for more trblks
                   12677:        #page   
                   12678: #
                   12679: #      ACESS (CONTINUED)
                   12680: #
                   12681: #      HERE ON READING END OF FILE
                   12682: #
                   12683: acs03: addl2   $4*num03,sp     # pop trblk ptr, name base and offset
                   12684:        movl    r9,dnamp        # pop unused scblk
                   12685: #
                   12686: #      MERGE HERE WHEN EVALUATION OF EXPRESSION FAILS
                   12687: #
                   12688: acs04: movl    (sp)+,r11       # take alternate (failure) return
                   12689:        jmp     *(r11)+
                   12690: #
                   12691: #      HERE IF NOT KEYWORD OR EXPRESSION VARIABLE
                   12692: #
                   12693: acs05: movl    4*trtyp(r9),r7  # load trap type code
                   12694:        beqlu   0f              # jump if not input association
                   12695:        jmp     acs10
                   12696: 0:             
                   12697:        tstl    kvinp           # ignore input assoc if input is off
                   12698:        bnequ   0f
                   12699:        jmp     acs09
                   12700: 0:             
                   12701: #
                   12702: #      HERE FOR INPUT ASSOCIATION
                   12703: #
                   12704:        movl    r10,-(sp)       # stack name base
                   12705:        movl    r6,-(sp)        # stack name offset
                   12706:        movl    r9,-(sp)        # stack trblk pointer
                   12707:        movl    4*trfpt(r9),r10 # get file ctrl blk ptr or zero
                   12708:        bnequ   acs06           # jump if not standard input file
                   12709:        cmpl    4*trter(r9),$v$ter # jump if terminal
                   12710:        bnequ   0f
                   12711:        jmp     acs21
                   12712: 0:             
                   12713: #
                   12714: #      HERE TO READ FROM STANDARD INPUT FILE
                   12715: #
                   12716:        movl    cswin,r6        # length for read buffer
                   12717:        jsb     alocs           # build string of appropriate length
                   12718:        jsb     sysrd           # read next standard input image
                   12719:        .long   acs03           # jump to fail exit if end of file
                   12720:        jmp     acs07           # else merge with other file case
                   12721: #
                   12722: #      HERE FOR INPUT FROM OTHER THAN STANDARD INPUT FILE
                   12723: #
                   12724: acs06: movl    r10,r6          # fcblk ptr
                   12725:        jsb     sysil           # get input record max length (to wa)
                   12726:        jsb     alocs           # allocate string of correct size
                   12727:        movl    r10,r6          # fcblk ptr
                   12728:        jsb     sysin           # call system input routine
                   12729:        .long   acs03           # jump to fail exit if end of file
                   12730:        .long   acs22           # error
                   12731:        .long   acs23           # error
                   12732:        #page   
                   12733: #
                   12734: #      ACESS (CONTINUED)
                   12735: #
                   12736: #      MERGE HERE AFTER OBTAINING INPUT RECORD
                   12737: #
                   12738: acs07: movl    kvtrm,r7        # load trim indicator
                   12739:        jsb     trimr           # trim record as required
                   12740:        movl    r9,r7           # copy result pointer
                   12741:        movl    (sp),r9         # reload pointer to trblk
                   12742: #
                   12743: #      LOOP TO CHASE TO END OF TRBLK CHAIN AND STORE VALUE
                   12744: #
                   12745: acs08: movl    r9,r10          # save pointer to this trblk
                   12746:        movl    4*trnxt(r9),r9  # load forward pointer
                   12747:        cmpl    (r9),$b$trt     # loop if this is another trblk
                   12748:        beqlu   acs08
                   12749:        movl    r7,4*trnxt(r10) # else store result at end of chain
                   12750:        movl    (sp)+,r9        # restore initial trblk pointer
                   12751:        movl    (sp)+,r6        # restore name offset
                   12752:        movl    (sp)+,r10       # restore name base pointer
                   12753: #
                   12754: #      COME HERE TO MOVE TO NEXT TRBLK
                   12755: #
                   12756: acs09: movl    4*trnxt(r9),r9  # load forward ptr to next value
                   12757:        jmp     acs02           # back to check if trapped
                   12758: #
                   12759: #      HERE TO CHECK FOR ACCESS TRACE TRBLK
                   12760: #
                   12761: acs10: cmpl    r7,$trtac       # loop back if not access trace
                   12762:        beqlu   0f
                   12763:        jmp     acs09
                   12764: 0:             
                   12765:        tstl    kvtra           # ignore access trace if trace off
                   12766:        bnequ   0f
                   12767:        jmp     acs09
                   12768: 0:             
                   12769:        decl    kvtra           # else decrement trace count
                   12770:        tstl    4*trfnc(r9)     # jump if print trace
                   12771:        beqlu   acs11
                   12772:        #page   
                   12773: #
                   12774: #      ACESS (CONTINUED)
                   12775: #
                   12776: #      HERE FOR FULL FUNCTION TRACE
                   12777: #
                   12778:        jsb     trxeq           # call routine to execute trace
                   12779:        jmp     acs09           # jump for next trblk
                   12780: #
                   12781: #      HERE FOR CASE OF PRINT TRACE
                   12782: #
                   12783: acs11: jsb     prtsn           # print statement number
                   12784:        jsb     prtnv           # print name = value
                   12785:        jmp     acs09           # jump back for next trblk
                   12786: #
                   12787: #      HERE FOR KEYWORD VARIABLE
                   12788: #
                   12789: acs12: movl    4*kvnum(r10),r9 # load keyword number
                   12790:        cmpl    r9,$k$v$$       # jump if not one word value
                   12791:        bgequ   acs14
                   12792:        movl    l^kvabe(r9),r5  # else load value as integer
                   12793: #
                   12794: #      COMMON EXIT WITH KEYWORD VALUE AS INTEGER IN (IA)
                   12795: #
                   12796: acs13: jsb     icbld           # build icblk
                   12797:        jmp     acs18           # jump to exit
                   12798: #
                   12799: #      HERE IF NOT ONE WORD KEYWORD VALUE
                   12800: #
                   12801: acs14: cmpl    r9,$k$s$$       # jump if special case
                   12802:        bgequ   acs15
                   12803:        subl2   $k$v$$,r9       # else get offset
                   12804:        addl2   $ndabo,r9       # point to pattern value
                   12805:        jmp     acs18           # jump to exit
                   12806: #
                   12807: #      HERE IF SPECIAL KEYWORD CASE
                   12808: #
                   12809: acs15: movl    kvrtn,r10       # load rtntype in case
                   12810:        movl    kvstl,r5        # load stlimit in case
                   12811:        subl2   $k$s$$,r9       # get case number
                   12812:        casel   r9,$0,$5                # switch on keyword number
                   12813: 5:             
                   12814:        .word   acs16-5b        # jump if alphabet
                   12815:        .word   acs17-5b        # rtntype
                   12816:        .word   acs19-5b        # stcount
                   12817:        .word   acs20-5b        # errtext
                   12818:        .word   acs13-5b        # stlimit
                   12819:        #esw                    # end switch on keyword number
                   12820:        #page   
                   12821: #
                   12822: #      ACESS (CONTINUED)
                   12823: #
                   12824: #      ALPHABET
                   12825: #
                   12826: acs16: movl    kvalp,r10       # load pointer to alphabet string
                   12827: #
                   12828: #      RTNTYPE MERGES HERE
                   12829: #
                   12830: acs17: movl    r10,r9          # copy string ptr to proper reg
                   12831: #
                   12832: #      COMMON RETURN POINT
                   12833: #
                   12834: acs18: addl2   $4*1,(sp)       # return to acess caller
                   12835:        rsb     
                   12836: #
                   12837: #      HERE FOR STCOUNT (IA HAS STLIMIT)
                   12838: #
                   12839: acs19: subl2   kvstc,r5        # stcount = limit - left
                   12840:        jmp     acs13           # merge back with integer result
                   12841: #
                   12842: #      ERRTEXT
                   12843: #
                   12844: acs20: movl    r$etx,r9        # get errtext string
                   12845:        jmp     acs18           # merge with result
                   12846: #
                   12847: #      HERE TO READ A RECORD FROM TERMINAL
                   12848: #
                   12849: acs21: movl    $rilen,r6       # buffer length
                   12850:        jsb     alocs           # allocate buffer
                   12851:        jsb     sysri           # read record
                   12852:        .long   acs03           # endfile
                   12853:        jmp     acs07           # merge with record read
                   12854: #
                   12855: #      ERROR RETURNS
                   12856: #
                   12857: acs22: movl    r9,dnamp        # pop unused scblk
                   12858:        jmp     er_202          # input from file caused non-recoverable error
                   12859: #
                   12860: acs23: movl    r9,dnamp        # pop unused scblk
                   12861:        jmp     er_203          # input file record has incorrect format
                   12862:        #enp                    # end procedure acess
                   12863:        #page   
                   12864: #
                   12865: #      ACOMP -- COMPARE TWO ARITHMETIC VALUES
                   12866: #
                   12867: #      1(XS)                 FIRST ARGUMENT
                   12868: #      0(XS)                 SECOND ARGUMENT
                   12869: #      JSR  ACOMP            CALL TO COMPARE VALUES
                   12870: #      PPM  LOC              TRANSFER LOC IF ARG1 IS NON-NUMERIC
                   12871: #      PPM  LOC              TRANSFER LOC IF ARG2 IS NON-NUMERIC
                   12872: #      PPM  LOC              TRANSFER LOC FOR ARG1 LT ARG2
                   12873: #      PPM  LOC              TRANSFER LOC FOR ARG1 EQ ARG2
                   12874: #      PPM  LOC              TRANSFER LOC FOR ARG1 GT ARG2
                   12875: #      (NORMAL RETURN IS NEVER GIVEN)
                   12876: #      (WA,WB,WC,IA,RA)      DESTROYED
                   12877: #      (XL,XR)               DESTROYED
                   12878: #
                   12879:        .data   1
                   12880: acomp_s:       .long   0
                   12881:        .text   0
                   12882: acomp: movl    (sp)+,acomp_s   # entry point
                   12883:        jsb     arith           # load arithmetic operands
                   12884:        .long   acmp7           # jump if first arg non-numeric
                   12885:        .long   acmp8           # jump if second arg non-numeric
                   12886:        .long   acmp4           # jump if real arguments
                   12887: #
                   12888: #      HERE FOR INTEGER ARGUMENTS
                   12889: #
                   12890:        subl2   4*icval(r10),r5 # subtract to compare
                   12891:        bvs     acmp3
                   12892:        tstl    r5              # else jump if arg1 lt arg2
                   12893:        blss    acmp5
                   12894:        tstl    r5              # jump if arg1 eq arg2
                   12895:        beql    acmp2
                   12896: #
                   12897: #      HERE IF ARG1 GT ARG2
                   12898: #
                   12899: acmp1: addl3   $4*4,acomp_s,r11        # take gt exit
                   12900:        jmp     *(r11)+
                   12901: #
                   12902: #      HERE IF ARG1 EQ ARG2
                   12903: #
                   12904: acmp2: addl3   $4*3,acomp_s,r11        # take eq exit
                   12905:        jmp     *(r11)+
                   12906:        #page   
                   12907: #
                   12908: #      ACOMP (CONTINUED)
                   12909: #
                   12910: #      HERE FOR INTEGER OVERFLOW ON SUBTRACT
                   12911: #
                   12912: acmp3: movl    4*icval(r10),r5 # load second argument
                   12913:        blss    acmp1           # gt if negative
                   12914:        jmp     acmp5           # else lt
                   12915: #
                   12916: #      HERE FOR REAL OPERANDS
                   12917: #
                   12918: acmp4: subf2   4*rcval(r10),r2 # subtract to compare
                   12919:        bvs     acmp6
                   12920:        tstf    r2              # else jump if arg1 gt
                   12921:        bgtr    acmp1
                   12922:        tstf    r2              # jump if arg1 eq arg2
                   12923:        beql    acmp2
                   12924: #
                   12925: #      HERE IF ARG1 LT ARG2
                   12926: #
                   12927: acmp5: addl3   $4*2,acomp_s,r11        # take lt exit
                   12928:        jmp     *(r11)+
                   12929: #
                   12930: #      HERE IF OVERFLOW ON REAL SUBTRACTION
                   12931: #
                   12932: acmp6: movf    4*rcval(r10),r2 # reload arg2
                   12933:        tstf    r2              # gt if negative
                   12934:        blss    acmp1
                   12935:        jmp     acmp5           # else lt
                   12936: #
                   12937: #      HERE IF ARG1 NON-NUMERIC
                   12938: #
                   12939: acmp7: movl    acomp_s,r11     # take error exit
                   12940:        jmp     *(r11)+
                   12941: #
                   12942: #      HERE IF ARG2 NON-NUMERIC
                   12943: #
                   12944: acmp8: addl3   $4*1,acomp_s,r11        # take error exit
                   12945:        jmp     *(r11)+
                   12946:        #enp                    # end procedure acomp
                   12947:        #page   
                   12948: #
                   12949: #      ALLOC                 ALLOCATE BLOCK OF DYNAMIC STORAGE
                   12950: #
                   12951: #      (WA)                  LENGTH REQUIRED IN BYTES
                   12952: #      JSR  ALLOC            CALL TO ALLOCATE BLOCK
                   12953: #      (XR)                  POINTER TO ALLOCATED BLOCK
                   12954: #
                   12955: #      A POSSIBLE ALTERNATIVE TO AOV .. AND FOLLOWING STMT IS -
                   12956: #      MOV  DNAME,XR .  SUB  WA,XR .  BLO XR,DNAMP,ALOC2 .
                   12957: #      MOV  DNAMP,XR .  ADD  WA,XR
                   12958: #
                   12959: alloc: #prc                    # entry point
                   12960: #
                   12961: #      COMMON EXIT POINT
                   12962: #
                   12963: aloc1: movl    dnamp,r9        # point to next available loc
                   12964:        addl2   r6,r9           # point past allocated block
                   12965:        bvc     0f
                   12966:        jmp     aloc2
                   12967: 0:             
                   12968:        cmpl    r9,dname        # jump if not enough room
                   12969:        bgtru   aloc2
                   12970:        movl    r9,dnamp        # store new pointer
                   12971:        subl2   r6,r9           # point back to start of allocated bk
                   12972:        rsb                     # return to caller
                   12973: #
                   12974: #      HERE IF INSUFFICIENT ROOM, TRY A GARBAGE COLLECTION
                   12975: #
                   12976: aloc2: movl    r7,allsv        # save wb
                   12977:        clrl    r7              # set no upward move for gbcol
                   12978:        jsb     gbcol           # garbage collect
                   12979: #
                   12980: #      SEE IF ROOM AFTER GBCOL OR SYSMM CALL
                   12981: #
                   12982: aloc3: movl    dnamp,r9        # point to first available loc
                   12983:        addl2   r6,r9           # point past new block
                   12984:        bvc     0f
                   12985:        jmp     alc3a
                   12986: 0:             
                   12987:        cmpl    r9,dname        # jump if there is room now
                   12988:        blequ   aloc4
                   12989: #
                   12990: #      FAILED AGAIN, SEE IF WE CAN GET MORE CORE
                   12991: #
                   12992: alc3a: jsb     sysmm           # try to get more memory
                   12993:        moval   0[r9],r9        # convert to baus (sgd05)
                   12994:        addl2   r9,dname        # bump ptr by amount obtained
                   12995:        tstl    r9              # jump if got more core
                   12996:        bnequ   aloc3
                   12997:        addl2   rsmem,dname     # get the reserve memory
                   12998:        clrl    rsmem           # only permissible once
                   12999:        incl    errft           # fatal error
                   13000:        jmp     er_204          # memory overflow
                   13001:        #page   
                   13002: #
                   13003: #      HERE AFTER SUCCESSFUL GARBAGE COLLECTION
                   13004: #
                   13005: aloc4: movl    r5,allia        # save ia
                   13006:        movl    dname,r7        # get dynamic end adrs
                   13007:        subl2   dnamp,r7        # compute free store
                   13008:        ashl    $-2,r7,r7       # convert bytes to words
                   13009:        movl    r7,r5           # put free store in ia
                   13010:        mull2   alfsf,r5        # multiply by free store factor
                   13011:        bvs     aloc5
                   13012:        movl    dname,r7        # dynamic end adrs
                   13013:        subl2   dnamb,r7        # compute total amount of dynamic
                   13014:        ashl    $-2,r7,r7       # convert to words
                   13015:        movl    r7,aldyn        # store it
                   13016:        subl2   aldyn,r5        # subtract from scaled up free store
                   13017:        bgtr    aloc5           # jump if sufficient free store
                   13018:        jsb     sysmm           # try to get more store
                   13019:        moval   0[r9],r9        # convert to baus (sgd05)
                   13020:        addl2   r9,dname        # adjust dynamic end adrs
                   13021: #
                   13022: #      MERGE TO RESTORE IA AND WB
                   13023: #
                   13024: aloc5: movl    allia,r5        # recover ia
                   13025:        movl    allsv,r7        # restore wb
                   13026:        jmp     aloc1           # jump back to exit
                   13027:        #enp                    # end procedure alloc
                   13028:        #page   
                   13029: #
                   13030: #      ALOBF -- ALLOCATE BUFFER
                   13031: #
                   13032: #      THIS ROUTINES ALLOCATES A NEW BUFFER.  AS THE BFBLK
                   13033: #      AND BCBLK COME IN PAIRS, BOTH ARE ALLOCATED HERE,
                   13034: #      AND XR POINTS TO THE BCBLK ON RETURN.  THE BFBLK
                   13035: #      AND BCBLK ARE SET TO THE NULL BUFFER, AND THE IDVAL
                   13036: #      IS ZERO ON RETURN.
                   13037: #
                   13038: #      (WA)                  BUFFER SIZE IN CHARACTERS
                   13039: #      JSR  ALOBF            CALL TO CREATE BUFFER
                   13040: #      (XR)                  BCBLK PTR
                   13041: #      (WA,WB)               DESTROYED
                   13042: #
                   13043: alobf: #prc                    # entry point
                   13044:        movl    r6,r7           # hang onto allocation size
                   13045:        movab   3+(4*bfsi$)(r6),r6 # get total block size
                   13046:        bicl2   $3,r6
                   13047:        cmpl    r6,mxlen        # check for maxlen exceeded
                   13048:        bgequ   alb01
                   13049:        addl2   $4*bcsi$,r6     # add in allocation for bcblk
                   13050:        jsb     alloc           # allocate frame
                   13051:        movl    $b$bct,(r9)     # set type
                   13052:        clrl    4*idval(r9)     # no id yet
                   13053:        clrl    4*bclen(r9)     # no defined length
                   13054:        movl    r10,r6          # save xl
                   13055:        movl    r9,r10          # copy bcblk ptr
                   13056:        addl2   $4*bcsi$,r10    # bias past partially built bcblk
                   13057:        movl    $b$bft,(r10)    # set bfblk type word
                   13058:        movl    r7,4*bfalc(r10) # set allocated size
                   13059:        movl    r10,4*bcbuf(r9) # set pointer in bcblk
                   13060:        clrl    4*bfchr(r10)    # clear first word (null pad)
                   13061:        movl    r6,r10          # restore entry xl
                   13062:        rsb                     # return to caller
                   13063: #
                   13064: #      HERE FOR MXLEN EXCEEDED
                   13065: #
                   13066: alb01: jmp     er_274          # requested buffer allocation exceeds mxlen
                   13067:        #enp                    # end procedure alobf
                   13068:        #page   
                   13069: #
                   13070: #      ALOCS -- ALLOCATE STRING BLOCK
                   13071: #
                   13072: #      ALOCS IS USED TO BUILD A FRAME FOR A STRING BLOCK INTO
                   13073: #      WHICH THE ACTUAL CHARACTERS ARE PLACED BY THE CALLER.
                   13074: #      ALL STRINGS ARE CREATED WITH A CALL TO ALOCS (THE
                   13075: #      EXCEPTIONS OCCUR IN TRIMR AND S$RPL PROCEDURES).
                   13076: #
                   13077: #      (WA)                  LENGTH OF STRING TO BE ALLOCATED
                   13078: #      JSR  ALOCS            CALL TO ALLOCATE SCBLK
                   13079: #      (XR)                  POINTER TO RESULTING SCBLK
                   13080: #      (WA)                  DESTROYED
                   13081: #      (WC)                  CHARACTER COUNT (ENTRY VALUE OF WA)
                   13082: #
                   13083: #      THE RESULTING SCBLK HAS THE TYPE WORD AND THE LENGTH
                   13084: #      FILLED IN AND THE LAST WORD IS CLEARED TO ZERO CHARACTERS
                   13085: #      TO ENSURE CORRECT RIGHT PADDING OF THE FINAL WORD.
                   13086: #
                   13087: alocs: #prc                    # entry point
                   13088:        cmpl    r6,kvmxl        # jump if length exceeeds maxlength
                   13089:        bgtru   alcs2
                   13090:        movl    r6,r8           # else copy length
                   13091:        movab   3+(4*scsi$)(r6),r6 # compute length of scblk in bytes
                   13092:        bicl2   $3,r6
                   13093:        movl    dnamp,r9        # point to next available location
                   13094:        addl2   r6,r9           # point past block
                   13095:        bvc     0f
                   13096:        jmp     alcs0
                   13097: 0:             
                   13098:        cmpl    r9,dname        # jump if there is room
                   13099:        blequ   alcs1
                   13100: #
                   13101: #      INSUFFICIENT MEMORY
                   13102: #
                   13103: alcs0: clrl    r9              # else clear garbage xr value
                   13104:        jsb     alloc           # and use standard allocator
                   13105:        addl2   r6,r9           # point past end of block to merge
                   13106: #
                   13107: #      MERGE HERE WITH XR POINTING BEYOND NEW BLOCK
                   13108: #
                   13109: alcs1: movl    r9,dnamp        # set updated storage pointer
                   13110:        clrl    -(r9)           # store zero chars in last word
                   13111:        subl2   $4,r6           # decrement length
                   13112:        subl2   r6,r9           # point back to start of block
                   13113:        movl    $b$scl,(r9)     # set type word
                   13114:        movl    r8,4*sclen(r9)  # store length in chars
                   13115:        rsb                     # return to alocs caller
                   13116: #
                   13117: #      COME HERE IF STRING IS TOO LONG
                   13118: #
                   13119: alcs2: jmp     er_205          # string length exceeds value of maxlngth keyword
                   13120:        #enp                    # end procedure alocs
                   13121:        #page   
                   13122: #
                   13123: #      ALOST -- ALLOCATE SPACE IN STATIC REGION
                   13124: #
                   13125: #      (WA)                  LENGTH REQUIRED IN BYTES
                   13126: #      JSR  ALOST            CALL TO ALLOCATE SPACE
                   13127: #      (XR)                  POINTER TO ALLOCATED BLOCK
                   13128: #      (WB)                  DESTROYED
                   13129: #
                   13130: #      NOTE THAT THE CODING ENSURES THAT THE RESULTING VALUE
                   13131: #      OF STATE IS ALWAYS LESS THAN DNAMB. THIS FACT IS USED
                   13132: #      IN TESTING A VARIABLE NAME FOR BEING IN THE STATIC REGION
                   13133: #
                   13134: alost: #prc                    # entry point
                   13135: #
                   13136: #      MERGE BACK HERE AFTER ALLOCATING NEW CHUNK
                   13137: #
                   13138: alst1: movl    state,r9        # point to current end of area
                   13139:        addl2   r6,r9           # point beyond proposed block
                   13140:        bvc     0f
                   13141:        jmp     alst2
                   13142: 0:             
                   13143:        cmpl    r9,dnamb        # jump if overlap with dynamic area
                   13144:        bgequ   alst2
                   13145:        movl    r9,state        # else store new pointer
                   13146:        subl2   r6,r9           # point back to start of block
                   13147:        rsb                     # return to alost caller
                   13148: #
                   13149: #      HERE IF NO ROOM, PREPARE TO MOVE DYNAMIC STORAGE UP
                   13150: #
                   13151: alst2: movl    r6,alsta        # save wa
                   13152:        cmpl    r6,$4*e$sts     # skip if requested chunk is large
                   13153:        bgequ   alst3
                   13154:        movl    $4*e$sts,r6     # else set to get large enough chunk
                   13155: #
                   13156: #      HERE WITH AMOUNT TO MOVE UP IN WA
                   13157: #
                   13158: alst3: jsb     alloc           # allocate block to ensure room
                   13159:        movl    r9,dnamp        # and delete it
                   13160:        movl    r6,r7           # copy move up amount
                   13161:        jsb     gbcol           # call gbcol to move dynamic area up
                   13162:        movl    alsta,r6        # restore wa
                   13163:        jmp     alst1           # loop back to try again
                   13164:        #enp                    # end procedure alost
                   13165:        #page   
                   13166: #
                   13167: #      APNDB -- APPEND STRING TO BUFFER
                   13168: #
                   13169: #      THIS ROUTINE IS USED BY BUFFER HANDLING ROUTINES TO
                   13170: #      APPEND DATA TO AN EXISTING BFBLK.
                   13171: #
                   13172: #      (XR)                  EXISTING BCBLK TO BE APPENDED
                   13173: #      (XL)                  CONVERTABLE TO STRING
                   13174: #      JSR  APNDB            CALL TO APPEND TO BUFFER
                   13175: #      PPM  LOC              THREAD IF (XL) CANT BE CONVERTED
                   13176: #      PPM  LOC              IF NOT ENOUGH ROOM
                   13177: #      (WA,WB)               DESTROYED
                   13178: #
                   13179: #      IF MORE CHARACTERS ARE SPECIFIED THAN CAN BE INSERTED,
                   13180: #      THEN NO ACTION IS TAKEN AND THE SECOND RETURN IS TAKEN.
                   13181: #
                   13182: apndb: #prc                    # entry point
                   13183:        movl    4*bclen(r9),r6  # load offset to insert
                   13184:        clrl    r7              # replace section is null
                   13185:        jsb     insbf           # call to insert at end
                   13186:        .long   apn01           # convert error
                   13187:        .long   apn02           # no room
                   13188:        addl2   $4*2,(sp)       # return to caller
                   13189:        rsb     
                   13190: #
                   13191: #      HERE TO TAKE CONVERT FAILURE EXIT
                   13192: #
                   13193: apn01: movl    (sp)+,r11       # return to caller alternate
                   13194:        jmp     *(r11)+
                   13195: #
                   13196: #      HERE FOR NO FIT EXIT
                   13197: #
                   13198: apn02: addl3   $4*1,(sp)+,r11  # alternate exit to caller
                   13199:        jmp     *(r11)+
                   13200:        #enp                    # end procedure apndb
                   13201:        #page   
                   13202: #
                   13203: #      ARITH -- FETCH ARITHMETIC OPERANDS
                   13204: #
                   13205: #      ARITH IS USED BY FUNCTIONS AND OPERATORS WHICH EXPECT
                   13206: #      TWO NUMERIC ARGUMENTS (OPERANDS) WHICH MUST BOTH BE
                   13207: #      INTEGER OR BOTH BE REAL. ARITH FETCHES TWO ARGUMENTS FROM
                   13208: #      THE STACK AND PERFORMS ANY NECESSARY CONVERSIONS.
                   13209: #
                   13210: #      1(XS)                 FIRST ARGUMENT (LEFT OPERAND)
                   13211: #      0(XS)                 SECOND ARGUMENT (RIGHT OPERAND)
                   13212: #      JSR  ARITH            CALL TO FETCH NUMERIC ARGUMENTS
                   13213: #      PPM  LOC              TRANSFER LOC FOR OPND 1 NON-NUMERIC
                   13214: #      PPM  LOC              TRANSFER LOC FOR OPND 2 NON-NUMERIC
                   13215: #      PPM  LOC              TRANSFER LOC FOR REAL OPERANDS
                   13216: #
                   13217: #      FOR INTEGER ARGS, CONTROL RETURNS PAST THE PARAMETERS
                   13218: #
                   13219: #      (IA)                  LEFT OPERAND VALUE
                   13220: #      (XR)                  PTR TO ICBLK FOR LEFT OPERAND
                   13221: #      (XL)                  PTR TO ICBLK FOR RIGHT OPERAND
                   13222: #      (XS)                  POPPED TWICE
                   13223: #      (WA,WB,RA)            DESTROYED
                   13224: #
                   13225: #      FOR REAL ARGUMENTS, CONTROL RETURNS TO THE LOCATION
                   13226: #      SPECIFIED BY THE THIRD PARAMETER.
                   13227: #
                   13228: #      (RA)                  LEFT OPERAND VALUE
                   13229: #      (XR)                  PTR TO RCBLK FOR LEFT OPERAND
                   13230: #      (XL)                  PTR TO RCBLK FOR RIGHT OPERAND
                   13231: #      (WA,WB,WC)            DESTROYED
                   13232: #      (XS)                  POPPED TWICE
                   13233:        #page   
                   13234: #
                   13235: #      ARITH (CONTINUED)
                   13236: #
                   13237: #      ENTRY POINT
                   13238: #
                   13239:        .data   1
                   13240: arith_s:       .long   0
                   13241:        .text   0
                   13242: arith: movl    (sp)+,arith_s   # entry point
                   13243:        movl    (sp)+,r10       # load right operand
                   13244:        movl    (sp)+,r9        # load left operand
                   13245:        movl    (r10),r6        # get right operand type word
                   13246:        cmpl    r6,$b$icl       # jump if integer
                   13247:        beqlu   arth1
                   13248:        cmpl    r6,$b$rcl       # jump if real
                   13249:        beqlu   arth4
                   13250:        movl    r9,-(sp)        # else replace left arg on stack
                   13251:        movl    r10,r9          # copy left arg pointer
                   13252:        jsb     gtnum           # convert to numeric
                   13253:        .long   arth6           # jump if unconvertible
                   13254:        movl    r9,r10          # else copy converted result
                   13255:        movl    (r10),r6        # get right operand type word
                   13256:        movl    (sp)+,r9        # reload left argument
                   13257:        cmpl    r6,$b$rcl       # jump if right arg is real
                   13258:        beqlu   arth4
                   13259: #
                   13260: #      HERE IF RIGHT ARG IS AN INTEGER
                   13261: #
                   13262: arth1: cmpl    (r9),$b$icl     # jump if left arg not integer
                   13263:        bnequ   arth3
                   13264: #
                   13265: #      EXIT FOR INTEGER CASE
                   13266: #
                   13267: arth2: movl    4*icval(r9),r5  # load left operand value
                   13268:        addl3   $4*3,arith_s,r11        # return to arith caller
                   13269:        jmp     (r11)
                   13270: #
                   13271: #      HERE FOR RIGHT OPERAND INTEGER, LEFT OPERAND NOT
                   13272: #
                   13273: arth3: jsb     gtnum           # convert left arg to numeric
                   13274:        .long   arth7           # jump if not convertible
                   13275:        cmpl    r6,$b$icl       # jump back if integer-integer
                   13276:        beqlu   arth2
                   13277: #
                   13278: #      HERE WE MUST CONVERT REAL-INTEGER TO REAL-REAL
                   13279: #
                   13280:        movl    r9,-(sp)        # put left arg back on stack
                   13281:        movl    4*icval(r10),r5 # load right argument value
                   13282:        cvtlf   r5,r2           # convert to real
                   13283:        jsb     rcbld           # get real block for right arg, merge
                   13284:        movl    r9,r10          # copy right arg ptr
                   13285:        movl    (sp)+,r9        # load left argument
                   13286:        jmp     arth5           # merge for real-real case
                   13287:        #page   
                   13288: #
                   13289: #      ARITH (CONTINUED)
                   13290: #
                   13291: #      HERE IF RIGHT ARGUMENT IS REAL
                   13292: #
                   13293: arth4: cmpl    (r9),$b$rcl     # jump if left arg real
                   13294:        beqlu   arth5
                   13295:        jsb     gtrea           # else convert to real
                   13296:        .long   arth7           # error if unconvertible
                   13297: #
                   13298: #      HERE FOR REAL-REAL
                   13299: #
                   13300: arth5: movf    4*rcval(r9),r2  # load left operand value
                   13301:        addl3   $4*2,arith_s,r11        # take real-real exit
                   13302:        jmp     *(r11)+
                   13303: #
                   13304: #      HERE FOR ERROR CONVERTING RIGHT ARGUMENT
                   13305: #
                   13306: arth6: addl2   $4,sp           # pop unwanted left arg
                   13307:        addl3   $4*1,arith_s,r11        # take appropriate error exit
                   13308:        jmp     *(r11)+
                   13309: #
                   13310: #      HERE FOR ERROR CONVERTING LEFT OPERAND
                   13311: #
                   13312: arth7: movl    arith_s,r11     # take appropriate error return
                   13313:        jmp     *(r11)+
                   13314:        #enp                    # end procedure arith
                   13315:        #page   
                   13316: #
                   13317: #      ASIGN -- PERFORM ASSIGNMENT
                   13318: #
                   13319: #      ASIGN PERFORMS THE ASSIGNMENT OF A VALUE TO A VARIABLE
                   13320: #      WITH APPROPRIATE CHECKS FOR OUTPUT ASSOCIATIONS AND
                   13321: #      VALUE TRACE ASSOCIATIONS WHICH ARE EXECUTED AS REQUIRED.
                   13322: #      ASIGN ALSO HANDLES THE SPECIAL CASES OF ASSIGNMENT TO
                   13323: #      PATTERN AND EXPRESSION VARIABLES.
                   13324: #
                   13325: #      (WB)                  VALUE TO BE ASSIGNED
                   13326: #      (XL)                  BASE POINTER FOR VARIABLE
                   13327: #      (WA)                  OFFSET FOR VARIABLE
                   13328: #      JSR  ASIGN            CALL TO ASSIGN VALUE TO VARIABLE
                   13329: #      PPM  LOC              TRANSFER LOC FOR FAILURE
                   13330: #      (XR,XL,WA,WB,WC)      DESTROYED
                   13331: #      (RA)                  DESTROYED
                   13332: #
                   13333: #      FAILURE OCCURS IF THE EVALUATION OF AN EXPRESSION
                   13334: #      ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS.
                   13335: #
                   13336: asign: #prc                    # entry point (recursive)
                   13337: #
                   13338: #      MERGE BACK HERE TO ASSIGN RESULT TO EXPRESSION VARIABLE.
                   13339: #
                   13340: asg01: addl2   r6,r10          # point to variable value
                   13341:        movl    (r10),r9        # load variable value
                   13342:        cmpl    (r9),$b$trt     # jump if trapped
                   13343:        beqlu   asg02
                   13344:        movl    r7,(r10)        # else perform assignment
                   13345:        clrl    r10             # clear garbage value in xl
                   13346:        addl2   $4*1,(sp)       # and return to asign caller
                   13347:        rsb     
                   13348: #
                   13349: #      HERE IF VALUE IS TRAPPED
                   13350: #
                   13351: asg02: subl2   r6,r10          # restore name base
                   13352:        cmpl    r9,$trbkv       # jump if keyword variable
                   13353:        bnequ   0f
                   13354:        jmp     asg14
                   13355: 0:             
                   13356:        cmpl    r9,$trbev       # jump if not expression variable
                   13357:        bnequ   asg04
                   13358: #
                   13359: #      HERE FOR ASSIGNMENT TO EXPRESSION VARIABLE
                   13360: #
                   13361:        movl    4*evexp(r10),r9 # point to expression
                   13362:        movl    r7,-(sp)        # store value to assign on stack
                   13363:        movl    $num01,r7       # set for evaluation by name
                   13364:        jsb     evalx           # evaluate expression by name
                   13365:        .long   asg03           # jump if evaluation fails
                   13366:        movl    (sp)+,r7        # else reload value to assign
                   13367:        jmp     asg01           # loop back to perform assignment
                   13368:        #page   
                   13369: #
                   13370: #      ASIGN (CONTINUED)
                   13371: #
                   13372: #      HERE FOR FAILURE DURING EXPRESSION EVALUATION
                   13373: #
                   13374: asg03: addl2   $4,sp           # remove stacked value entry
                   13375:        movl    (sp)+,r11       # take failure exit
                   13376:        jmp     *(r11)+
                   13377: #
                   13378: #      HERE IF NOT KEYWORD OR EXPRESSION VARIABLE
                   13379: #
                   13380: asg04: movl    r9,-(sp)        # save ptr to first trblk
                   13381: #
                   13382: #      LOOP TO CHASE DOWN TRBLK CHAIN AND ASSIGN VALUE AT END
                   13383: #
                   13384: asg05: movl    r9,r8           # save ptr to this trblk
                   13385:        movl    4*trnxt(r9),r9  # point to next trblk
                   13386:        cmpl    (r9),$b$trt     # loop back if another trblk
                   13387:        beqlu   asg05
                   13388:        movl    r8,r9           # else point back to last trblk
                   13389:        movl    r7,4*trval(r9)  # store value at end of chain
                   13390:        movl    (sp)+,r9        # restore ptr to first trblk
                   13391: #
                   13392: #      LOOP TO PROCESS TRBLK ENTRIES ON CHAIN
                   13393: #
                   13394: asg06: movl    4*trtyp(r9),r7  # load type code of trblk
                   13395:        cmpl    r7,$trtvl       # jump if value trace
                   13396:        beqlu   asg08
                   13397:        cmpl    r7,$trtou       # jump if output association
                   13398:        beqlu   asg10
                   13399: #
                   13400: #      HERE TO MOVE TO NEXT TRBLK ON CHAIN
                   13401: #
                   13402: asg07: movl    4*trnxt(r9),r9  # point to next trblk on chain
                   13403:        cmpl    (r9),$b$trt     # loop back if another trblk
                   13404:        beqlu   asg06
                   13405:        addl2   $4*1,(sp)       # else end of chain, return to caller
                   13406:        rsb     
                   13407: #
                   13408: #      HERE TO PROCESS VALUE TRACE
                   13409: #
                   13410: asg08: tstl    kvtra           # ignore value trace if trace off
                   13411:        beqlu   asg07
                   13412:        decl    kvtra           # else decrement trace count
                   13413:        tstl    4*trfnc(r9)     # jump if print trace
                   13414:        beqlu   asg09
                   13415:        jsb     trxeq           # else execute function trace
                   13416:        jmp     asg07           # and loop back
                   13417:        #page   
                   13418: #
                   13419: #      ASIGN (CONTINUED)
                   13420: #
                   13421: #      HERE FOR PRINT TRACE
                   13422: #
                   13423: asg09: jsb     prtsn           # print statement number
                   13424:        jsb     prtnv           # print name = value
                   13425:        jmp     asg07           # loop back for next trblk
                   13426: #
                   13427: #      HERE FOR OUTPUT ASSOCIATION
                   13428: #
                   13429: asg10: tstl    kvoup           # ignore output assoc if output off
                   13430:        beqlu   asg07
                   13431:        movl    r9,r10          # else copy trblk pointer
                   13432:        movl    4*trval(r8),-(sp)# stack value to output (sgd01)
                   13433:        jsb     gtstg           # convert to string
                   13434:        .long   asg12           # get datatype name if unconvertible
                   13435: #
                   13436: #      MERGE WITH STRING FOR OUTPUT
                   13437: #
                   13438: asg11: movl    4*trfpt(r10),r6 # fcblk ptr
                   13439:        beqlu   asg13           # jump if standard output file
                   13440: #
                   13441: #      HERE FOR OUTPUT TO NON-STANDARD OUTPUT FILE
                   13442: #
                   13443:        jsb     sysou           # call system output routine
                   13444:        .long   er_206          # output caused file overflow
                   13445:        .long   er_207          # output caused non-recoverable error
                   13446:        addl2   $4*1,(sp)       # else all done, return to caller
                   13447:        rsb     
                   13448: #
                   13449: #      IF NOT PRINTABLE, GET DATATYPE NAME INSTEAD
                   13450: #
                   13451: asg12: jsb     dtype           # call datatype routine
                   13452:        jmp     asg11           # merge
                   13453: #
                   13454: #      HERE TO PRINT A STRING ON THE PRINTER
                   13455: #
                   13456: asg13: jsb     prtst           # print string value
                   13457:        cmpl    4*trter(r10),$v$ter # jump if terminal output
                   13458:        bnequ   0f
                   13459:        jmp     asg20
                   13460: 0:             
                   13461:        jsb     prtnl           # end of line
                   13462:        addl2   $4*1,(sp)       # return to caller
                   13463:        rsb     
                   13464:        #page   
                   13465: #
                   13466: #      ASIGN (CONTINUED)
                   13467: #
                   13468: #      HERE FOR KEYWORD ASSIGNMENT
                   13469: #
                   13470: asg14: movl    4*kvnum(r10),r10# load keyword number
                   13471:        cmpl    r10,$k$etx      # jump if errtext
                   13472:        bnequ   0f
                   13473:        jmp     asg19
                   13474: 0:             
                   13475:        movl    r7,r9           # copy value to be assigned
                   13476:        jsb     gtint           # convert to integer
                   13477:        .long   er_208          # keyword value assigned is not integer
                   13478:        movl    4*icval(r9),r5  # else load value
                   13479:        cmpl    r10,$k$stl      # jump if special case of stlimit
                   13480:        beqlu   asg16
                   13481:        movl    r5,r6           # else get addr integer, test ovflow
                   13482:        bgeq    0f
                   13483:        jmp     asg18
                   13484: 0:             
                   13485:        cmpl    r6,mxlen        # fail if too large
                   13486:        bgequ   asg18
                   13487:        cmpl    r10,$k$ert      # jump if special case of errtype
                   13488:        beqlu   asg17
                   13489:        cmpl    r10,$k$pfl      # jump if special case of profile
                   13490:        beqlu   asg21
                   13491:        cmpl    r10,$k$p$$      # jump unless protected
                   13492:        blssu   asg15
                   13493:        jmp     er_209          # keyword in assignment is protected
                   13494: #
                   13495: #      HERE TO DO ASSIGNMENT IF NOT PROTECTED
                   13496: #
                   13497: asg15: movl    r6,l^kvabe(r10) # store new value
                   13498:        addl2   $4*1,(sp)       # return to asign caller
                   13499:        rsb     
                   13500: #
                   13501: #      HERE FOR SPECIAL CASE OF STLIMIT
                   13502: #
                   13503: #      SINCE STCOUNT IS MAINTAINED AS (STLIMIT-STCOUNT)
                   13504: #      IT IS ALSO NECESSARY TO MODIFY STCOUNT APPROPRIATELY.
                   13505: #
                   13506: asg16: subl2   kvstl,r5        # subtract old limit
                   13507:        addl2   kvstc,r5        # add old counter
                   13508:        movl    r5,kvstc        # store new counter value
                   13509:        movl    4*icval(r9),r5  # reload new limit value
                   13510:        movl    r5,kvstl        # store new limit value
                   13511:        addl2   $4*1,(sp)       # return to asign caller
                   13512:        rsb     
                   13513: #
                   13514: #      HERE FOR SPECIAL CASE OF ERRTYPE
                   13515: #
                   13516: asg17: cmpl    r6,$nini9       # ok to signal if in range
                   13517:        bgtru   0f
                   13518:        jmp     error
                   13519: 0:             
                   13520: #
                   13521: #      HERE IF VALUE ASSIGNED IS OUT OF RANGE
                   13522: #
                   13523: asg18: jmp     er_210          # keyword value assigned is negative or too large
                   13524: #
                   13525: #      HERE FOR SPECIAL CASE OF ERRTEXT
                   13526: #
                   13527: asg19: movl    r7,-(sp)        # stack value
                   13528:        jsb     gtstg           # convert to string
                   13529:        .long   er_211          # value assigned to keyword errtext not a string
                   13530:        movl    r9,r$etx        # make assignment
                   13531:        addl2   $4*1,(sp)       # return to caller
                   13532:        rsb     
                   13533: #
                   13534: #      PRINT STRING TO TERMINAL
                   13535: #
                   13536: asg20: jsb     prttr           # print
                   13537:        addl2   $4*1,(sp)       # return
                   13538:        rsb     
                   13539: #
                   13540: #      HERE FOR KEYWORD PROFILE
                   13541: #
                   13542: asg21: cmpl    r6,$num02       # moan if not 0,1, or 2
                   13543:        bgtru   asg18
                   13544:        tstl    r6              # just assign if zero
                   13545:        beqlu   asg15
                   13546:        tstl    pfdmp           # branch if first assignment
                   13547:        beqlu   asg22
                   13548:        cmpl    r6,pfdmp        # also if same value as before
                   13549:        beqlu   asg23
                   13550:        jmp     er_268          # inconsistent value assigned to keyword profile
                   13551: #
                   13552: asg22: movl    r6,pfdmp        # note value on first assignment
                   13553: asg23: jsb     systm           # get the time
                   13554:        movl    r5,pfstm        # fudge some kind of start time
                   13555:        jmp     asg15           # and go assign
                   13556:        #enp                    # end procedure asign
                   13557:        #page   
                   13558: #
                   13559: #      ASINP -- ASSIGN DURING PATTERN MATCH
                   13560: #
                   13561: #      ASINP IS LIKE ASIGN AND HAS A SIMILAR CALLING SEQUENCE
                   13562: #      AND EFFECT. THE DIFFERENCE IS THAT THE GLOBAL PATTERN
                   13563: #      VARIABLES ARE SAVED AND RESTORED IF REQUIRED.
                   13564: #
                   13565: #      (XL)                  BASE POINTER FOR VARIABLE
                   13566: #      (WA)                  OFFSET FOR VARIABLE
                   13567: #      (WB)                  VALUE TO BE ASSIGNED
                   13568: #      JSR  ASINP            CALL TO ASSIGN VALUE TO VARIABLE
                   13569: #      PPM  LOC              TRANSFER LOC IF FAILURE
                   13570: #      (XR,XL)               DESTROYED
                   13571: #      (WA,WB,WC,RA)         DESTROYED
                   13572: #
                   13573: asinp: #prc                    # entry point, recursive
                   13574:        addl2   r6,r10          # point to variable
                   13575:        movl    (r10),r9        # load current contents
                   13576:        cmpl    (r9),$b$trt     # jump if trapped
                   13577:        beqlu   asnp1
                   13578:        movl    r7,(r10)        # else perform assignment
                   13579:        clrl    r10             # clear garbage value in xl
                   13580:        addl2   $4*1,(sp)       # return to asinp caller
                   13581:        rsb     
                   13582: #
                   13583: #      HERE IF VARIABLE IS TRAPPED
                   13584: #
                   13585: asnp1: subl2   r6,r10          # restore base pointer
                   13586:        movl    pmssl,-(sp)     # stack subject string length
                   13587:        movl    pmhbs,-(sp)     # stack history stack base ptr
                   13588:        movl    r$pms,-(sp)     # stack subject string pointer
                   13589:        movl    pmdfl,-(sp)     # stack dot flag
                   13590:        jsb     asign           # call full-blown assignment routine
                   13591:        .long   asnp2           # jump if failure
                   13592:        movl    (sp)+,pmdfl     # restore dot flag
                   13593:        movl    (sp)+,r$pms     # restore subject string pointer
                   13594:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   13595:        movl    (sp)+,pmssl     # restore subject string length
                   13596:        addl2   $4*1,(sp)       # return to asinp caller
                   13597:        rsb     
                   13598: #
                   13599: #      HERE IF FAILURE IN ASIGN CALL
                   13600: #
                   13601: asnp2: movl    (sp)+,pmdfl     # restore dot flag
                   13602:        movl    (sp)+,r$pms     # restore subject string pointer
                   13603:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   13604:        movl    (sp)+,pmssl     # restore subject string length
                   13605:        movl    (sp)+,r11       # take failure exit
                   13606:        jmp     *(r11)+
                   13607:        #enp                    # end procedure asinp
                   13608:        #page   
                   13609: #
                   13610: #      BLKLN -- DETERMINE LENGTH OF BLOCK
                   13611: #
                   13612: #      BLKLN DETERMINES THE LENGTH OF A BLOCK IN DYNAMIC STORE.
                   13613: #
                   13614: #      (WA)                  FIRST WORD OF BLOCK
                   13615: #      (XR)                  POINTER TO BLOCK
                   13616: #      JSR  BLKLN            CALL TO GET BLOCK LENGTH
                   13617: #      (WA)                  LENGTH OF BLOCK IN BYTES
                   13618: #      (XL)                  DESTROYED
                   13619: #
                   13620: #      BLKLN IS USED BY THE GARBAGE COLLECTOR AND IS NOT
                   13621: #      PERMITTED TO CALL GBCOL DIRECTLY OR INDIRECTLY.
                   13622: #
                   13623: #      THE FIRST WORD STORED IN THE BLOCK (I.E. AT XR) MAY
                   13624: #      BE ANYTHING, BUT THE CONTENTS OF WA MUST BE CORRECT.
                   13625: #
                   13626: blkln: #prc                    # entry point
                   13627:        movl    r6,r10          # copy first word
                   13628:        movzwl  -2(r10),r10     # get entry id (bl$xx)
                   13629:        casel   r10,$0,$bl$$$   # switch on block type
                   13630: 5:             
                   13631:        .word   bln01-5b        # arblk
                   13632:        .word   bln04-5b        # bcblk
                   13633:        .word   bln01-5b        # cdblk
                   13634:        .word   bln01-5b        # exblk
                   13635:        .word   bln07-5b        # icblk
                   13636:        .word   bln03-5b        # nmblk
                   13637:        .word   bln02-5b        # p0blk
                   13638:        .word   bln03-5b        # p1blk
                   13639:        .word   bln04-5b        # p2blk
                   13640:        .word   bln09-5b        # rcblk
                   13641:        .word   bln10-5b        # scblk
                   13642:        .word   bln02-5b        # seblk
                   13643:        .word   bln01-5b        # tbblk
                   13644:        .word   bln01-5b        # vcblk
                   13645:        .word   bln00-5b
                   13646:        .word   bln00-5b
                   13647:        .word   bln08-5b        # pdblk
                   13648:        .word   bln05-5b        # trblk
                   13649:        .word   bln11-5b        # bfblk
                   13650:        .word   bln00-5b
                   13651:        .word   bln00-5b
                   13652:        .word   bln06-5b        # ctblk
                   13653:        .word   bln01-5b        # dfblk
                   13654:        .word   bln01-5b        # efblk
                   13655:        .word   bln03-5b        # evblk
                   13656:        .word   bln05-5b        # ffblk
                   13657:        .word   bln03-5b        # kvblk
                   13658:        .word   bln01-5b        # pfblk
                   13659:        .word   bln04-5b        # teblk
                   13660:        #esw                    # end of jump table on block type
                   13661:        #page   
                   13662: #
                   13663: #      BLKLN (CONTINUED)
                   13664: #
                   13665: #      HERE FOR BLOCKS WITH LENGTH IN SECOND WORD
                   13666: #
                   13667: bln00: movl    4*1(r9),r6      # load length
                   13668:        rsb                     # return to blkln caller
                   13669: #
                   13670: #      HERE FOR LENGTH IN THIRD WORD (AR,CD,DF,EF,EX,PF,TB,VC)
                   13671: #
                   13672: bln01: movl    4*2(r9),r6      # load length from third word
                   13673:        rsb                     # return to blkln caller
                   13674: #
                   13675: #      HERE FOR TWO WORD BLOCKS (P0,SE)
                   13676: #
                   13677: bln02: movl    $4*num02,r6     # load length (two words)
                   13678:        rsb                     # return to blkln caller
                   13679: #
                   13680: #      HERE FOR THREE WORD BLOCKS (NM,P1,EV,KV)
                   13681: #
                   13682: bln03: movl    $4*num03,r6     # load length (three words)
                   13683:        rsb                     # return to blkln caller
                   13684: #
                   13685: #      HERE FOR FOUR WORD BLOCKS (P2,TE,BC)
                   13686: #
                   13687: bln04: movl    $4*num04,r6     # load length (four words)
                   13688:        rsb                     # return to blkln caller
                   13689: #
                   13690: #      HERE FOR FIVE WORD BLOCKS (FF,TR)
                   13691: #
                   13692: bln05: movl    $4*num05,r6     # load length
                   13693:        rsb                     # return to blkln caller
                   13694:        #page   
                   13695: #
                   13696: #      BLKLN (CONTINUED)
                   13697: #
                   13698: #      HERE FOR CTBLK
                   13699: #
                   13700: bln06: movl    $4*ctsi$,r6     # set size of ctblk
                   13701:        rsb                     # return to blkln caller
                   13702: #
                   13703: #      HERE FOR ICBLK
                   13704: #
                   13705: bln07: movl    $4*icsi$,r6     # set size of icblk
                   13706:        rsb                     # return to blkln caller
                   13707: #
                   13708: #      HERE FOR PDBLK
                   13709: #
                   13710: bln08: movl    4*pddfp(r9),r10 # point to dfblk
                   13711:        movl    4*dfpdl(r10),r6 # load pdblk length from dfblk
                   13712:        rsb                     # return to blkln caller
                   13713: #
                   13714: #      HERE FOR RCBLK
                   13715: #
                   13716: bln09: movl    $4*rcsi$,r6     # set size of rcblk
                   13717:        rsb                     # return to blkln caller
                   13718: #
                   13719: #      HERE FOR SCBLK
                   13720: #
                   13721: bln10: movl    4*sclen(r9),r6  # load length in characters
                   13722:        movab   3+(4*scsi$)(r6),r6 # calculate length in bytes
                   13723:        bicl2   $3,r6
                   13724:        rsb                     # return to blkln caller
                   13725: #
                   13726: #      HERE FOR BFBLK
                   13727: #
                   13728: bln11: movl    4*bfalc(r9),r6  # get allocation in bytes
                   13729:        movab   3+(4*bfsi$)(r6),r6 # calculate length in bytes
                   13730:        bicl2   $3,r6
                   13731:        rsb                     # return to blkln caller
                   13732:        #enp                    # end procedure blkln
                   13733:        #page   
                   13734: #
                   13735: #      COPYB -- COPY A BLOCK
                   13736: #
                   13737: #      (XS)                  BLOCK TO BE COPIED
                   13738: #      JSR  COPYB            CALL TO COPY BLOCK
                   13739: #      PPM  LOC              RETURN IF BLOCK HAS NO IDVAL FIELD
                   13740: #                            NORMAL RETURN IF IDVAL FIELD
                   13741: #      (XR)                  COPY OF BLOCK
                   13742: #      (XS)                  POPPED
                   13743: #      (XL,WA,WB,WC)         DESTROYED
                   13744: #
                   13745:        .data   1
                   13746: copyb_s:       .long   0
                   13747:        .text   0
                   13748: copyb: movl    (sp)+,copyb_s   # entry point
                   13749:        movl    (sp),r9         # load argument
                   13750:        cmpl    r9,$nulls       # return argument if it is null
                   13751:        bnequ   0f
                   13752:        jmp     cop10
                   13753: 0:             
                   13754:        movl    (r9),r6         # else load type word
                   13755:        movl    r6,r7           # copy type word
                   13756:        jsb     blkln           # get length of argument block
                   13757:        movl    r9,r10          # copy pointer
                   13758:        jsb     alloc           # allocate block of same size
                   13759:        movl    r9,(sp)         # store pointer to copy
                   13760:        jsb     sbmvw           # copy contents of old block to new
                   13761:        movl    (sp),r9         # reload pointer to start of copy
                   13762:        cmpl    r7,$b$tbt       # jump if table
                   13763:        beqlu   cop05
                   13764:        cmpl    r7,$b$vct       # jump if vector
                   13765:        beqlu   cop01
                   13766:        cmpl    r7,$b$pdt       # jump if program defined
                   13767:        beqlu   cop01
                   13768:        cmpl    r7,$b$bct       # jump if buffer
                   13769:        bnequ   0f
                   13770:        jmp     cop11
                   13771: 0:             
                   13772:        cmpl    r7,$b$art       # return copy if not array
                   13773:        beqlu   0f
                   13774:        jmp     cop10
                   13775: 0:             
                   13776: #
                   13777: #      HERE FOR ARRAY (ARBLK)
                   13778: #
                   13779:        addl2   4*arofs(r9),r9  # point to prototype field
                   13780:        jmp     cop02           # jump to merge
                   13781: #
                   13782: #      HERE FOR VECTOR, PROGRAM DEFINED
                   13783: #
                   13784: cop01: addl2   $4*pdfld,r9     # point to pdfld = vcvls
                   13785: #
                   13786: #      MERGE HERE FOR ARBLK, VCBLK, PDBLK TO DELETE TRAP
                   13787: #      BLOCKS FROM ALL VALUE FIELDS (THE COPY IS UNTRAPPED)
                   13788: #
                   13789: cop02: movl    (r9),r10        # load next pointer
                   13790: #
                   13791: #      LOOP TO GET VALUE AT END OF TRBLK CHAIN
                   13792: #
                   13793: cop03: cmpl    (r10),$b$trt    # jump if not trapped
                   13794:        bnequ   cop04
                   13795:        movl    4*trval(r10),r10# else point to next value
                   13796:        jmp     cop03           # and loop back
                   13797:        #page   
                   13798: #
                   13799: #      COPYB (CONTINUED)
                   13800: #
                   13801: #      HERE WITH UNTRAPPED VALUE IN XL
                   13802: #
                   13803: cop04: movl    r10,(r9)+       # store real value, bump pointer
                   13804:        cmpl    r9,dnamp        # loop back if more to go
                   13805:        bnequ   cop02
                   13806:        jmp     cop09           # else jump to exit
                   13807: #
                   13808: #      HERE TO COPY A TABLE
                   13809: #
                   13810: cop05: clrl    4*idval(r9)     # zero id to stop dump blowing up
                   13811:        movl    $4*tesi$,r6     # set size of teblk
                   13812:        movl    $4*tbbuk,r8     # set initial offset
                   13813: #
                   13814: #      LOOP THROUGH BUCKETS IN TABLE
                   13815: #
                   13816: cop06: movl    (sp),r9         # load table pointer
                   13817:        cmpl    r8,4*tblen(r9)  # jump to exit if all done
                   13818:        beqlu   cop09
                   13819:        addl2   r8,r9           # else point to next bucket header
                   13820:        addl2   $4,r8           # bump offset
                   13821:        subl2   $4*tenxt,r9     # subtract link offset to merge
                   13822: #
                   13823: #      LOOP THROUGH TEBLKS ON ONE CHAIN
                   13824: #
                   13825: cop07: movl    4*tenxt(r9),r10 # load pointer to next teblk
                   13826:        movl    (sp),4*tenxt(r9)# set end of chain pointer in case
                   13827:        cmpl    (r10),$b$tbt    # back for next bucket if chain end
                   13828:        beqlu   cop06
                   13829:        movl    r9,-(sp)        # else stack ptr to previous block
                   13830:        movl    $4*tesi$,r6     # set size of teblk
                   13831:        jsb     alloc           # allocate new teblk
                   13832:        movl    r9,r7           # save ptr to new teblk
                   13833:        jsb     sbmvw           # copy old teblk to new teblk
                   13834:        movl    r7,r9           # restore pointer to new teblk
                   13835:        movl    (sp)+,r10       # restore pointer to previous block
                   13836:        movl    r9,4*tenxt(r10) # link new block to previous
                   13837:        movl    r9,r10          # copy pointer to new block
                   13838: #
                   13839: #      LOOP TO SET REAL VALUE AFTER REMOVING TRAP CHAIN
                   13840: #
                   13841: cop08: movl    4*teval(r10),r10# load value
                   13842:        cmpl    (r10),$b$trt    # loop back if trapped
                   13843:        beqlu   cop08
                   13844:        movl    r10,4*teval(r9) # store untrapped value in teblk
                   13845:        jmp     cop07           # back for next teblk
                   13846: #
                   13847: #      COMMON EXIT POINT
                   13848: #
                   13849: cop09: movl    (sp)+,r9        # load pointer to block
                   13850:        addl3   $4*1,copyb_s,r11        # return
                   13851:        jmp     (r11)
                   13852: #
                   13853: #      ALTERNATIVE RETURN
                   13854: #
                   13855: cop10: movl    copyb_s,r11     # return
                   13856:        jmp     *(r11)+
                   13857:        #page   
                   13858: #
                   13859: #      HERE TO COPY BUFFER
                   13860: #
                   13861: cop11: movl    4*bcbuf(r9),r10 # get bfblk ptr
                   13862:        movl    4*bfalc(r10),r6 # get allocation
                   13863:        movab   3+(4*bfsi$)(r6),r6 # set total size
                   13864:        bicl2   $3,r6
                   13865:        movl    r9,r10          # save bcblk ptr
                   13866:        jsb     alloc           # allocate bfblk
                   13867:        movl    4*bcbuf(r10),r7 # get old bfblk
                   13868:        movl    r9,4*bcbuf(r10) # set pointer to new bfblk
                   13869:        movl    r7,r10          # point to old bfblk
                   13870:        jsb     sbmvw           # copy bfblk too
                   13871:        clrl    r10             # clear rubbish ptr
                   13872:        jmp     cop09           # branch to exit
                   13873:        #enp                    # end procedure copyb
                   13874: #
                   13875: #      CDGCG -- GENERATE CODE FOR COMPLEX GOTO
                   13876: #
                   13877: #      USED BY CMPIL TO PROCESS COMPLEX GOTO TREE
                   13878: #
                   13879: #      (WB)                  MUST BE COLLECTABLE
                   13880: #      (XR)                  EXPRESSION POINTER
                   13881: #      JSR  CDGCG            CALL TO GENERATE COMPLEX GOTO
                   13882: #      (XL,XR,WA)            DESTROYED
                   13883: #
                   13884: cdgcg: #prc                    # entry point
                   13885:        movl    4*cmopn(r9),r10 # get unary goto operator
                   13886:        movl    4*cmrop(r9),r9  # point to goto operand
                   13887:        cmpl    r10,$opdvd      # jump if direct goto
                   13888:        beqlu   cdgc2
                   13889:        jsb     cdgnm           # generate opnd by name if not direct
                   13890: #
                   13891: #      RETURN POINT
                   13892: #
                   13893: cdgc1: movl    r10,r6          # goto operator
                   13894:        jsb     cdwrd           # generate it
                   13895:        rsb                     # return to caller
                   13896: #
                   13897: #      DIRECT GOTO
                   13898: #
                   13899: cdgc2: jsb     cdgvl           # generate operand by value
                   13900:        jmp     cdgc1           # merge to return
                   13901:        #enp                    # end procedure cdgcg
                   13902:        #page   
                   13903: #
                   13904: #      CDGEX -- BUILD EXPRESSION BLOCK
                   13905: #
                   13906: #      CDGEX IS PASSED A POINTER TO AN EXPRESSION TREE (SEE
                   13907: #      EXPAN) AND RETURNS AN EXPRESSION (SEBLK OR EXBLK).
                   13908: #
                   13909: #      (WC)                  SOME COLLECTABLE VALUE
                   13910: #      (WB)                  INTEGER IN RANGE 0 LE X LE MXLEN
                   13911: #      (XL)                  PTR TO EXPRESSION TREE
                   13912: #      JSR  CDGEX            CALL TO BUILD EXPRESSION
                   13913: #      (XR)                  PTR TO SEBLK OR EXBLK
                   13914: #      (XL,WA,WB)            DESTROYED
                   13915: #
                   13916: cdgex: #prc                    # entry point, recursive
                   13917:        cmpl    (r10),$b$vr$    # jump if not variable
                   13918:        blequ   cdgx1
                   13919: #
                   13920: #      HERE FOR NATURAL VARIABLE, BUILD SEBLK
                   13921: #
                   13922:        movl    $4*sesi$,r6     # set size of seblk
                   13923:        jsb     alloc           # allocate space for seblk
                   13924:        movl    $b$sel,(r9)     # set type word
                   13925:        movl    r10,4*sevar(r9) # store vrblk pointer
                   13926:        rsb                     # return to cdgex caller
                   13927: #
                   13928: #      HERE IF NOT VARIABLE, BUILD EXBLK
                   13929: #
                   13930: cdgx1: movl    r10,r9          # copy tree pointer
                   13931:        movl    r8,-(sp)        # save wc
                   13932:        movl    cwcof,r10       # save current offset
                   13933:        movl    (r9),r6         # get type word
                   13934:        cmpl    r6,$b$cmt       # call by value if not cmblk
                   13935:        bnequ   cdgx2
                   13936:        cmpl    4*cmtyp(r9),$c$$nm # jump if cmblk only by value
                   13937:        bgequ   cdgx2
                   13938:        #page   
                   13939: #
                   13940: #      CDGEX (CONTINUED)
                   13941: #
                   13942: #      HERE IF EXPRESSION CAN BE EVALUATED BY NAME
                   13943: #
                   13944:        jsb     cdgnm           # generate code by name
                   13945:        movl    $ornm$,r6       # load return by name word
                   13946:        jmp     cdgx3           # merge with value case
                   13947: #
                   13948: #      HERE IF EXPRESSION CAN ONLY BE EVALUATED BY VALUE
                   13949: #
                   13950: cdgx2: jsb     cdgvl           # generate code by value
                   13951:        movl    $orvl$,r6       # load return by value word
                   13952: #
                   13953: #      MERGE HERE TO CONSTRUCT EXBLK
                   13954: #
                   13955: cdgx3: jsb     cdwrd           # generate return word
                   13956:        jsb     exbld           # build exblk
                   13957:        movl    (sp)+,r8        # restore wc
                   13958:        rsb                     # return to cdgex caller
                   13959:        #enp                    # end procedure cdgex
                   13960:        #page   
                   13961: #
                   13962: #      CDGNM -- GENERATE CODE BY NAME
                   13963: #
                   13964: #      CDGNM IS CALLED DURING THE COMPILATION PROCESS TO
                   13965: #      GENERATE CODE BY NAME FOR AN EXPRESSION. SEE CDBLK
                   13966: #      DESCRIPTION FOR DETAILS OF CODE GENERATED. THE INPUT
                   13967: #      TO CDGNM IS AN EXPRESSION TREE AS GENERATED BY EXPAN.
                   13968: #
                   13969: #      CDGNM IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING
                   13970: #      RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS.
                   13971: #
                   13972: #      (WB)                  INTEGER IN RANGE 0 LE N LE DNAMB
                   13973: #      (XR)                  PTR TO TREE GENERATED BY EXPAN
                   13974: #      (WC)                  CONSTANT FLAG (SEE BELOW)
                   13975: #      JSR  CDGNM            CALL TO GENERATE CODE BY NAME
                   13976: #      (XR,WA)               DESTROYED
                   13977: #      (WC)                  SET NON-ZERO IF NON-CONSTANT
                   13978: #
                   13979: #      WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE
                   13980: #      EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE
                   13981: #      EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED.
                   13982: #
                   13983: #      THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD).
                   13984: #
                   13985: cdgnm: #prc                    # entry point, recursive
                   13986:        movl    r10,-(sp)       # save entry xl
                   13987:        movl    r7,-(sp)        # save entry wb
                   13988:        jsb     sbchk           # check for stack overflow
                   13989:        movl    (r9),r6         # load type word
                   13990:        cmpl    r6,$b$cmt       # jump if cmblk
                   13991:        beqlu   cgn04
                   13992:        cmpl    r6,$b$vr$       # jump if simple variable
                   13993:        blssu   0f
                   13994:        jmp     cgn02
                   13995: 0:             
                   13996: #
                   13997: #      MERGE HERE FOR OPERAND YIELDING VALUE (E.G. CONSTANT)
                   13998: #
                   13999: cgn01: jmp     er_212          # syntax error. value used where name is required
                   14000: #
                   14001: #      HERE FOR NATURAL VARIABLE REFERENCE
                   14002: #
                   14003: cgn02: movl    $olvn$,r6       # load variable load call
                   14004:        jsb     cdwrd           # generate it
                   14005:        movl    r9,r6           # copy vrblk pointer
                   14006:        jsb     cdwrd           # generate vrblk pointer
                   14007:        #page   
                   14008: #
                   14009: #      CDGNM (CONTINUED)
                   14010: #
                   14011: #      HERE TO EXIT WITH WC SET CORRECTLY
                   14012: #
                   14013: cgn03: movl    (sp)+,r7        # restore entry wb
                   14014:        movl    (sp)+,r10       # restore entry xl
                   14015:        rsb                     # return to cdgnm caller
                   14016: #
                   14017: #      HERE FOR CMBLK
                   14018: #
                   14019: cgn04: movl    r9,r10          # copy cmblk pointer
                   14020:        movl    4*cmtyp(r9),r9  # load cmblk type
                   14021:        cmpl    r9,$c$$nm       # error if not name operand
                   14022:        bgequ   cgn01
                   14023:        casel   r9,$0,$c$$nm    # else switch on type
                   14024: 5:             
                   14025:        .word   cgn05-5b        # array reference
                   14026:        .word   cgn08-5b        # function call
                   14027:        .word   cgn09-5b        # deferred expression
                   14028:        .word   cgn10-5b        # indirect reference
                   14029:        .word   cgn11-5b        # keyword reference
                   14030:        .word   cgn08-5b        # undefined binary op
                   14031:        .word   cgn08-5b        # undefined unary op
                   14032:        #esw                    # end switch on cmblk type
                   14033: #
                   14034: #      HERE TO GENERATE CODE FOR ARRAY REFERENCE
                   14035: #
                   14036: cgn05: movl    $4*cmopn,r7     # point to array operand
                   14037: #
                   14038: #      LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS
                   14039: #
                   14040: cgn06: jsb     cmgen           # generate code for next operand
                   14041:        movl    4*cmlen(r10),r8 # load length of cmblk
                   14042:        cmpl    r7,r8           # loop till all generated
                   14043:        blssu   cgn06
                   14044: #
                   14045: #      GENERATE APPROPRIATE ARRAY CALL
                   14046: #
                   14047:        movl    $oaon$,r6       # load one-subscript case call
                   14048:        cmpl    r8,$4*cmar1     # jump to exit if one subscript case
                   14049:        beqlu   cgn07
                   14050:        movl    $oamn$,r6       # else load multi-subscript case call
                   14051:        jsb     cdwrd           # generate call
                   14052:        movl    r8,r6           # copy cmblk length
                   14053:        ashl    $-2,r6,r6       # convert to words
                   14054:        subl2   $cmvls,r6       # calculate number of subscripts
                   14055:        #page   
                   14056: #
                   14057: #      CDGNM (CONTINUED)
                   14058: #
                   14059: #      HERE TO EXIT GENERATING WORD (NON-CONSTANT)
                   14060: #
                   14061: cgn07: movl    sp,r8           # set result non-constant
                   14062:        jsb     cdwrd           # generate word
                   14063:        jmp     cgn03           # back to exit
                   14064: #
                   14065: #      HERE TO GENERATE CODE FOR FUNCTIONS AND UNDEFINED OPRS
                   14066: #
                   14067: cgn08: movl    r10,r9          # copy cmblk pointer
                   14068:        jsb     cdgvl           # gen code by value for call
                   14069:        movl    $ofne$,r6       # get extra call for by name
                   14070:        jmp     cgn07           # back to generate and exit
                   14071: #
                   14072: #      HERE TO GENERATE CODE FOR DEFERED EXPRESSION
                   14073: #
                   14074: cgn09: movl    4*cmrop(r10),r9 # check if variable
                   14075:        cmpl    (r9),$b$vr$     # treat *variable as simple var
                   14076:        blssu   0f
                   14077:        jmp     cgn02
                   14078: 0:             
                   14079:        movl    r9,r10          # copy ptr to expression tree
                   14080:        jsb     cdgex           # else build exblk
                   14081:        movl    $olex$,r6       # set call to load expr by name
                   14082:        jsb     cdwrd           # generate it
                   14083:        movl    r9,r6           # copy exblk pointer
                   14084:        jsb     cdwrd           # generate exblk pointer
                   14085:        jmp     cgn03           # back to exit
                   14086: #
                   14087: #      HERE TO GENERATE CODE FOR INDIRECT REFERENCE
                   14088: #
                   14089: cgn10: movl    4*cmrop(r10),r9 # get operand
                   14090:        jsb     cdgvl           # generate code by value for it
                   14091:        movl    $oinn$,r6       # load call for indirect by name
                   14092:        jmp     cgn12           # merge
                   14093: #
                   14094: #      HERE TO GENERATE CODE FOR KEYWORD REFERENCE
                   14095: #
                   14096: cgn11: movl    4*cmrop(r10),r9 # get operand
                   14097:        jsb     cdgnm           # generate code by name for it
                   14098:        movl    $okwn$,r6       # load call for keyword by name
                   14099: #
                   14100: #      KEYWORD, INDIRECT MERGE HERE
                   14101: #
                   14102: cgn12: jsb     cdwrd           # generate code for operator
                   14103:        jmp     cgn03           # exit
                   14104:        #enp                    # end procedure cdgnm
                   14105:        #page   
                   14106: #
                   14107: #      CDGVL -- GENERATE CODE BY VALUE
                   14108: #
                   14109: #      CDGVL IS CALLED DURING THE COMPILATION PROCESS TO
                   14110: #      GENERATE CODE BY VALUE FOR AN EXPRESSION. SEE CDBLK
                   14111: #      DESCRIPTION FOR DETAILS OF THE CODE GENERATED. THE INPUT
                   14112: #      TO CDGVL IS AN EXPRESSION TREE AS GENERATED BY EXPAN.
                   14113: #
                   14114: #      CDGVL IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING
                   14115: #      RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS.
                   14116: #
                   14117: #      (WB)                  INTEGER IN RANGE 0 LE N LE DNAMB
                   14118: #      (XR)                  PTR TO TREE GENERATED BY EXPAN
                   14119: #      (WC)                  CONSTANT FLAG (SEE BELOW)
                   14120: #      JSR  CDGVL            CALL TO GENERATE CODE BY VALUE
                   14121: #      (XR,WA)               DESTROYED
                   14122: #      (WC)                  SET NON-ZERO IF NON-CONSTANT
                   14123: #
                   14124: #      WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE
                   14125: #      EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE
                   14126: #      EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED.
                   14127: #
                   14128: #      IF WC IS NON-ZERO ON ENTRY, THEN PREEVALUATION IS NOT
                   14129: #      ALLOWED REGARDLESS OF THE NATURE OF THE OPERAND.
                   14130: #
                   14131: #      THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD).
                   14132: #
                   14133: cdgvl: #prc                    # entry point, recursive
                   14134:        movl    (r9),r6         # load type word
                   14135:        cmpl    r6,$b$cmt       # jump if cmblk
                   14136:        beqlu   cgv01
                   14137:        cmpl    r6,$b$vra       # jump if icblk, rcblk, scblk
                   14138:        blssu   cgv00
                   14139:        tstl    4*vrlen(r9)     # jump if not system variable
                   14140:        bnequ   cgvl0
                   14141:        movl    r9,-(sp)        # stack xr
                   14142:        movl    4*vrsvp(r9),r9  # point to svblk
                   14143:        movl    4*svbit(r9),r6  # get svblk property bits
                   14144:        movl    (sp)+,r9        # recover xr
                   14145:        mcoml   btckw,r11       # check if constant keyword
                   14146:        bicl2   r11,r6
                   14147:        bnequ   cgv00           # jump if constant keyword
                   14148: #
                   14149: #      HERE FOR VARIABLE VALUE REFERENCE
                   14150: #
                   14151: cgvl0: movl    sp,r8           # indicate non-constant value
                   14152: #
                   14153: #      MERGE HERE FOR SIMPLE CONSTANT (ICBLK,RCBLK,SCBLK)
                   14154: #      AND FOR VARIABLES CORRESPONDING TO CONSTANT KEYWORDS.
                   14155: #
                   14156: cgv00: movl    r9,r6           # copy ptr to var or constant
                   14157:        jsb     cdwrd           # generate as code word
                   14158:        rsb                     # return to caller
                   14159:        #page   
                   14160: #
                   14161: #      CDGVL (CONTINUED)
                   14162: #
                   14163: #      HERE FOR TREE NODE (CMBLK)
                   14164: #
                   14165: cgv01: movl    r7,-(sp)        # save entry wb
                   14166:        movl    r10,-(sp)       # save entry xl
                   14167:        movl    r8,-(sp)        # save entry constant flag
                   14168:        movl    cwcof,-(sp)     # save initial code offset
                   14169:        jsb     sbchk           # check for stack overflow
                   14170: #
                   14171: #      PREPARE TO GENERATE CODE FOR CMBLK. WC IS SET TO THE
                   14172: #      VALUE OF CSWNO (ZERO IF -OPTIMISE, 1 IF -NOOPT) TO
                   14173: #      START WITH AND IS RESET NON-ZERO FOR ANY NON-CONSTANT
                   14174: #      CODE GENERATED. IF IT IS STILL ZERO AFTER GENERATING ALL
                   14175: #      THE CMBLK CODE, THEN ITS VALUE IS COMPUTED AS THE RESULT.
                   14176: #
                   14177:        movl    r9,r10          # copy cmblk pointer
                   14178:        movl    4*cmtyp(r9),r9  # load cmblk type
                   14179:        movl    cswno,r8        # reset constant flag
                   14180:        cmpl    r9,$c$pr$       # jump if not predicate value
                   14181:        blequ   cgv02
                   14182:        movl    sp,r8           # else force non-constant case
                   14183: #
                   14184: #      HERE WITH WC SET APPROPRIATELY
                   14185: #
                   14186: cgv02: casel   r9,$0,$c$$nv    # switch to appropriate generator
                   14187: 5:             
                   14188:        .word   cgv03-5b        # array reference
                   14189:        .word   cgv05-5b        # function call
                   14190:        .word   cgv14-5b        # deferred expression
                   14191:        .word   cgv31-5b        # indirect reference
                   14192:        .word   cgv27-5b        # keyword reference
                   14193:        .word   cgv29-5b        # undefined binop
                   14194:        .word   cgv30-5b        # undefined unop
                   14195:        .word   cgv18-5b        # binops with val opds
                   14196:        .word   cgv19-5b        # unops with valu opnd
                   14197:        .word   cgv18-5b        # alternation
                   14198:        .word   cgv24-5b        # concatenation
                   14199:        .word   cgv24-5b        # concatenation (not pattern match)
                   14200:        .word   cgv27-5b        # unops with name opnd
                   14201:        .word   cgv26-5b        # binary $ and .
                   14202:        .word   cgv21-5b        # assignment
                   14203:        .word   cgv31-5b        # interrogation
                   14204:        .word   cgv28-5b        # negation
                   14205:        .word   cgv15-5b        # selection
                   14206:        .word   cgv18-5b        # pattern match
                   14207:        #esw                    # end switch on cmblk type
                   14208:        #page   
                   14209: #
                   14210: #      CDGVL (CONTINUED)
                   14211: #
                   14212: #      HERE TO GENERATE CODE FOR ARRAY REFERENCE
                   14213: #
                   14214: cgv03: movl    $4*cmopn,r7     # set offset to array operand
                   14215: #
                   14216: #      LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS
                   14217: #
                   14218: cgv04: jsb     cmgen           # gen value code for next operand
                   14219:        movl    4*cmlen(r10),r8 # load cmblk length
                   14220:        cmpl    r7,r8           # loop back if more to go
                   14221:        blssu   cgv04
                   14222: #
                   14223: #      GENERATE CALL TO APPROPRIATE ARRAY REFERENCE ROUTINE
                   14224: #
                   14225:        movl    $oaov$,r6       # set one subscript call in case
                   14226:        cmpl    r8,$4*cmar1     # jump to exit if 1-sub case
                   14227:        bnequ   0f
                   14228:        jmp     cgv32
                   14229: 0:             
                   14230:        movl    $oamv$,r6       # else set call for multi-subscripts
                   14231:        jsb     cdwrd           # generate call
                   14232:        movl    r8,r6           # copy length of cmblk
                   14233:        subl2   $4*cmvls,r6     # subtract standard length
                   14234:        ashl    $-2,r6,r6       # get number of words
                   14235:        jmp     cgv32           # jump to generate subscript count
                   14236: #
                   14237: #      HERE TO GENERATE CODE FOR FUNCTION CALL
                   14238: #
                   14239: cgv05: movl    $4*cmvls,r7     # set offset to first argument
                   14240: #
                   14241: #      LOOP TO GENERATE CODE FOR ARGUMENTS
                   14242: #
                   14243: cgv06: cmpl    r7,4*cmlen(r10) # jump if all generated
                   14244:        beqlu   cgv07
                   14245:        jsb     cmgen           # else gen value code for next arg
                   14246:        jmp     cgv06           # back to generate next argument
                   14247: #
                   14248: #      HERE TO GENERATE ACTUAL FUNCTION CALL
                   14249: #
                   14250: cgv07: subl2   $4*cmvls,r7     # get number of arg ptrs (bytes)
                   14251:        ashl    $-2,r7,r7       # convert bytes to words
                   14252:        movl    4*cmopn(r10),r9 # load function vrblk pointer
                   14253:        tstl    4*vrlen(r9)     # jump if not system function
                   14254:        bnequ   cgv12
                   14255:        movl    4*vrsvp(r9),r10 # load svblk ptr if system var
                   14256:        movl    4*svbit(r10),r6 # load bit mask
                   14257:        mcoml   btffc,r11       # test for fast function call allowed
                   14258:        bicl2   r11,r6
                   14259:        beqlu   cgv12           # jump if not
                   14260:        #page   
                   14261: #
                   14262: #      CDGVL (CONTINUED)
                   14263: #
                   14264: #      HERE IF FAST FUNCTION CALL IS ALLOWED
                   14265: #
                   14266:        movl    4*svbit(r10),r6 # reload bit indicators
                   14267:        mcoml   btpre,r11       # test for preevaluation ok
                   14268:        bicl2   r11,r6
                   14269:        bnequ   cgv08           # jump if preevaluation permitted
                   14270:        movl    sp,r8           # else set result non-constant
                   14271: #
                   14272: #      TEST FOR CORRECT NUMBER OF ARGS FOR FAST CALL
                   14273: #
                   14274: cgv08: movl    4*vrfnc(r9),r10 # load ptr to svfnc field
                   14275:        movl    4*fargs(r10),r6 # load svnar field value
                   14276:        cmpl    r6,r7           # jump if argument count is correct
                   14277:        beqlu   cgv11
                   14278:        cmpl    r6,r7           # jump if too few arguments given
                   14279:        bgequ   cgv09
                   14280: #
                   14281: #      HERE IF TOO MANY ARGUMENTS, PREPARE TO GENERATE O$POPS
                   14282: #
                   14283:        subl2   r6,r7           # get number of extra args
                   14284:                                # set as count to control loop
                   14285:        movl    $opop$,r6       # set pop call
                   14286:        jmp     cgv10           # jump to common loop
                   14287: #
                   14288: #      HERE IF TOO FEW ARGUMENTS, PREPARE TO GENERATE NULLS
                   14289: #
                   14290: cgv09: subl2   r7,r6           # get number of missing arguments
                   14291:        movl    r6,r7           # load as count to control loop
                   14292:        movl    $nulls,r6       # load ptr to null constant
                   14293: #
                   14294: #      LOOP TO GENERATE CALLS TO FIX ARGUMENT COUNT
                   14295: #
                   14296: cgv10: jsb     cdwrd           # generate one call
                   14297:        sobgtr  r7,cgv10        # loop till all generated
                   14298: #
                   14299: #      HERE AFTER ADJUSTING ARG COUNT AS REQUIRED
                   14300: #
                   14301: cgv11: movl    r10,r6          # copy pointer to svfnc field
                   14302:        jmp     cgv36           # jump to generate call
                   14303:        #page   
                   14304: #
                   14305: #      CDGVL (CONTINUED)
                   14306: #
                   14307: #      COME HERE IF FAST CALL IS NOT PERMITTED
                   14308: #
                   14309: cgv12: movl    $ofns$,r6       # set one arg call in case
                   14310:        cmpl    r7,$num01       # jump if one arg case
                   14311:        beqlu   cgv13
                   14312:        movl    $ofnc$,r6       # else load call for more than 1 arg
                   14313:        jsb     cdwrd           # generate it
                   14314:        movl    r7,r6           # copy argument count
                   14315: #
                   14316: #      ONE ARG CASE MERGES HERE
                   14317: #
                   14318: cgv13: jsb     cdwrd           # generate =o$fns or arg count
                   14319:        movl    r9,r6           # copy vrblk pointer
                   14320:        jmp     cgv32           # jump to generate vrblk ptr
                   14321: #
                   14322: #      HERE FOR DEFERRED EXPRESSION
                   14323: #
                   14324: cgv14: movl    4*cmrop(r10),r10# point to expression tree
                   14325:        jsb     cdgex           # build exblk or seblk
                   14326:        movl    r9,r6           # copy block ptr
                   14327:        jsb     cdwrd           # generate ptr to exblk or seblk
                   14328:        jmp     cgv34           # jump to exit, constant test
                   14329: #
                   14330: #      HERE TO GENERATE CODE FOR SELECTION
                   14331: #
                   14332: cgv15: clrl    -(sp)           # zero ptr to chain of forward jumps
                   14333:        clrl    -(sp)           # zero ptr to prev o$slc forward ptr
                   14334:        movl    $4*cmvls,r7     # point to first alternative
                   14335:        movl    $osla$,r6       # set initial code word
                   14336: #
                   14337: #      0(XS)                 IS THE OFFSET TO THE PREVIOUS WORD
                   14338: #                            WHICH REQUIRES FILLING IN WITH AN
                   14339: #                            OFFSET TO THE FOLLOWING O$SLC,O$SLD
                   14340: #
                   14341: #      1(XS)                 IS THE HEAD OF A CHAIN OF OFFSET
                   14342: #                            POINTERS INDICATING THOSE LOCATIONS
                   14343: #                            TO BE FILLED WITH OFFSETS PAST
                   14344: #                            THE END OF ALL THE ALTERNATIVES
                   14345: #
                   14346: cgv16: jsb     cdwrd           # generate o$slc (o$sla first time)
                   14347:        movl    cwcof,(sp)      # set current loc as ptr to fill in
                   14348:        jsb     cdwrd           # generate garbage word there for now
                   14349:        jsb     cmgen           # gen value code for alternative
                   14350:        movl    $oslb$,r6       # load o$slb pointer
                   14351:        jsb     cdwrd           # generate o$slb call
                   14352:        movl    4*1(sp),r6      # load old chain ptr
                   14353:        movl    cwcof,4*1(sp)   # set current loc as new chain head
                   14354:        jsb     cdwrd           # generate forward chain link
                   14355:        #page   
                   14356: #
                   14357: #      CDGVL (CONTINUED)
                   14358: #
                   14359: #      NOW TO FILL IN THE SKIP OFFSET TO O$SLC,O$SLD
                   14360: #
                   14361:        movl    (sp),r9         # load offset to word to plug
                   14362:        addl2   r$ccb,r9        # point to actual location to plug
                   14363:        movl    cwcof,(r9)      # plug proper offset in
                   14364:        movl    $oslc$,r6       # load o$slc ptr for next alternative
                   14365:        movl    r7,r9           # copy offset (destroy garbage xr)
                   14366:        addl2   $4,r9           # bump extra time for test
                   14367:        cmpl    r9,4*cmlen(r10) # loop back if not last alternative
                   14368:        blssu   cgv16
                   14369: #
                   14370: #      HERE TO GENERATE CODE FOR LAST ALTERNATIVE
                   14371: #
                   14372:        movl    $osld$,r6       # get header call
                   14373:        jsb     cdwrd           # generate o$sld call
                   14374:        jsb     cmgen           # generate code for last alternative
                   14375:        addl2   $4,sp           # pop offset ptr
                   14376:        movl    (sp)+,r9        # load chain ptr
                   14377: #
                   14378: #      LOOP TO PLUG OFFSETS PAST STRUCTURE
                   14379: #
                   14380: cgv17: addl2   r$ccb,r9        # make next ptr absolute
                   14381:        movl    (r9),r6         # load forward ptr
                   14382:        movl    cwcof,(r9)      # plug required offset
                   14383:        movl    r6,r9           # copy forward ptr
                   14384:        tstl    r6              # loop back if more to go
                   14385:        bnequ   cgv17
                   14386:        jmp     cgv33           # else jump to exit (not constant)
                   14387: #
                   14388: #      HERE FOR BINARY OPS WITH VALUE OPERANDS
                   14389: #
                   14390: cgv18: movl    4*cmlop(r10),r9 # load left operand pointer
                   14391:        jsb     cdgvl           # gen value code for left operand
                   14392: #
                   14393: #      HERE FOR UNARY OPS WITH VALUE OPERAND (BINOPS MERGE)
                   14394: #
                   14395: cgv19: movl    4*cmrop(r10),r9 # load right (only) operand ptr
                   14396:        jsb     cdgvl           # gen code by value
                   14397:        #page   
                   14398: #
                   14399: #      CDGVL (CONTINUED)
                   14400: #
                   14401: #      MERGE HERE TO GENERATE OPERATOR CALL FROM CMOPN FIELD
                   14402: #
                   14403: cgv20: movl    4*cmopn(r10),r6 # load operator call pointer
                   14404:        jmp     cgv36           # jump to generate it with cons test
                   14405: #
                   14406: #      HERE FOR ASSIGNMENT
                   14407: #
                   14408: cgv21: movl    4*cmlop(r10),r9 # load left operand pointer
                   14409:        cmpl    (r9),$b$vr$     # jump if not variable
                   14410:        blequ   cgv22
                   14411: #
                   14412: #      HERE FOR ASSIGNMENT TO SIMPLE VARIABLE
                   14413: #
                   14414:        movl    4*cmrop(r10),r9 # load right operand ptr
                   14415:        jsb     cdgvl           # generate code by value
                   14416:        movl    4*cmlop(r10),r6 # reload left operand vrblk ptr
                   14417:        addl2   $4*vrsto,r6     # point to vrsto field
                   14418:        jmp     cgv32           # jump to generate store ptr
                   14419: #
                   14420: #      HERE IF NOT SIMPLE VARIABLE ASSIGNMENT
                   14421: #
                   14422: cgv22: jsb     expap           # test for pattern match on left side
                   14423:        .long   cgv23           # jump if not pattern match
                   14424: #
                   14425: #      HERE FOR PATTERN REPLACEMENT
                   14426: #
                   14427:        movl    4*cmrop(r9),4*cmlop(r10) # save pattern ptr in safe place
                   14428:        movl    4*cmlop(r9),r9  # load subject ptr
                   14429:        jsb     cdgnm           # gen code by name for subject
                   14430:        movl    4*cmlop(r10),r9 # load pattern ptr
                   14431:        jsb     cdgvl           # gen code by value for pattern
                   14432:        movl    $opmn$,r6       # load match by name call
                   14433:        jsb     cdwrd           # generate it
                   14434:        movl    4*cmrop(r10),r9 # load replacement value ptr
                   14435:        jsb     cdgvl           # gen code by value
                   14436:        movl    $orpl$,r6       # load replace call
                   14437:        jmp     cgv32           # jump to gen and exit (not constant)
                   14438: #
                   14439: #      HERE FOR ASSIGNMENT TO COMPLEX VARIABLE
                   14440: #
                   14441: cgv23: movl    sp,r8           # inhibit pre-evaluation
                   14442:        jsb     cdgnm           # gen code by name for left side
                   14443:        jmp     cgv31           # merge with unop circuit
                   14444:        #page   
                   14445: #
                   14446: #      CDGVL (CONTINUED)
                   14447: #
                   14448: #      HERE FOR CONCATENATION
                   14449: #
                   14450: cgv24: movl    4*cmlop(r10),r9 # load left operand ptr
                   14451:        cmpl    (r9),$b$cmt     # ordinary binop if not cmblk
                   14452:        beqlu   0f
                   14453:        jmp     cgv18
                   14454: 0:             
                   14455:        movl    4*cmtyp(r9),r7  # load cmblk type code
                   14456:        cmpl    r7,$c$int       # special case if interrogation
                   14457:        beqlu   cgv25
                   14458:        cmpl    r7,$c$neg       # or negation
                   14459:        beqlu   cgv25
                   14460:        cmpl    r7,$c$fnc       # else ordinary binop if not function
                   14461:        beqlu   0f
                   14462:        jmp     cgv18
                   14463: 0:             
                   14464:        movl    4*cmopn(r9),r9  # else load function vrblk ptr
                   14465:        tstl    4*vrlen(r9)     # ordinary binop if not system var
                   14466:        beqlu   0f
                   14467:        jmp     cgv18
                   14468: 0:             
                   14469:        movl    4*vrsvp(r9),r9  # else point to svblk
                   14470:        movl    4*svbit(r9),r6  # load bit indicators
                   14471:        mcoml   btprd,r11       # test for predicate function
                   14472:        bicl2   r11,r6
                   14473:        bnequ   0f              # ordinary binop if not
                   14474:        jmp     cgv18
                   14475: 0:             
                   14476: #
                   14477: #      HERE IF LEFT ARG OF CONCATENATION IS PREDICATE FUNCTION
                   14478: #
                   14479: cgv25: movl    4*cmlop(r10),r9 # reload left arg
                   14480:        jsb     cdgvl           # gen code by value
                   14481:        movl    $opop$,r6       # load pop call
                   14482:        jsb     cdwrd           # generate it
                   14483:        movl    4*cmrop(r10),r9 # load right operand
                   14484:        jsb     cdgvl           # gen code by value as result code
                   14485:        jmp     cgv33           # exit (not constant)
                   14486: #
                   14487: #      HERE TO GENERATE CODE FOR PATTERN, IMMEDIATE ASSIGNMENT
                   14488: #
                   14489: cgv26: movl    4*cmlop(r10),r9 # load left operand
                   14490:        jsb     cdgvl           # gen code by value, merge
                   14491: #
                   14492: #      HERE FOR UNOPS WITH ARG BY NAME (BINARY $ . MERGE)
                   14493: #
                   14494: cgv27: movl    4*cmrop(r10),r9 # load right operand ptr
                   14495:        jsb     cdgnm           # gen code by name for right arg
                   14496:        movl    4*cmopn(r10),r9 # get operator code word
                   14497:        cmpl    (r9),$o$kwv     # gen call unless keyword value
                   14498:        beqlu   0f
                   14499:        jmp     cgv20
                   14500: 0:             
                   14501:        #page   
                   14502: #
                   14503: #      CDGVL (CONTINUED)
                   14504: #
                   14505: #      HERE FOR KEYWORD BY VALUE. THIS IS CONSTANT ONLY IF
                   14506: #      THE OPERAND IS ONE OF THE SPECIAL SYSTEM VARIABLES WITH
                   14507: #      THE SVCKW BIT SET TO INDICATE A CONSTANT KEYWORD VALUE.
                   14508: #      NOTE THAT THE ONLY CONSTANT OPERAND BY NAME IS A VARIABLE
                   14509: #
                   14510:        tstl    r8              # gen call if non-constant (not var)
                   14511:        beqlu   0f
                   14512:        jmp     cgv20
                   14513: 0:             
                   14514:        movl    sp,r8           # else set non-constant in case
                   14515:        movl    4*cmrop(r10),r9 # load ptr to operand vrblk
                   14516:        tstl    4*vrlen(r9)     # gen (non-constant) if not sys var
                   14517:        beqlu   0f
                   14518:        jmp     cgv20
                   14519: 0:             
                   14520:        movl    4*vrsvp(r9),r9  # else load ptr to svblk
                   14521:        movl    4*svbit(r9),r6  # load bit mask
                   14522:        mcoml   btckw,r11       # test for constant keyword
                   14523:        bicl2   r11,r6
                   14524:        bnequ   0f              # go gen if not constant
                   14525:        jmp     cgv20
                   14526: 0:             
                   14527:        clrl    r8              # else set result constant
                   14528:        jmp     cgv20           # and jump back to generate call
                   14529: #
                   14530: #      HERE TO GENERATE CODE FOR NEGATION
                   14531: #
                   14532: cgv28: movl    $onta$,r6       # get initial word
                   14533:        jsb     cdwrd           # generate it
                   14534:        movl    cwcof,r7        # save next offset
                   14535:        jsb     cdwrd           # generate gunk word for now
                   14536:        movl    4*cmrop(r10),r9 # load right operand ptr
                   14537:        jsb     cdgvl           # gen code by value
                   14538:        movl    $ontb$,r6       # load end of evaluation call
                   14539:        jsb     cdwrd           # generate it
                   14540:        movl    r7,r9           # copy offset to word to plug
                   14541:        addl2   r$ccb,r9        # point to actual word to plug
                   14542:        movl    cwcof,(r9)      # plug word with current offset
                   14543:        movl    $ontc$,r6       # load final call
                   14544:        jmp     cgv32           # jump to generate it (not constant)
                   14545: #
                   14546: #      HERE TO GENERATE CODE FOR UNDEFINED BINARY OPERATOR
                   14547: #
                   14548: cgv29: movl    4*cmlop(r10),r9 # load left operand ptr
                   14549:        jsb     cdgvl           # generate code by value
                   14550:        #page   
                   14551: #
                   14552: #      CDGVL (CONTINUED)
                   14553: #
                   14554: #      HERE TO GENERATE CODE FOR UNDEFINED UNARY OPERATOR
                   14555: #
                   14556: cgv30: movl    $c$uo$,r7       # set unop code + 1
                   14557:        subl2   4*cmtyp(r10),r7 # set number of args (1 or 2)
                   14558: #
                   14559: #      MERGE HERE FOR UNDEFINED OPERATORS
                   14560: #
                   14561:        movl    4*cmrop(r10),r9 # load right (only) operand pointer
                   14562:        jsb     cdgvl           # gen value code for right operand
                   14563:        movl    4*cmopn(r10),r9 # load pointer to operator dv
                   14564:        movl    4*dvopn(r9),r9  # load pointer offset
                   14565:        moval   0[r9],r9        # convert word offset to bytes
                   14566:        addl2   $r$uba,r9       # point to proper function ptr
                   14567:        subl2   $4*vrfnc,r9     # set standard function offset
                   14568:        jmp     cgv12           # merge with function call circuit
                   14569: #
                   14570: #      HERE TO GENERATE CODE FOR INTERROGATION, INDIRECTION
                   14571: #
                   14572: cgv31: movl    sp,r8           # set non constant
                   14573:        jmp     cgv19           # merge
                   14574: #
                   14575: #      HERE TO EXIT GENERATING A WORD, RESULT NOT CONSTANT
                   14576: #
                   14577: cgv32: jsb     cdwrd           # generate word, merge
                   14578: #
                   14579: #      HERE TO EXIT WITH NO WORD GENERATED, NOT CONSTANT
                   14580: #
                   14581: cgv33: movl    sp,r8           # indicate result is not constant
                   14582: #
                   14583: #      COMMON EXIT POINT
                   14584: #
                   14585: cgv34: addl2   $4,sp           # pop initial code offset
                   14586:        movl    (sp)+,r6        # restore old constant flag
                   14587:        movl    (sp)+,r10       # restore entry xl
                   14588:        movl    (sp)+,r7        # restore entry wb
                   14589:        tstl    r8              # jump if not constant
                   14590:        bnequ   cgv35
                   14591:        movl    r6,r8           # else restore entry constant flag
                   14592: #
                   14593: #      HERE TO RETURN AFTER DEALING WITH WC SETTING
                   14594: #
                   14595: cgv35: rsb                     # return to cdgvl caller
                   14596: #
                   14597: #      EXIT HERE TO GENERATE WORD AND TEST FOR CONSTANT
                   14598: #
                   14599: cgv36: jsb     cdwrd           # generate word
                   14600:        tstl    r8              # jump to exit if not constant
                   14601:        bnequ   cgv34
                   14602:        #page   
                   14603: #
                   14604: #      CDGVL (CONTINUED)
                   14605: #
                   14606: #      HERE TO PREEVALUATE CONSTANT SUB-EXPRESSION
                   14607: #
                   14608:        movl    $orvl$,r6       # load call to return value
                   14609:        jsb     cdwrd           # generate it
                   14610:        movl    (sp),r10        # load initial code offset
                   14611:        jsb     exbld           # build exblk for expression
                   14612:        clrl    r7              # set to evaluate by value
                   14613:        jsb     evalx           # evaluate expression
                   14614:        .long   invalid$        # should not fail
                   14615:        movl    (r9),r6         # load type word of result
                   14616:        cmpl    r6,$p$aaa       # jump if not pattern
                   14617:        blequ   cgv37
                   14618:        movl    $olpt$,r6       # else load special pattern load call
                   14619:        jsb     cdwrd           # generate it
                   14620: #
                   14621: #      MERGE HERE TO GENERATE POINTER TO RESULTING CONSTANT
                   14622: #
                   14623: cgv37: movl    r9,r6           # copy constant pointer
                   14624:        jsb     cdwrd           # generate ptr
                   14625:        clrl    r8              # set result constant
                   14626:        jmp     cgv34           # jump back to exit
                   14627:        #enp                    # end procedure cdgvl
                   14628:        #page   
                   14629: #
                   14630: #      CDWRD -- GENERATE ONE WORD OF CODE
                   14631: #
                   14632: #      CDWRD WRITES ONE WORD INTO THE CURRENT CODE BLOCK UNDER
                   14633: #      CONSTRUCTION. A NEW, LARGER, BLOCK IS ALLOCATED IF THERE
                   14634: #      IS INSUFFICIENT ROOM IN THE CURRENT BLOCK. CDWRD ENSURES
                   14635: #      THAT THERE ARE AT LEAST THREE WORDS LEFT IN THE BLOCK
                   14636: #      AFTER ENTERING THE NEW WORD. THIS GUARANTEES THAT ANY
                   14637: #      EXTRA SPACE AT THE END CAN BE SPLIT OFF AS A CCBLK.
                   14638: #
                   14639: #      (WA)                  WORD TO BE GENERATED
                   14640: #      JSR  CDWRD            CALL TO GENERATE WORD
                   14641: #
                   14642: cdwrd: #prc                    # entry point
                   14643:        movl    r9,-(sp)        # save entry xr
                   14644:        movl    r6,-(sp)        # save code word to be generated
                   14645: #
                   14646: #      MERGE BACK HERE AFTER ALLOCATING LARGER BLOCK
                   14647: #
                   14648: cdwd1: movl    r$ccb,r9        # load ptr to ccblk being built
                   14649:        bnequ   cdwd2           # jump if block allocated
                   14650: #
                   14651: #      HERE WE ALLOCATE AN ENTIRELY FRESH BLOCK
                   14652: #
                   14653:        movl    $4*e$cbs,r6     # load initial length
                   14654:        jsb     alloc           # allocate ccblk
                   14655:        movl    $b$cct,(r9)     # store type word
                   14656:        movl    $4*cccod,cwcof  # set initial offset
                   14657:        movl    r6,4*cclen(r9)  # store block length
                   14658:        movl    r9,r$ccb        # store ptr to new block
                   14659: #
                   14660: #      HERE WE HAVE A BLOCK WE CAN USE
                   14661: #
                   14662: cdwd2: movl    cwcof,r6        # load current offset
                   14663:        addl2   $4*num04,r6     # adjust for test (four words)
                   14664:        cmpl    r6,4*cclen(r9)  # jump if room in this block
                   14665:        bgtru   0f
                   14666:        jmp     cdwd4
                   14667: 0:             
                   14668: #
                   14669: #      HERE IF NO ROOM IN CURRENT BLOCK
                   14670: #
                   14671:        cmpl    r6,mxlen        # jump if already at max size
                   14672:        blssu   0f
                   14673:        jmp     cdwd5
                   14674: 0:             
                   14675:        addl2   $4*e$cbs,r6     # else get new size
                   14676:        movl    r10,-(sp)       # save entry xl
                   14677:        movl    r9,r10          # copy pointer
                   14678:        cmpl    r6,mxlen        # jump if not too large
                   14679:        blssu   cdwd3
                   14680:        movl    mxlen,r6        # else reset to max allowed size
                   14681:        #page   
                   14682: #
                   14683: #      CDWRD (CONTINUED)
                   14684: #
                   14685: #      HERE WITH NEW BLOCK SIZE IN WA
                   14686: #
                   14687: cdwd3: jsb     alloc           # allocate new block
                   14688:        movl    r9,r$ccb        # store pointer to new block
                   14689:        movl    $b$cct,(r9)+    # store type word in new block
                   14690:        movl    r6,(r9)+        # store block length
                   14691:        addl2   $4*ccuse,r10    # point to ccuse,cccod fields in old
                   14692:        movl    (r10),r6        # load ccuse value
                   14693:        jsb     sbmvw           # copy useful words from old block
                   14694:        movl    (sp)+,r10       # restore xl
                   14695:        jmp     cdwd1           # merge back to try again
                   14696: #
                   14697: #      HERE WITH ROOM IN CURRENT BLOCK
                   14698: #
                   14699: cdwd4: movl    cwcof,r6        # load current offset
                   14700:        addl2   $4,r6           # get new offset
                   14701:        movl    r6,cwcof        # store new offset
                   14702:        movl    r6,4*ccuse(r9)  # store in ccblk for gbcol
                   14703:        subl2   $4,r6           # restore ptr to this word
                   14704:        addl2   r6,r9           # point to current entry
                   14705:        movl    (sp)+,r6        # reload word to generate
                   14706:        movl    r6,(r9)         # store word in block
                   14707:        movl    (sp)+,r9        # restore entry xr
                   14708:        rsb                     # return to caller
                   14709: #
                   14710: #      HERE IF COMPILED CODE IS TOO LONG FOR CDBLK
                   14711: #
                   14712: cdwd5: jmp     er_213          # syntax error. statement is too complicated.
                   14713:        #enp                    # end procedure cdwrd
                   14714:        #page   
                   14715: #
                   14716: #      CMGEN -- GENERATE CODE FOR CMBLK PTR
                   14717: #
                   14718: #      CMGEN IS A SUBSIDIARY PROCEDURE USED TO GENERATE VALUE
                   14719: #      CODE FOR A CMBLK PTR FROM THE MAIN CODE GENERATORS.
                   14720: #
                   14721: #      (XL)                  CMBLK POINTER
                   14722: #      (WB)                  OFFSET TO POINTER IN CMBLK
                   14723: #      JSR  CMGEN            CALL TO GENERATE CODE
                   14724: #      (XR,WA)               DESTROYED
                   14725: #      (WB)                  BUMPED BY ONE WORD
                   14726: #
                   14727: cmgen: #prc                    # entry point, recursive
                   14728:        movl    r10,r9          # copy cmblk pointer
                   14729:        addl2   r7,r9           # point to cmblk pointer
                   14730:        movl    (r9),r9         # load cmblk pointer
                   14731:        jsb     cdgvl           # generate code by value
                   14732:        addl2   $4,r7           # bump offset
                   14733:        rsb                     # return to caller
                   14734:        #enp                    # end procedure cmgen
                   14735:        #page   
                   14736: #
                   14737: #      CMPIL (COMPILE SOURCE CODE)
                   14738: #
                   14739: #      CMPIL IS USED TO CONVERT SNOBOL4 SOURCE CODE TO INTERNAL
                   14740: #      FORM (SEE CDBLK FORMAT). IT IS USED BOTH FOR THE INITIAL
                   14741: #      COMPILE AND AT RUN TIME BY THE CODE AND CONVERT FUNCTIONS
                   14742: #      THIS PROCEDURE HAS CONTROL FOR THE ENTIRE DURATION OF
                   14743: #      INITIAL COMPILATION. AN ERROR IN ANY PROCEDURE CALLED
                   14744: #      DURING COMPILATION WILL LEAD FIRST TO THE ERROR SECTION
                   14745: #      AND ULTIMATELY BACK HERE FOR RESUMED COMPILATION. THE
                   14746: #      RE-ENTRY POINTS AFTER AN ERROR ARE SPECIALLY LABELLED -
                   14747: #
                   14748: #      CMPCE                 RESUME AFTER CONTROL CARD ERROR
                   14749: #      CMPLE                 RESUME AFTER LABEL ERROR
                   14750: #      CMPSE                 RESUME AFTER STATEMENT ERROR
                   14751: #
                   14752: #      JSR  CMPIL            CALL TO COMPILE CODE
                   14753: #      (XR)                  PTR TO CDBLK FOR ENTRY STATEMENT
                   14754: #      (XL,WA,WB,WC,RA)      DESTROYED
                   14755: #
                   14756: #      THE FOLLOWING GLOBAL VARIABLES ARE REFERENCED
                   14757: #
                   14758: #      CMPSN                 NUMBER OF NEXT STATEMENT
                   14759: #                            TO BE COMPILED.
                   14760: #
                   14761: #      CSWXX                 CONTROL CARD SWITCH VALUES ARE
                   14762: #                            CHANGED WHEN RELEVANT CONTROL
                   14763: #                            CARDS ARE MET.
                   14764: #
                   14765: #      CWCOF                 OFFSET TO NEXT WORD IN CODE BLOCK
                   14766: #                            BEING BUILT (SEE CDWRD).
                   14767: #
                   14768: #      LSTSN                 NUMBER OF STATEMENT MOST RECENTLY
                   14769: #                            COMPILED (INITIALLY SET TO ZERO).
                   14770: #
                   14771: #      R$CIM                 CURRENT (INITIAL) COMPILER IMAGE
                   14772: #                            (ZERO FOR INITIAL COMPILE CALL)
                   14773: #
                   14774: #      R$CNI                 USED TO POINT TO FOLLOWING IMAGE.
                   14775: #                            (SEE READR PROCEDURE).
                   14776: #
                   14777: #      SCNGO                 GOTO SWITCH FOR SCANE PROCEDURE
                   14778: #
                   14779: #      SCNIL                 LENGTH OF CURRENT IMAGE EXCLUDING
                   14780: #                            CHARACTERS REMOVED BY -INPUT.
                   14781: #
                   14782: #      SCNPT                 CURRENT SCAN OFFSET, SEE SCANE.
                   14783: #
                   14784: #      SCNRS                 RESCAN SWITCH FOR SCANE PROCEDURE.
                   14785: #
                   14786: #      SCNSE                 OFFSET (IN R$CIM) OF MOST RECENTLY
                   14787: #                            SCANNED ELEMENT. SET ZERO IF NOT
                   14788: #                            CURRENTLY SCANNING ITEMS
                   14789:        #page   
                   14790: #
                   14791: #      CMPIL (CONTINUED)
                   14792: #
                   14793: #      STAGE               STGIC  INITIAL COMPILE IN PROGRESS
                   14794: #                          STGXC  CODE/CONVERT COMPILE
                   14795: #                          STGEV  BUILDING EXBLK FOR EVAL
                   14796: #                          STGXT  EXECUTE TIME (OUTSIDE COMPILE)
                   14797: #                          STGCE  INITIAL COMPILE AFTER END LINE
                   14798: #                          STGXE  EXECUTE COMPILE AFTER END LINE
                   14799: #
                   14800: #      CMPIL ALSO USES A FIXED NUMBER OF LOCATIONS ON THE
                   14801: #      MAIN STACK AS FOLLOWS. (THE DEFINITIONS OF THE ACTUAL
                   14802: #      OFFSETS ARE IN THE DEFINITIONS SECTION).
                   14803: #
                   14804: #      CMSTM(XS)             POINTER TO EXPAN TREE FOR BODY OF
                   14805: #                            STATEMENT (SEE EXPAN PROCEDURE).
                   14806: #
                   14807: #      CMSGO(XS)             POINTER TO TREE REPRESENTATION OF
                   14808: #                            SUCCESS GOTO (SEE PROCEDURE SCNGO)9
                   14809: #                            ZERO IF NO SUCCESS GOTO IS GIVEN
                   14810: #
                   14811: #      CMFGO(XS)             LIKE CMSGO FOR FAILURE GOTO.
                   14812: #
                   14813: #      CMCGO(XS)             SET NON-ZERO ONLY IF THERE IS A
                   14814: #                            CONDITIONAL GOTO. USED FOR -FAIL,
                   14815: #                            -NOFAIL CODE GENERATION.
                   14816: #
                   14817: #      CMPCD(XS)             POINTER TO CDBLK FOR PREVIOUS
                   14818: #                            STATEMENT. ZERO FOR 1ST STATEMENT.
                   14819: #
                   14820: #      CMFFP(XS)             SET NON-ZERO IF CDFAL IN PREVIOUS
                   14821: #                            CDBLK NEEDS FILLING WITH FORWARD
                   14822: #                            POINTER, ELSE SET TO ZERO.
                   14823: #
                   14824: #      CMFFC(XS)             SAME AS CMFFP FOR CURRENT CDBLK
                   14825: #
                   14826: #      CMSOP(XS)             OFFSET TO WORD IN PREVIOUS CDBLK
                   14827: #                            TO BE FILLED IN WITH FORWARD PTR
                   14828: #                            TO NEXT CDBLK FOR SUCCESS GOTO.
                   14829: #                            ZERO IF NO FILL IN IS REQUIRED.
                   14830: #
                   14831: #      CMSOC(XS)             SAME AS CMSOP FOR CURRENT CDBLK.
                   14832: #
                   14833: #      CMLBL(XS)             POINTER TO VRBLK FOR LABEL OF
                   14834: #                            CURRENT STATEMENT. ZERO IF NO LABEL
                   14835: #
                   14836: #      CMTRA(XS)             POINTER TO CDBLK FOR ENTRY STMNT.
                   14837:        #page   
                   14838: #
                   14839: #      CMPIL (CONTINUED)
                   14840: #
                   14841: #      ENTRY POINT
                   14842: #
                   14843: cmpil: #prc                    # entry point
                   14844:        movl    $cmnen,r7       # set number of stack work locations
                   14845: #
                   14846: #      LOOP TO INITIALIZE STACK WORKING LOCATIONS
                   14847: #
                   14848: cmp00: clrl    -(sp)           # store a zero, make one entry
                   14849:        sobgtr  r7,cmp00        # loop back until all set
                   14850:        movl    sp,cmpxs        # save stack pointer for error sec
                   14851:        #sss    cmpss           # save s-r stack pointer if any
                   14852: #
                   14853: #      LOOP THROUGH STATEMENTS
                   14854: #
                   14855: cmp01: movl    scnpt,r7        # set scan pointer offset
                   14856:        movl    r7,scnse        # set start of element location
                   14857:        movl    $ocer$,r6       # point to compile error call
                   14858:        jsb     cdwrd           # generate as temporary cdfal
                   14859:        cmpl    r7,scnil        # jump if chars left on this image
                   14860:        blssu   cmp04
                   14861: #
                   14862: #      LOOP HERE AFTER COMMENT OR CONTROL CARD
                   14863: #      ALSO SPECIAL ENTRY AFTER CONTROL CARD ERROR
                   14864: #
                   14865: cmpce: clrl    r9              # clear possible garbage xr value
                   14866:        cmpl    stage,$stgic    # skip unless initial compile
                   14867:        bnequ   cmp02
                   14868:        jsb     readr           # read next input image
                   14869:        tstl    r9              # jump if no input available
                   14870:        bnequ   0f
                   14871:        jmp     cmp09
                   14872: 0:             
                   14873:        jsb     nexts           # acquire next source image
                   14874:        movl    cmpsn,lstsn     # store stmt no for use by listr
                   14875:        clrl    scnpt           # reset scan pointer
                   14876:        jmp     cmp04           # go process image
                   14877: #
                   14878: #      FOR EXECUTE TIME COMPILE, PERMIT EMBEDDED CONTROL CARDS
                   14879: #      AND COMMENTS (BY SKIPPING TO NEXT SEMI-COLON)
                   14880: #
                   14881: cmp02: movl    r$cim,r9        # get current image
                   14882:        movl    scnpt,r7        # get current offset
                   14883:        movab   cfp$f(r9)[r7],r9# prepare to get chars
                   14884: #
                   14885: #      SKIP TO SEMI-COLON
                   14886: #
                   14887: cmp03: movzbl  (r9)+,r8        # get char
                   14888:        incl    scnpt           # advance offset
                   14889:        cmpl    r8,$ch$sm       # skip if semi-colon found
                   14890:        beqlu   cmp04
                   14891:        cmpl    scnpt,scnil     # loop if more chars
                   14892:        blssu   cmp03
                   14893:        clrl    r9              # clear garbage xr value
                   14894:        jmp     cmp09           # end of image
                   14895:        #page   
                   14896: #
                   14897: #      CMPIL (CONTINUED)
                   14898: #
                   14899: #      HERE WITH IMAGE AVAILABLE TO SCAN. NOTE THAT IF THE INPUT
                   14900: #      STRING IS NULL, THEN EVERYTHING IS OK SINCE NULL IS
                   14901: #      ACTUALLY ASSEMBLED AS A WORD OF BLANKS.
                   14902: #
                   14903: cmp04: movl    r$cim,r9        # point to current image
                   14904:        movl    scnpt,r7        # load current offset
                   14905:        movl    r7,r6           # copy for label scan
                   14906:        movab   cfp$f(r9)[r7],r9# point to first character
                   14907:        movzbl  (r9)+,r8        # load first character
                   14908:        cmpl    r8,$ch$sm       # no label if semicolon
                   14909:        bnequ   0f
                   14910:        jmp     cmp12
                   14911: 0:             
                   14912:        cmpl    r8,$ch$as       # loop back if comment card
                   14913:        bnequ   0f
                   14914:        jmp     cmpce
                   14915: 0:             
                   14916:        cmpl    r8,$ch$mn       # jump if control card
                   14917:        bnequ   0f
                   14918:        jmp     cmp32
                   14919: 0:             
                   14920:        movl    r$cim,r$cmp     # about to destroy r$cim
                   14921:        movl    $cmlab,r10      # point to label work string
                   14922:        movl    r10,r$cim       # scane is to scan work string
                   14923:        movab   cfp$f(r10),r10  # point to first character position
                   14924:        movb    r8,(r10)+       # store char just loaded
                   14925:        movl    $ch$sm,r8       # get a semicolon
                   14926:        movb    r8,(r10)        # store after first char
                   14927:        #csc    r10             # finished character storing
                   14928:        clrl    r10             # clear pointer
                   14929:        clrl    scnpt           # start at first character
                   14930:        movl    scnil,-(sp)     # preserve image length
                   14931:        movl    $num02,scnil    # read 2 chars at most
                   14932:        jsb     scane           # scan first char for type
                   14933:        movl    (sp)+,scnil     # restore image length
                   14934:        movl    r10,r8          # note return code
                   14935:        movl    r$cmp,r10       # get old r$cim
                   14936:        movl    r10,r$cim       # put it back
                   14937:        movl    r7,scnpt        # reinstate offset
                   14938:        tstl    scnbl           # blank seen - cant be label
                   14939:        beqlu   0f
                   14940:        jmp     cmp12
                   14941: 0:             
                   14942:        movl    r10,r9          # point to current image
                   14943:        movab   cfp$f(r9)[r7],r9# point to first char again
                   14944:        cmpl    r8,$t$var       # ok if letter
                   14945:        beqlu   cmp06
                   14946:        cmpl    r8,$t$con       # ok if digit
                   14947:        beqlu   cmp06
                   14948: #
                   14949: #      DROP IN OR JUMP FROM ERROR SECTION IF SCANE FAILED
                   14950: #
                   14951: cmple: movl    r$cmp,r$cim     # point to bad line
                   14952:        jmp     er_214          # bad label or misplaced continuation line
                   14953: #
                   14954: #      LOOP TO SCAN LABEL
                   14955: #
                   14956: cmp05: cmpl    r8,$ch$sm       # skip if semicolon
                   14957:        beqlu   cmp07
                   14958:        incl    r6              # bump offset
                   14959:        cmpl    r6,scnil        # jump if end of image (label end)
                   14960:        beqlu   cmp07
                   14961:        #page   
                   14962: #
                   14963: #      CMPIL (CONTINUED)
                   14964: #
                   14965: #      ENTER LOOP AT THIS POINT
                   14966: #
                   14967: cmp06: movzbl  (r9)+,r8        # else load next character
                   14968:        cmpl    r8,$ch$ht       # jump if horizontal tab
                   14969:        beqlu   cmp07
                   14970:        cmpl    r8,$ch$bl       # loop back if non-blank
                   14971:        bnequ   cmp05
                   14972: #
                   14973: #      HERE AFTER SCANNING OUT LABEL
                   14974: #
                   14975: cmp07: movl    r6,scnpt        # save updated scan offset
                   14976:        subl2   r7,r6           # get length of label
                   14977:        bnequ   0f              # skip if label length zero
                   14978:        jmp     cmp12
                   14979: 0:             
                   14980:        clrl    r9              # clear garbage xr value
                   14981:        jsb     sbstr           # build scblk for label name
                   14982:        jsb     gtnvr           # locate/contruct vrblk
                   14983:        .long   invalid$        # dummy (impossible) error return
                   14984:        movl    r9,4*cmlbl(sp)  # store label pointer
                   14985:        tstl    4*vrlen(r9)     # jump if not system label
                   14986:        bnequ   cmp11
                   14987:        cmpl    4*vrsvp(r9),$v$end # jump if not end label
                   14988:        bnequ   cmp11
                   14989: #
                   14990: #      HERE FOR END LABEL SCANNED OUT
                   14991: #
                   14992:        addl2   $stgnd,stage    # adjust stage appropriately
                   14993:        jsb     scane           # scan out next element
                   14994:        cmpl    r10,$t$smc      # jump if end of image
                   14995:        bnequ   0f
                   14996:        jmp     cmp10
                   14997: 0:             
                   14998:        cmpl    r10,$t$var      # else error if not variable
                   14999:        bnequ   cmp08
                   15000: #
                   15001: #      HERE CHECK FOR VALID INITIAL TRANSFER
                   15002: #
                   15003:        cmpl    4*vrlbl(r9),$stndl # jump if not defined (error)
                   15004:        beqlu   cmp08
                   15005:        movl    4*vrlbl(r9),4*cmtra(sp) # else set initial entry pointer
                   15006:        jsb     scane           # scan next element
                   15007:        cmpl    r10,$t$smc      # jump if ok (end of image)
                   15008:        bnequ   0f
                   15009:        jmp     cmp10
                   15010: 0:             
                   15011: #
                   15012: #      HERE FOR BAD TRANSFER LABEL
                   15013: #
                   15014: cmp08: jmp     er_215          # syntax error. undefined or erroneous entry label
                   15015: #
                   15016: #      HERE FOR END OF INPUT (NO END LABEL DETECTED)
                   15017: #
                   15018: cmp09: addl2   $stgnd,stage    # adjust stage appropriately
                   15019:        cmpl    stage,$stgxe    # jump if code call (ok)
                   15020:        bnequ   0f
                   15021:        jmp     cmp10
                   15022: 0:             
                   15023:        jmp     er_216          # syntax error. missing end line
                   15024: #
                   15025: #      HERE AFTER PROCESSING END LINE (MERGE HERE ON END ERROR)
                   15026: #
                   15027: cmp10: movl    $ostp$,r6       # set stop call pointer
                   15028:        jsb     cdwrd           # generate as statement call
                   15029:        jmp     cmpse           # jump to generate as failure
                   15030:        #page   
                   15031: #
                   15032: #      CMPIL (CONTINUED)
                   15033: #
                   15034: #      HERE AFTER PROCESSING LABEL OTHER THAN END
                   15035: #
                   15036: cmp11: cmpl    stage,$stgic    # jump if code call - redef. ok
                   15037:        beqlu   0f
                   15038:        jmp     cmp12
                   15039: 0:             
                   15040:        cmpl    4*vrlbl(r9),$stndl # else check for redefinition
                   15041:        bnequ   0f
                   15042:        jmp     cmp12
                   15043: 0:             
                   15044:        clrl    4*cmlbl(sp)     # leave first label decln undisturbed
                   15045:        jmp     er_217          # syntax error. duplicate label
                   15046: #
                   15047: #      HERE AFTER DEALING WITH LABEL
                   15048: #
                   15049: cmp12: clrl    r7              # set flag for statement body
                   15050:        jsb     expan           # get tree for statement body
                   15051:        movl    r9,4*cmstm(sp)  # store for later use
                   15052:        clrl    4*cmsgo(sp)     # clear success goto pointer
                   15053:        clrl    4*cmfgo(sp)     # clear failure goto pointer
                   15054:        clrl    4*cmcgo(sp)     # clear conditional goto flag
                   15055:        jsb     scane           # scan next element
                   15056:        cmpl    r10,$t$col      # jump it not colon (no goto)
                   15057:        beqlu   0f
                   15058:        jmp     cmp18
                   15059: 0:             
                   15060: #
                   15061: #      LOOP TO PROCESS GOTO FIELDS
                   15062: #
                   15063: cmp13: movl    sp,scngo        # set goto flag
                   15064:        jsb     scane           # scan next element
                   15065:        cmpl    r10,$t$smc      # jump if no fields left
                   15066:        bnequ   0f
                   15067:        jmp     cmp31
                   15068: 0:             
                   15069:        cmpl    r10,$t$sgo      # jump if s for success goto
                   15070:        beqlu   cmp14
                   15071:        cmpl    r10,$t$fgo      # jump if f for failure goto
                   15072:        beqlu   cmp16
                   15073: #
                   15074: #      HERE FOR UNCONDITIONAL GOTO (I.E. NOT F OR S)
                   15075: #
                   15076:        movl    sp,scnrs        # set to rescan element not f,s
                   15077:        jsb     scngf           # scan out goto field
                   15078:        tstl    4*cmfgo(sp)     # error if fgoto already
                   15079:        bnequ   cmp17
                   15080:        movl    r9,4*cmfgo(sp)  # else set as fgoto
                   15081:        jmp     cmp15           # merge with sgoto circuit
                   15082: #
                   15083: #      HERE FOR SUCCESS GOTO
                   15084: #
                   15085: cmp14: jsb     scngf           # scan success goto field
                   15086:        movl    $num01,4*cmcgo(sp) # set conditional goto flag
                   15087: #
                   15088: #      UNCONTIONAL GOTO MERGES HERE
                   15089: #
                   15090: cmp15: tstl    4*cmsgo(sp)     # error if sgoto already given
                   15091:        bnequ   cmp17
                   15092:        movl    r9,4*cmsgo(sp)  # else set sgoto
                   15093:        jmp     cmp13           # loop back for next goto field
                   15094: #
                   15095: #      HERE FOR FAILURE GOTO
                   15096: #
                   15097: cmp16: jsb     scngf           # scan goto field
                   15098:        movl    $num01,4*cmcgo(sp) # set conditonal goto flag
                   15099:        tstl    4*cmfgo(sp)     # error if fgoto already given
                   15100:        bnequ   cmp17
                   15101:        movl    r9,4*cmfgo(sp)  # else store fgoto pointer
                   15102:        jmp     cmp13           # loop back for next field
                   15103:        #page   
                   15104: #
                   15105: #      CMPIL (CONTINUED)
                   15106: #
                   15107: #      HERE FOR DUPLICATED GOTO FIELD
                   15108: #
                   15109: cmp17: jmp     er_218          # syntax error. duplicated goto field
                   15110: #
                   15111: #      HERE TO GENERATE CODE
                   15112: #
                   15113: cmp18: clrl    scnse           # stop positional error flags
                   15114:        movl    4*cmstm(sp),r9  # load tree ptr for statement body
                   15115:        clrl    r7              # collectable value for wb for cdgvl
                   15116:        clrl    r8              # reset constant flag for cdgvl
                   15117:        jsb     expap           # test for pattern match
                   15118:        .long   cmp19           # jump if not pattern match
                   15119:        movl    $opms$,4*cmopn(r9) # else set pattern match pointer
                   15120:        movl    $c$pmt,4*cmtyp(r9)
                   15121: #
                   15122: #      HERE AFTER DEALING WITH SPECIAL PATTERN MATCH CASE
                   15123: #
                   15124: cmp19: jsb     cdgvl           # generate code for body of statement
                   15125:        movl    4*cmsgo(sp),r9  # load sgoto pointer
                   15126:        movl    r9,r6           # copy it
                   15127:        tstl    r9              # jump if no success goto
                   15128:        beqlu   cmp21
                   15129:        clrl    4*cmsoc(sp)     # clear success offset fillin ptr
                   15130:        cmpl    r9,state        # jump if complex goto
                   15131:        bgequ   cmp20
                   15132: #
                   15133: #      HERE FOR SIMPLE SUCCESS GOTO (LABEL)
                   15134: #
                   15135:        addl2   $4*vrtra,r6     # point to vrtra field as required
                   15136:        jsb     cdwrd           # generate success goto
                   15137:        jmp     cmp22           # jump to deal with fgoto
                   15138: #
                   15139: #      HERE FOR COMPLEX SUCCESS GOTO
                   15140: #
                   15141: cmp20: cmpl    r9,4*cmfgo(sp)  # no code if same as fgoto
                   15142:        beqlu   cmp22
                   15143:        clrl    r7              # else set ok value for cdgvl in wb
                   15144:        jsb     cdgcg           # generate code for success goto
                   15145:        jmp     cmp22           # jump to deal with fgoto
                   15146: #
                   15147: #      HERE FOR NO SUCCESS GOTO
                   15148: #
                   15149: cmp21: movl    cwcof,4*cmsoc(sp)# set success fill in offset
                   15150:        movl    $ocer$,r6       # point to compile error call
                   15151:        jsb     cdwrd           # generate as temporary value
                   15152:        #page   
                   15153: #
                   15154: #      CMPIL (CONTINUED)
                   15155: #
                   15156: #      HERE TO DEAL WITH FAILURE GOTO
                   15157: #
                   15158: cmp22: movl    4*cmfgo(sp),r9  # load failure goto pointer
                   15159:        movl    r9,r6           # copy it
                   15160:        clrl    4*cmffc(sp)     # set no fill in required yet
                   15161:        tstl    r9              # jump if no failure goto given
                   15162:        beqlu   cmp23
                   15163:        addl2   $4*vrtra,r6     # point to vrtra field in case
                   15164:        cmpl    r9,state        # jump to gen if simple fgoto
                   15165:        blequ   cmpse
                   15166: #
                   15167: #      HERE FOR COMPLEX FAILURE GOTO
                   15168: #
                   15169:        movl    cwcof,r7        # save offset to o$gof call
                   15170:        movl    $ogof$,r6       # point to failure goto call
                   15171:        jsb     cdwrd           # generate
                   15172:        movl    $ofif$,r6       # point to fail in fail word
                   15173:        jsb     cdwrd           # generate
                   15174:        jsb     cdgcg           # generate code for failure goto
                   15175:        movl    r7,r6           # copy offset to o$gof for cdfal
                   15176:        movl    $b$cdc,r7       # set complex case cdtyp
                   15177:        jmp     cmp25           # jump to build cdblk
                   15178: #
                   15179: #      HERE IF NO FAILURE GOTO GIVEN
                   15180: #
                   15181: cmp23: movl    $ounf$,r6       # load unexpected failure call in cas
                   15182:        movl    cswfl,r8        # get -nofail flag
                   15183:        bisl2   4*cmcgo(sp),r8  # check if conditional goto
                   15184:        beqlu   cmpse           # jump if -nofail and no cond. goto
                   15185:        movl    sp,4*cmffc(sp)  # else set fill in flag
                   15186:        movl    $ocer$,r6       # and set compile error for temporary
                   15187: #
                   15188: #      MERGE HERE WITH CDFAL VALUE IN WA, SIMPLE CDBLK
                   15189: #      ALSO SPECIAL ENTRY AFTER STATEMENT ERROR
                   15190: #
                   15191: cmpse: movl    $b$cds,r7       # set cdtyp for simple case
                   15192:        #page   
                   15193: #
                   15194: #      CMPIL (CONTINUED)
                   15195: #
                   15196: #      MERGE HERE TO BUILD CDBLK
                   15197: #
                   15198: #      (WA)                  CDFAL VALUE TO BE GENERATED
                   15199: #      (WB)                  CDTYP VALUE TO BE GENERATED
                   15200: #
                   15201: #      AT THIS STAGE, WE CHOP OFF AN APPROPRIATE CHUNK OF THE
                   15202: #      CURRENT CCBLK AND CONVERT IT INTO A CDBLK. THE REMAINDER
                   15203: #      OF THE CCBLK IS REFORMATTED TO BE THE NEW CCBLK.
                   15204: #
                   15205: cmp25: movl    r$ccb,r9        # point to ccblk
                   15206:        movl    4*cmlbl(sp),r10 # get possible label pointer
                   15207:        beqlu   cmp26           # skip if no label
                   15208:        clrl    4*cmlbl(sp)     # clear flag for next statement
                   15209:        movl    r9,4*vrlbl(r10) # put cdblk ptr in vrblk label field
                   15210: #
                   15211: #      MERGE AFTER DOING LABEL
                   15212: #
                   15213: cmp26: movl    r7,(r9)         # set type word for new cdblk
                   15214:        movl    r6,4*cdfal(r9)  # set failure word
                   15215:        movl    r9,r10          # copy pointer to ccblk
                   15216:        movl    4*ccuse(r9),r7  # load length gen (= new cdlen)
                   15217:        movl    4*cclen(r9),r8  # load total ccblk length
                   15218:        addl2   r7,r10          # point past cdblk
                   15219:        subl2   r7,r8           # get length left for chop off
                   15220:        movl    $b$cct,(r10)    # set type code for new ccblk at end
                   15221:        movl    $4*cccod,4*ccuse(r10) # set initial code offset
                   15222:        movl    $4*cccod,cwcof  # reinitialise cwcof
                   15223:        movl    r8,4*cclen(r10) # set new length
                   15224:        movl    r10,r$ccb       # set new ccblk pointer
                   15225:        movl    cmpsn,4*cdstm(r9)# set statement number
                   15226:        incl    cmpsn           # bump statement number
                   15227: #
                   15228: #      SET POINTERS IN PREVIOUS CODE BLOCK AS REQUIRED
                   15229: #
                   15230:        movl    4*cmpcd(sp),r10 # load ptr to previous cdblk
                   15231:        tstl    4*cmffp(sp)     # jump if no failure fill in required
                   15232:        beqlu   cmp27
                   15233:        movl    r9,4*cdfal(r10) # else set failure ptr in previous
                   15234: #
                   15235: #      HERE TO DEAL WITH SUCCESS FORWARD POINTER
                   15236: #
                   15237: cmp27: movl    4*cmsop(sp),r6  # load success offset
                   15238:        beqlu   cmp28           # jump if no fill in required
                   15239:        addl2   r6,r10          # else point to fill in location
                   15240:        movl    r9,(r10)        # store forward pointer
                   15241:        clrl    r10             # clear garbage xl value
                   15242:        #page   
                   15243: #
                   15244: #      CMPIL (CONTINUED)
                   15245: #
                   15246: #      NOW SET FILL IN POINTERS FOR THIS STATEMENT
                   15247: #
                   15248: cmp28: movl    4*cmffc(sp),4*cmffp(sp) # copy failure fill in flag
                   15249:        movl    4*cmsoc(sp),4*cmsop(sp) # copy success fill in offset
                   15250:        movl    r9,4*cmpcd(sp)  # save ptr to this cdblk
                   15251:        tstl    4*cmtra(sp)     # jump if initial entry already set
                   15252:        bnequ   cmp29
                   15253:        movl    r9,4*cmtra(sp)  # else set ptr here as default
                   15254: #
                   15255: #      HERE AFTER COMPILING ONE STATEMENT
                   15256: #
                   15257: cmp29: cmpl    stage,$stgce    # jump if not end line just done
                   15258:        bgequ   0f
                   15259:        jmp     cmp01
                   15260: 0:             
                   15261:        tstl    cswls           # skip if -nolist
                   15262:        beqlu   cmp30
                   15263:        jsb     listr           # list last line
                   15264: #
                   15265: #      RETURN
                   15266: #
                   15267: cmp30: movl    4*cmtra(sp),r9  # load initial entry cdblk pointer
                   15268:        addl2   $4*cmnen,sp     # pop work locations off stack
                   15269:        rsb                     # and return to cmpil caller
                   15270: #
                   15271: #      HERE AT END OF GOTO FIELD
                   15272: #
                   15273: cmp31: movl    4*cmfgo(sp),r7  # get fail goto
                   15274:        bisl2   4*cmsgo(sp),r7  # or in success goto
                   15275:        beqlu   0f              # ok if non-null field
                   15276:        jmp     cmp18
                   15277: 0:             
                   15278:        jmp     er_219          # syntax error. empty goto field
                   15279: #
                   15280: #      CONTROL CARD FOUND
                   15281: #
                   15282: cmp32: incl    r7              # point past ch$mn
                   15283:        jsb     cncrd           # process control card
                   15284:        clrl    scnse           # clear start of element loc.
                   15285:        jmp     cmpce           # loop for next statement
                   15286:        #enp                    # end procedure cmpil
                   15287:        #page   
                   15288: #
                   15289: #      CNCRD -- CONTROL CARD PROCESSOR
                   15290: #
                   15291: #      CALLED TO DEAL WITH CONTROL CARDS
                   15292: #
                   15293: #      R$CIM                 POINTS TO CURRENT IMAGE
                   15294: #      (WB)                  OFFSET TO 1ST CHAR OF CONTROL CARD
                   15295: #      JSR  CNCRD            CALL TO PROCESS CONTROL CARDS
                   15296: #      (XL,XR,WA,WB,WC,IA)   DESTROYED
                   15297: #
                   15298: cncrd: #prc                    # entry point
                   15299:        movl    r7,scnpt        # offset for control card scan
                   15300:        movl    $ccnoc,r6       # number of chars for comparison
                   15301:        movab   3+(4*0)(r6),r6  # convert to word count
                   15302:        ashl    $-2,r6,r6
                   15303:        movl    r6,cnswc        # save word count
                   15304: #
                   15305: #      LOOP HERE IF MORE THAN ONE CONTROL CARD
                   15306: #
                   15307: cnc01: cmpl    scnpt,scnil     # return if end of image
                   15308:        blssu   0f
                   15309:        jmp     cnc09
                   15310: 0:             
                   15311:        movl    r$cim,r9        # point to image
                   15312:        movl    scnpt,r11       # [get in scratch register]
                   15313:        movab   cfp$f(r9)[r11],r9# char ptr for first char
                   15314:        movzbl  (r9)+,r6        # get first char
                   15315:        bicl2   $ch$bl,r6       # fold to upper case
                   15316:        cmpl    r6,$ch$li       # special case of -inxxx
                   15317:        bnequ   0f
                   15318:        jmp     cnc07
                   15319: 0:             
                   15320:        movl    sp,scncc        # set flag for scane
                   15321:        jsb     scane           # scan card name
                   15322:        clrl    scncc           # clear scane flag
                   15323:        tstl    r10             # fail unless control card name
                   15324:        beqlu   0f
                   15325:        jmp     cnc06
                   15326: 0:             
                   15327:        movl    $ccnoc,r6       # no. of chars to be compared
                   15328:        cmpl    4*sclen(r9),r6  # fail if too few chars
                   15329:        bgequ   0f
                   15330:        jmp     cnc06
                   15331: 0:             
                   15332:        movl    r9,r10          # point to control card name
                   15333:        clrl    r7              # zero offset for substring
                   15334:        jsb     sbstr           # extract substring for comparison
                   15335:        movl    4*sclen(r9),r6  # reload length
                   15336:        jsb     flstg           # fold to upper case
                   15337:        movl    r9,cnscc        # keep control card substring ptr
                   15338:        movl    $ccnms,r9       # point to list of standard names
                   15339:        clrl    r7              # initialise name offset
                   15340:        movl    $cc$nc,r8       # number of standard names
                   15341: #
                   15342: #      TRY TO MATCH NAME
                   15343: #
                   15344: cnc02: movl    cnscc,r10       # point to name
                   15345:        movl    cnswc,r6        # counter for inner loop
                   15346:        jmp     cnc04           # jump into loop
                   15347: #
                   15348: #      INNER LOOP TO MATCH CARD NAME CHARS
                   15349: #
                   15350: cnc03: addl2   $4,r9           # bump standard names ptr
                   15351:        addl2   $4,r10          # bump name pointer
                   15352: #
                   15353: #      HERE TO INITIATE THE LOOP
                   15354: #
                   15355: cnc04: cmpl    4*schar(r10),(r9)# comp. up to cfp$c chars at once
                   15356:        bnequ   cnc05
                   15357:        sobgtr  r6,cnc03        # loop if more words to compare
                   15358:        #page   
                   15359: #
                   15360: #      CNCRD (CONTINUED)
                   15361: #
                   15362: #      MATCHED - BRANCH ON CARD OFFSET
                   15363: #
                   15364:        movl    r7,r10          # get name offset
                   15365:        casel   r10,$0,$cc$nc   # switch
                   15366: 5:             
                   15367:        .word   cnc37-5b        # -case
                   15368:        .word   cnc10-5b        # -double
                   15369:        .word   cnc11-5b        # -dump
                   15370:        .word   cnc12-5b        # -eject
                   15371:        .word   cnc13-5b        # -errors
                   15372:        .word   cnc14-5b        # -execute
                   15373:        .word   cnc15-5b        # -fail
                   15374:        .word   cnc16-5b        # -list
                   15375:        .word   cnc17-5b        # -noerrors
                   15376:        .word   cnc18-5b        # -noexecute
                   15377:        .word   cnc19-5b        # -nofail
                   15378:        .word   cnc20-5b        # -nolist
                   15379:        .word   cnc21-5b        # -noopt
                   15380:        .word   cnc22-5b        # -noprint
                   15381:        .word   cnc24-5b        # -optimise
                   15382:        .word   cnc25-5b        # -print
                   15383:        .word   cnc27-5b        # -single
                   15384:        .word   cnc28-5b        # -space
                   15385:        .word   cnc31-5b        # -stitle
                   15386:        .word   cnc32-5b        # -title
                   15387:        .word   cnc36-5b        # -trace
                   15388:        #esw                    # end switch
                   15389: #
                   15390: #      NOT MATCHED YET. ALIGN STD NAMES PTR AND TRY AGAIN
                   15391: #
                   15392: cnc05: addl2   $4,r9           # bump standard names ptr
                   15393:        sobgtr  r6,cnc05        # loop
                   15394:        incl    r7              # bump names offset
                   15395:        sobgtr  r8,cnc02        # continue if more names
                   15396: #
                   15397: #      INVALID CONTROL CARD NAME
                   15398: #
                   15399: cnc06: jmp     er_247          # invalid control card
                   15400: #
                   15401: #      SPECIAL PROCESSING FOR -INXXX
                   15402: #
                   15403: cnc07: movzbl  (r9),r6         # get next char
                   15404:        bicl2   $ch$bl,r6       # fold to upper case
                   15405:        cmpl    r6,$ch$ln       # fail if not letter n
                   15406:        beqlu   0f
                   15407:        jmp     cnc06
                   15408: 0:             
                   15409:        addl2   $num02,scnpt    # bump offset past -in
                   15410:        jsb     scane           # scan integer after -in
                   15411:        movl    r9,-(sp)        # stack scanned item
                   15412:        jsb     gtsmi           # check if integer
                   15413:        .long   cnc06           # fail if not integer
                   15414:        .long   cnc06           # fail if negative or large
                   15415:        movl    r9,cswin        # keep integer
                   15416:        #page   
                   15417: #
                   15418: #      CNCRD (CONTINUED)
                   15419: #
                   15420: #      CHECK FOR MORE CONTROL CARDS BEFORE RETURNING
                   15421: #
                   15422: cnc08: movl    scnpt,r6        # preserve in case xeq time compile
                   15423:        jsb     scane           # look for comma
                   15424:        cmpl    r10,$t$cma      # loop if comma found
                   15425:        bnequ   0f
                   15426:        jmp     cnc01
                   15427: 0:             
                   15428:        movl    r6,scnpt        # restore scnpt in case xeq time
                   15429: #
                   15430: #      RETURN POINT
                   15431: #
                   15432: cnc09: rsb                     # return
                   15433: #
                   15434: #      -DOUBLE
                   15435: #
                   15436: cnc10: movl    sp,cswdb        # set switch
                   15437:        jmp     cnc08           # merge
                   15438: #
                   15439: #      -DUMP
                   15440: #      THIS IS USED FOR SYSTEM DEBUGGING . IT HAS THE EFFECT OF
                   15441: #      PRODUCING A CORE DUMP AT COMPILATION TIME
                   15442: #
                   15443: cnc11: jsb     sysdm           # call dumper
                   15444:        jmp     cnc09           # finished
                   15445: #
                   15446: #      -EJECT
                   15447: #
                   15448: cnc12: tstl    cswls           # return if -nolist
                   15449:        bnequ   0f
                   15450:        jmp     cnc09
                   15451: 0:             
                   15452:        jsb     prtps           # eject
                   15453:        jsb     listt           # list title
                   15454:        jmp     cnc09           # finished
                   15455: #
                   15456: #      -ERRORS
                   15457: #
                   15458: cnc13: clrl    cswer           # clear switch
                   15459:        jmp     cnc08           # merge
                   15460: #
                   15461: #      -EXECUTE
                   15462: #
                   15463: cnc14: clrl    cswex           # clear switch
                   15464:        jmp     cnc08           # merge
                   15465: #
                   15466: #      -FAIL
                   15467: #
                   15468: cnc15: movl    sp,cswfl        # set switch
                   15469:        jmp     cnc08           # merge
                   15470: #
                   15471: #      -LIST
                   15472: #
                   15473: cnc16: movl    sp,cswls        # set switch
                   15474:        cmpl    stage,$stgic    # done if compile time
                   15475:        beqlu   cnc08
                   15476: #
                   15477: #      LIST CODE LINE IF EXECUTE TIME COMPILE
                   15478: #
                   15479:        clrl    lstpf           # permit listing
                   15480:        jsb     listr           # list line
                   15481:        jmp     cnc08           # merge
                   15482:        #page   
                   15483: #
                   15484: #      CNCRD (CONTINUED)
                   15485: #
                   15486: #      -NOERRORS
                   15487: #
                   15488: cnc17: movl    sp,cswer        # set switch
                   15489:        jmp     cnc08           # merge
                   15490: #
                   15491: #      -NOEXECUTE
                   15492: #
                   15493: cnc18: movl    sp,cswex        # set switch
                   15494:        jmp     cnc08           # merge
                   15495: #
                   15496: #      -NOFAIL
                   15497: #
                   15498: cnc19: clrl    cswfl           # clear switch
                   15499:        jmp     cnc08           # merge
                   15500: #
                   15501: #      -NOLIST
                   15502: #
                   15503: cnc20: clrl    cswls           # clear switch
                   15504:        jmp     cnc08           # merge
                   15505: #
                   15506: #      -NOOPTIMISE
                   15507: #
                   15508: cnc21: movl    sp,cswno        # set switch
                   15509:        jmp     cnc08           # merge
                   15510: #
                   15511: #      -NOPRINT
                   15512: #
                   15513: cnc22: clrl    cswpr           # clear switch
                   15514:        jmp     cnc08           # merge
                   15515: #
                   15516: #      -OPTIMISE
                   15517: #
                   15518: cnc24: clrl    cswno           # clear switch
                   15519:        jmp     cnc08           # merge
                   15520: #
                   15521: #      -PRINT
                   15522: #
                   15523: cnc25: movl    sp,cswpr        # set switch
                   15524:        jmp     cnc08           # merge
                   15525:        #page   
                   15526: #
                   15527: #      CNCRD (CONTINUED)
                   15528: #
                   15529: #      -SINGLE
                   15530: #
                   15531: cnc27: clrl    cswdb           # clear switch
                   15532:        jmp     cnc08           # merge
                   15533: #
                   15534: #      -SPACE
                   15535: #
                   15536: cnc28: tstl    cswls           # return if -nolist
                   15537:        bnequ   0f
                   15538:        jmp     cnc09
                   15539: 0:             
                   15540:        jsb     scane           # scan integer after -space
                   15541:        movl    $num01,r8       # 1 space in case
                   15542:        cmpl    r9,$t$smc       # jump if no integer
                   15543:        beqlu   cnc29
                   15544:        movl    r9,-(sp)        # stack it
                   15545:        jsb     gtsmi           # check integer
                   15546:        .long   cnc06           # fail if not integer
                   15547:        .long   cnc06           # fail if negative or large
                   15548:        tstl    r8              # jump if non zero
                   15549:        bnequ   cnc29
                   15550:        movl    $num01,r8       # else 1 space
                   15551: #
                   15552: #      MERGE WITH COUNT OF LINES TO SKIP
                   15553: #
                   15554: cnc29: addl2   r8,lstlc        # bump line count
                   15555:                                # convert to loop counter
                   15556:        cmpl    lstlc,lstnp     # jump if fits on page
                   15557:        blssu   cnc30
                   15558:        jsb     prtps           # eject
                   15559:        jsb     listt           # list title
                   15560:        jmp     cnc09           # merge
                   15561: #
                   15562: #      SKIP LINES
                   15563: #
                   15564: cnc30: jsb     prtnl           # print a blank
                   15565:        sobgtr  r8,cnc30        # loop
                   15566:        jmp     cnc09           # merge
                   15567:        #page   
                   15568: #
                   15569: #      CNCRD (CONTINUED)
                   15570: #
                   15571: #      -STITL
                   15572: #
                   15573: cnc31: movl    $r$stl,cnr$t    # ptr to r$stl
                   15574:        jmp     cnc33           # merge
                   15575: #
                   15576: #      -TITLE
                   15577: #
                   15578: cnc32: movl    $nulls,r$stl    # clear subtitle
                   15579:        movl    $r$ttl,cnr$t    # ptr to r$ttl
                   15580: #
                   15581: #      COMMON PROCESSING FOR -TITLE, -STITL
                   15582: #
                   15583: cnc33: movl    $nulls,r9       # null in case needed
                   15584:        movl    sp,cnttl        # set flag for next listr call
                   15585:        movl    $ccofs,r7       # offset to title/subtitle
                   15586:        movl    scnil,r6        # input image length
                   15587:        cmpl    r6,r7           # jump if no chars left
                   15588:        blequ   cnc34
                   15589:        subl2   r7,r6           # no of chars to extract
                   15590:        movl    r$cim,r10       # point to image
                   15591:        jsb     sbstr           # get title/subtitle
                   15592: #
                   15593: #      STORE TITLE/SUBTITLE
                   15594: #
                   15595: cnc34: movl    cnr$t,r10       # point to storage location
                   15596:        movl    r9,(r10)        # store title/subtitle
                   15597:        cmpl    r10,$r$stl      # return if stitl
                   15598:        bnequ   0f
                   15599:        jmp     cnc09
                   15600: 0:             
                   15601:        tstl    precl           # return if extended listing
                   15602:        beqlu   0f
                   15603:        jmp     cnc09
                   15604: 0:             
                   15605:        tstl    prich           # return if regular printer
                   15606:        bnequ   0f
                   15607:        jmp     cnc09
                   15608: 0:             
                   15609:        movl    4*sclen(r9),r10 # get length of title
                   15610:        movl    r10,r6          # copy it
                   15611:        tstl    r10             # jump if null
                   15612:        beqlu   cnc35
                   15613:        addl2   $num10,r10      # increment
                   15614:        cmpl    r10,prlen       # use default lstp0 val if too long
                   15615:        blssu   0f
                   15616:        jmp     cnc09
                   15617: 0:             
                   15618:        addl2   $num04,r6       # point just past title
                   15619: #
                   15620: #      STORE OFFSET TO PAGE NN MESSAGE FOR SHORT TITLE
                   15621: #
                   15622: cnc35: movl    r6,lstpo        # store offset
                   15623:        jmp     cnc09           # return
                   15624: #
                   15625: #      -TRACE
                   15626: #      PROVIDED FOR SYSTEM DEBUGGING.  TOGGLES THE SYSTEM LABEL
                   15627: #      TRACE SWITCH AT COMPILE TIME
                   15628: #
                   15629: cnc36: jsb     systt           # toggle switch
                   15630:        jmp     cnc08           # merge
                   15631: #
                   15632: #      -CASE
                   15633: #      SETS VALUE OF KVCAS SO THAT NAMES ARE FOLDED OR NOT
                   15634: #      DURING COMPILATION.
                   15635: #
                   15636: cnc37: jsb     scane           # scan integer after -case
                   15637:        clrl    r8              # get 0 in case none there
                   15638:        cmpl    r10,$t$smc      # skip if no integer
                   15639:        beqlu   cnc38
                   15640:        movl    r9,-(sp)        # stack it
                   15641:        jsb     gtsmi           # check integer
                   15642:        .long   cnc06           # fail if not integer
                   15643:        .long   cnc06           # fail if negative or too large
                   15644: cnc38: movl    r8,kvcas        # store new case value
                   15645:        jmp     cnc09           # merge
                   15646:        #enp                    # end procedure cncrd
                   15647:        #page   
                   15648: #
                   15649: #      DFFNC -- DEFINE FUNCTION
                   15650: #
                   15651: #      DFFNC IS CALLED WHENEVER A NEW FUNCTION IS ASSIGNED TO
                   15652: #      A VARIABLE. IT DEALS WITH EXTERNAL FUNCTION USE COUNTS.
                   15653: #
                   15654: #      (XR)                  POINTER TO VRBLK
                   15655: #      (XL)                  POINTER TO NEW FUNCTION BLOCK
                   15656: #      JSR  DFFNC            CALL TO DEFINE FUNCTION
                   15657: #      (WA,WB)               DESTROYED
                   15658: #
                   15659: dffnc: #prc                    # entry point
                   15660:        cmpl    (r10),$b$efc    # skip if new function not external
                   15661:        bnequ   dffn1
                   15662:        incl    4*efuse(r10)    # else increment its use count
                   15663: #
                   15664: #      HERE AFTER DEALING WITH NEW FUNCTION USE COUNT
                   15665: #
                   15666: dffn1: movl    r9,r6           # save vrblk pointer
                   15667:        movl    4*vrfnc(r9),r9  # load old function pointer
                   15668:        cmpl    (r9),$b$efc     # jump if old function not external
                   15669:        bnequ   dffn2
                   15670:        movl    4*efuse(r9),r7  # else get use count
                   15671:        decl    r7              # decrement
                   15672:        movl    r7,4*efuse(r9)  # store decremented value
                   15673:        tstl    r7              # jump if use count still non-zero
                   15674:        bnequ   dffn2
                   15675:        jsb     sysul           # else call system unload function
                   15676: #
                   15677: #      HERE AFTER DEALING WITH OLD FUNCTION USE COUNT
                   15678: #
                   15679: dffn2: movl    r6,r9           # restore vrblk pointer
                   15680:        movl    r10,r6          # copy function block ptr
                   15681:        cmpl    r9,$r$yyy       # skip checks if opsyn op definition
                   15682:        blssu   dffn3
                   15683:        tstl    4*vrlen(r9)     # jump if not system variable
                   15684:        bnequ   dffn3
                   15685: #
                   15686: #      FOR SYSTEM VARIABLE, CHECK FOR ILLEGAL REDEFINITION
                   15687: #
                   15688:        movl    4*vrsvp(r9),r10 # point to svblk
                   15689:        movl    4*svbit(r10),r7 # load bit indicators
                   15690:        mcoml   btfnc,r11       # is it a system function
                   15691:        bicl2   r11,r7
                   15692:        beqlu   dffn3           # redef ok if not
                   15693:        jmp     er_248          # attempted redefinition of system function
                   15694: #
                   15695: #      HERE IF REDEFINITION IS PERMITTED
                   15696: #
                   15697: dffn3: movl    r6,4*vrfnc(r9)  # store new function pointer
                   15698:        movl    r6,r10          # restore function block pointer
                   15699:        rsb                     # return to dffnc caller
                   15700:        #enp                    # end procedure dffnc
                   15701:        #page   
                   15702: #
                   15703: #      DTACH -- DETACH I/O ASSOCIATED NAMES
                   15704: #
                   15705: #      DETACHES TRBLKS FROM I/O ASSOCIATED VARIABLES, REMOVES
                   15706: #      ENTRY FROM IOCHN CHAIN ATTACHED TO FILEARG1 VRBLK AND MAY
                   15707: #      REMOVE VRBLK ACCESS AND STORE TRAPS.
                   15708: #      INPUT, OUTPUT, TERMINAL ARE HANDLED SPECIALLY.
                   15709: #
                   15710: #      (XL)                  I/O ASSOC. VBL NAME BASE PTR
                   15711: #      (WA)                  OFFSET TO NAME
                   15712: #      JSR  DTACH            CALL FOR DETACH OPERATION
                   15713: #      (XL,XR,WA,WB,WC)      DESTROYED
                   15714: #
                   15715: dtach: #prc                    # entry point
                   15716:        movl    r10,dtcnb       # store name base (gbcol not called)
                   15717:        addl2   r6,r10          # point to name location
                   15718:        movl    r10,dtcnm       # store it
                   15719: #
                   15720: #      LOOP TO SEARCH FOR I/O TRBLK
                   15721: #
                   15722: dtch1: movl    r10,r9          # copy name pointer
                   15723: #
                   15724: #      CONTINUE AFTER BLOCK DELETION
                   15725: #
                   15726: dtch2: movl    (r10),r10       # point to next value
                   15727:        cmpl    (r10),$b$trt    # jump at chain end
                   15728:        bnequ   dtch6
                   15729:        movl    4*trtyp(r10),r6 # get trap block type
                   15730:        cmpl    r6,$trtin       # jump if input
                   15731:        beqlu   dtch3
                   15732:        cmpl    r6,$trtou       # jump if output
                   15733:        beqlu   dtch3
                   15734:        addl2   $4*trnxt,r10    # point to next link
                   15735:        jmp     dtch1           # loop
                   15736: #
                   15737: #      DELETE AN OLD ASSOCIATION
                   15738: #
                   15739: dtch3: movl    4*trval(r10),(r9)# delete trblk
                   15740:        movl    r10,r6          # dump xl ...
                   15741:        movl    r9,r7           # ... and xr
                   15742:        movl    4*trtrf(r10),r10# point to trtrf trap block
                   15743:        beqlu   dtch5           # jump if no iochn
                   15744:        cmpl    (r10),$b$trt    # jump if input, output, terminal
                   15745:        bnequ   dtch5
                   15746: #
                   15747: #      LOOP TO SEARCH IOCHN CHAIN FOR NAME PTR
                   15748: #
                   15749: dtch4: movl    r10,r9          # remember link ptr
                   15750:        movl    4*trtrf(r10),r10# point to next link
                   15751:        beqlu   dtch5           # jump if end of chain
                   15752:        movl    4*ionmb(r10),r8 # get name base
                   15753:        addl2   4*ionmo(r10),r8 # add offset
                   15754:        cmpl    r8,dtcnm        # loop if no match
                   15755:        bnequ   dtch4
                   15756:        movl    4*trtrf(r10),4*trtrf(r9) # remove name from chain
                   15757:        #page   
                   15758: #
                   15759: #      DTACH (CONTINUED)
                   15760: #
                   15761: #      PREPARE TO RESUME I/O TRBLK SCAN
                   15762: #
                   15763: dtch5: movl    r6,r10          # recover xl ...
                   15764:        movl    r7,r9           # ... and xr
                   15765:        addl2   $4*trval,r10    # point to value field
                   15766:        jmp     dtch2           # continue
                   15767: #
                   15768: #      EXIT POINT
                   15769: #
                   15770: dtch6: movl    dtcnb,r9        # possible vrblk ptr
                   15771:        jsb     setvr           # reset vrblk if necessary
                   15772:        rsb                     # return
                   15773:        #enp                    # end procedure dtach
                   15774:        #page   
                   15775: #
                   15776: #      DTYPE -- GET DATATYPE NAME
                   15777: #
                   15778: #      (XR)                  OBJECT WHOSE DATATYPE IS REQUIRED
                   15779: #      JSR  DTYPE            CALL TO GET DATATYPE
                   15780: #      (XR)                  RESULT DATATYPE
                   15781: #
                   15782: dtype: #prc                    # entry point
                   15783:        cmpl    (r9),$b$pdt     # jump if prog.defined
                   15784:        beqlu   dtyp1
                   15785:        movl    (r9),r9         # load type word
                   15786:        movzwl  -2(r9),r9       # get entry point id (block code)
                   15787:        moval   0[r9],r9        # convert to byte offset
                   15788:        movl    l^scnmt(r9),r9  # load table entry
                   15789:        rsb                     # exit to dtype caller
                   15790: #
                   15791: #      HERE IF PROGRAM DEFINED
                   15792: #
                   15793: dtyp1: movl    4*pddfp(r9),r9  # point to dfblk
                   15794:        movl    4*dfnam(r9),r9  # get datatype name from dfblk
                   15795:        rsb                     # return to dtype caller
                   15796:        #enp                    # end procedure dtype
                   15797:        #page   
                   15798: #
                   15799: #      DUMPR -- PRINT DUMP OF STORAGE
                   15800: #
                   15801: #      (XR)                  DUMP ARGUMENT (SEE BELOW)
                   15802: #      JSR  DUMPR            CALL TO PRINT DUMP
                   15803: #      (XR,XL)               DESTROYED
                   15804: #      (WA,WB,WC,RA)         DESTROYED
                   15805: #
                   15806: #      THE DUMP ARGUMENT HAS THE FOLLOWING SIGNIFICANCE
                   15807: #
                   15808: #      DMARG = 0             NO DUMP PRINTED
                   15809: #      DMARG = 1             PARTIAL DUMP (NAT VARS, KEYWORDS)
                   15810: #      DMARG EQ 2            FULL DUMP (INCL ARRAYS ETC.)
                   15811: #      DMARG GE 3            CORE DUMP
                   15812: #
                   15813: #      SINCE DUMPR SCRAMBLES STORE, IT IS NOT PERMISSIBLE TO
                   15814: #      COLLECT IN MID-DUMP. HENCE A COLLECT IS DONE INITIALLY
                   15815: #      AND THEN IF STORE RUNS OUT AN ERROR MESSAGE IS PRODUCED.
                   15816: #
                   15817: dumpr: #prc                    # entry point
                   15818:        tstl    r9              # skip dump if argument is zero
                   15819:        bnequ   0f
                   15820:        jmp     dmp28
                   15821: 0:             
                   15822:        cmpl    r9,$num02       # jump if core dump required
                   15823:        blequ   0f
                   15824:        jmp     dmp29
                   15825: 0:             
                   15826:        clrl    r10             # clear xl
                   15827:        clrl    r7              # zero move offset
                   15828:        movl    r9,dmarg        # save dump argument
                   15829:        jsb     gbcol           # collect garbage
                   15830:        jsb     prtpg           # eject printer
                   15831:        movl    $dmhdv,r9       # point to heading for variables
                   15832:        jsb     prtst           # print it
                   15833:        jsb     prtnl           # terminate print line
                   15834:        jsb     prtnl           # and print a blank line
                   15835: #
                   15836: #      FIRST ALL NATURAL VARIABLE BLOCKS (VRBLK) WHOSE VALUES
                   15837: #      ARE NON-NULL ARE LINKED IN LEXICAL ORDER USING DMVCH AS
                   15838: #      THE CHAIN HEAD AND CHAINING THROUGH THE VRGET FIELDS.
                   15839: #      NOTE THAT THIS SCRAMBLES STORE IF THE PROCESS IS
                   15840: #      INTERRUPTED BEFORE COMPLETION E.G. BY EXCEEDING TIME  OR
                   15841: #      PRINT LIMITS. SINCE THE SUBSEQUENT CORE DUMPS AND
                   15842: #      FAILURES IF EXECUTION IS RESUMED ARE VERY CONFUSING, THE
                   15843: #      EXECUTION TIME ERROR ROUTINE CHECKS FOR THIS EVENT AND
                   15844: #      ATTEMPTS AN UNSCRAMBLE. SIMILAR PRECAUTIONS SHOULD BE
                   15845: #      OBSERVED IF TRANSLATE TIME DUMPING IS IMPLEMENTED.
                   15846: #
                   15847:        clrl    dmvch           # set null chain to start
                   15848:        movl    hshtb,r6        # point to hash table
                   15849: #
                   15850: #      LOOP THROUGH HEADERS IN HASH TABLE
                   15851: #
                   15852: dmp00: movl    r6,r9           # copy hash bucket pointer
                   15853:        addl2   $4,r6           # bump pointer
                   15854:        subl2   $4*vrnxt,r9     # set offset to merge
                   15855: #
                   15856: #      LOOP THROUGH VRBLKS ON ONE CHAIN
                   15857: #
                   15858: dmp01: movl    4*vrnxt(r9),r9  # point to next vrblk on chain
                   15859:        bnequ   0f              # jump if end of this hash chain
                   15860:        jmp     dmp09
                   15861: 0:             
                   15862:        movl    r9,r10          # else copy vrblk pointer
                   15863:        #page   
                   15864: #
                   15865: #      DUMPR (CONTINUED)
                   15866: #
                   15867: #      LOOP TO FIND VALUE AND SKIP IF NULL
                   15868: #
                   15869: dmp02: movl    4*vrval(r10),r10# load value
                   15870:        cmpl    r10,$nulls      # loop for next vrblk if null value
                   15871:        beqlu   dmp01
                   15872:        cmpl    (r10),$b$trt    # loop back if value is trapped
                   15873:        beqlu   dmp02
                   15874: #
                   15875: #      NON-NULL VALUE, PREPARE TO SEARCH CHAIN
                   15876: #
                   15877:        movl    r9,r8           # save vrblk pointer
                   15878:        addl2   $4*vrsof,r9     # adjust ptr to be like scblk ptr
                   15879:        tstl    4*sclen(r9)     # jump if non-system variable
                   15880:        bnequ   dmp03
                   15881:        movl    4*vrsvo(r9),r9  # else load ptr to name in svblk
                   15882: #
                   15883: #      HERE WITH NAME POINTER FOR NEW BLOCK IN XR
                   15884: #
                   15885: dmp03: movl    r9,r7           # save pointer to chars
                   15886:        movl    r6,dmpsv        # save hash bucket pointer
                   15887:        movl    $dmvch,r6       # point to chain head
                   15888: #
                   15889: #      LOOP TO SEARCH CHAIN FOR CORRECT INSERTION POINT
                   15890: #
                   15891: dmp04: movl    r6,dmpch        # save chain pointer
                   15892:        movl    r6,r10          # copy it
                   15893:        movl    (r10),r9        # load pointer to next entry
                   15894:        bnequ   0f              # jump if end of chain to insert
                   15895:        jmp     dmp08
                   15896: 0:             
                   15897:        addl2   $4*vrsof,r9     # else get name ptr for chained vrblk
                   15898:        tstl    4*sclen(r9)     # jump if not system variable
                   15899:        bnequ   dmp05
                   15900:        movl    4*vrsvo(r9),r9  # else point to name in svblk
                   15901: #
                   15902: #      HERE PREPARE TO COMPARE THE NAMES
                   15903: #
                   15904: #      (WA)                  SCRATCH
                   15905: #      (WB)                  POINTER TO STRING OF ENTERING VRBLK
                   15906: #      (WC)                  POINTER TO ENTERING VRBLK
                   15907: #      (XR)                  POINTER TO STRING OF CURRENT BLOCK
                   15908: #      (XL)                  SCRATCH
                   15909: #
                   15910: dmp05: movl    r7,r10          # point to entering vrblk string
                   15911:        movl    4*sclen(r10),r6 # load its length
                   15912:        movab   cfp$f(r10),r10  # point to chars of entering string
                   15913:        cmpl    r6,4*sclen(r9)  # jump if entering length high
                   15914:        bgequ   dmp06
                   15915:        movab   cfp$f(r9),r9    # else point to chars of old string
                   15916:        jsb     sbcmc           # compare, insert if new is llt old
                   15917:        .long   dmp08
                   15918:        .long   dmp07
                   15919:        jmp     dmp08           # or if leq (we had shorter length)
                   15920: #
                   15921: #      HERE WHEN NEW LENGTH IS LONGER THAN OLD LENGTH
                   15922: #
                   15923: dmp06: movl    4*sclen(r9),r6  # load shorter length
                   15924:        movab   cfp$f(r9),r9    # point to chars of old string
                   15925:        jsb     sbcmc           # compare, insert if new one low
                   15926:        .long   dmp08
                   15927:        .long   dmp07
                   15928:        #page   
                   15929: #
                   15930: #      DUMPR (CONTINUED)
                   15931: #
                   15932: #      HERE WE MOVE OUT ON THE CHAIN
                   15933: #
                   15934: dmp07: movl    dmpch,r10       # copy chain pointer
                   15935:        movl    (r10),r6        # move to next entry on chain
                   15936:        jmp     dmp04           # loop back
                   15937: #
                   15938: #      HERE AFTER LOCATING THE PROPER INSERTION POINT
                   15939: #
                   15940: dmp08: movl    dmpch,r10       # copy chain pointer
                   15941:        movl    dmpsv,r6        # restore hash bucket pointer
                   15942:        movl    r8,r9           # restore vrblk pointer
                   15943:        movl    (r10),4*vrget(r9)# link vrblk to rest of chain
                   15944:        movl    r9,(r10)        # link vrblk into current chain loc
                   15945:        jmp     dmp01           # loop back for next vrblk
                   15946: #
                   15947: #      HERE AFTER PROCESSING ALL VRBLKS ON ONE CHAIN
                   15948: #
                   15949: dmp09: cmpl    r6,hshte        # loop back if more buckets to go
                   15950:        beqlu   0f
                   15951:        jmp     dmp00
                   15952: 0:             
                   15953: #
                   15954: #      LOOP TO GENERATE DUMP OF NATURAL VARIABLE VALUES
                   15955: #
                   15956: dmp10: movl    dmvch,r9        # load pointer to next entry on chain
                   15957:        beqlu   dmp11           # jump if end of chain
                   15958:        movl    (r9),dmvch      # else update chain ptr to next entry
                   15959:        jsb     setvr           # restore vrget field
                   15960:        movl    r9,r10          # copy vrblk pointer (name base)
                   15961:        movl    $4*vrval,r6     # set offset for vrblk name
                   15962:        jsb     prtnv           # print name = value
                   15963:        jmp     dmp10           # loop back till all printed
                   15964: #
                   15965: #      PREPARE TO PRINT KEYWORDS
                   15966: #
                   15967: dmp11: jsb     prtnl           # print blank line
                   15968:        jsb     prtnl           # and another
                   15969:        movl    $dmhdk,r9       # point to keyword heading
                   15970:        jsb     prtst           # print heading
                   15971:        jsb     prtnl           # end line
                   15972:        jsb     prtnl           # print one blank line
                   15973:        movl    $vdmkw,r10      # point to list of keyword svblk ptrs
                   15974:        #page   
                   15975: #
                   15976: #      DUMPR (CONTINUED)
                   15977: #
                   15978: #      LOOP TO DUMP KEYWORD VALUES
                   15979: #
                   15980: dmp12: movl    (r10)+,r9       # load next svblk ptr from table
                   15981:        beqlu   dmp13           # jump if end of list
                   15982:        movl    $ch$am,r6       # load ampersand
                   15983:        jsb     prtch           # print ampersand
                   15984:        jsb     prtst           # print keyword name
                   15985:        movl    4*svlen(r9),r6  # load name length from svblk
                   15986:        movab   3+(4*svchs)(r6),r6 # get length of name
                   15987:        bicl2   $3,r6
                   15988:        addl2   r6,r9           # point to svknm field
                   15989:        movl    (r9),dmpkn      # store in dummy kvblk
                   15990:        movl    $tmbeb,r9       # point to blank-equal-blank
                   15991:        jsb     prtst           # print it
                   15992:        movl    r10,dmpsv       # save table pointer
                   15993:        movl    $dmpkb,r10      # point to dummy kvblk
                   15994:        movl    $4*kvvar,r6     # set zero offset
                   15995:        jsb     acess           # get keyword value
                   15996:        .long   invalid$        # failure is impossible
                   15997:        jsb     prtvl           # print keyword value
                   15998:        jsb     prtnl           # terminate print line
                   15999:        movl    dmpsv,r10       # restore table pointer
                   16000:        jmp     dmp12           # loop back till all printed
                   16001: #
                   16002: #      HERE AFTER COMPLETING PARTIAL DUMP
                   16003: #
                   16004: dmp13: cmpl    dmarg,$num01    # exit if partial dump complete
                   16005:        bnequ   0f
                   16006:        jmp     dmp27
                   16007: 0:             
                   16008:        movl    dnamb,r9        # else point to first dynamic block
                   16009: #
                   16010: #      LOOP THROUGH BLOCKS IN DYNAMIC STORAGE
                   16011: #
                   16012: dmp14: cmpl    r9,dnamp        # jump if end of used region
                   16013:        bnequ   0f
                   16014:        jmp     dmp27
                   16015: 0:             
                   16016:        movl    (r9),r6         # else load first word of block
                   16017:        cmpl    r6,$b$vct       # jump if vector
                   16018:        beqlu   dmp16
                   16019:        cmpl    r6,$b$art       # jump if array
                   16020:        beqlu   dmp17
                   16021:        cmpl    r6,$b$pdt       # jump if program defined
                   16022:        beqlu   dmp18
                   16023:        cmpl    r6,$b$tbt       # jump if table
                   16024:        beqlu   dmp19
                   16025:        cmpl    r6,$b$bct       # jump if buffer
                   16026:        bnequ   0f
                   16027:        jmp     dmp30
                   16028: 0:             
                   16029: #
                   16030: #      MERGE HERE TO MOVE TO NEXT BLOCK
                   16031: #
                   16032: dmp15: jsb     blkln           # get length of block
                   16033:        addl2   r6,r9           # point past this block
                   16034:        jmp     dmp14           # loop back for next block
                   16035:        #page   
                   16036: #
                   16037: #      DUMPR (CONTINUED)
                   16038: #
                   16039: #      HERE FOR VECTOR
                   16040: #
                   16041: dmp16: movl    $4*vcvls,r7     # set offset to first value
                   16042:        jmp     dmp19           # jump to merge
                   16043: #
                   16044: #      HERE FOR ARRAY
                   16045: #
                   16046: dmp17: movl    4*arofs(r9),r7  # set offset to arpro field
                   16047:        addl2   $4,r7           # bump to get offset to values
                   16048:        jmp     dmp19           # jump to merge
                   16049: #
                   16050: #      HERE FOR PROGRAM DEFINED
                   16051: #
                   16052: dmp18: movl    $4*pdfld,r7     # point to values, merge
                   16053: #
                   16054: #      HERE FOR TABLE (OTHERS MERGE)
                   16055: #
                   16056: dmp19: tstl    4*idval(r9)     # ignore block if zero id value
                   16057:        bnequ   0f
                   16058:        jmp     dmp15
                   16059: 0:             
                   16060:        jsb     blkln           # else get block length
                   16061:        movl    r9,r10          # copy block pointer
                   16062:        movl    r6,dmpsv        # save length
                   16063:        movl    r7,r6           # copy offset to first value
                   16064:        jsb     prtnl           # print blank line
                   16065:        movl    r6,dmpsa        # preserve offset
                   16066:        jsb     prtvl           # print block value (for title)
                   16067:        movl    dmpsa,r6        # recover offset
                   16068:        jsb     prtnl           # end print line
                   16069:        cmpl    (r9),$b$tbt     # jump if table
                   16070:        beqlu   dmp22
                   16071:        subl2   $4,r6           # point before first word
                   16072: #
                   16073: #      LOOP TO PRINT CONTENTS OF ARRAY, VECTOR, OR PROGRAM DEF
                   16074: #
                   16075: dmp20: movl    r10,r9          # copy block pointer
                   16076:        addl2   $4,r6           # bump offset
                   16077:        addl2   r6,r9           # point to next value
                   16078:        cmpl    r6,dmpsv        # exit if end (xr past block)
                   16079:        bnequ   0f
                   16080:        jmp     dmp14
                   16081: 0:             
                   16082:        subl2   $4*vrval,r9     # subtract offset to merge into loop
                   16083: #
                   16084: #      LOOP TO FIND VALUE AND IGNORE NULLS
                   16085: #
                   16086: dmp21: movl    4*vrval(r9),r9  # load next value
                   16087:        cmpl    r9,$nulls       # loop back if null value
                   16088:        beqlu   dmp20
                   16089:        cmpl    (r9),$b$trt     # loop back if trapped
                   16090:        beqlu   dmp21
                   16091:        jsb     prtnv           # else print name = value
                   16092:        jmp     dmp20           # loop back for next field
                   16093:        #page   
                   16094: #
                   16095: #      DUMPR (CONTINUED)
                   16096: #
                   16097: #      HERE TO DUMP A TABLE
                   16098: #
                   16099: dmp22: movl    $4*tbbuk,r8     # set offset to first bucket
                   16100:        movl    $4*teval,r6     # set name offset for all teblks
                   16101: #
                   16102: #      LOOP THROUGH TABLE BUCKETS
                   16103: #
                   16104: dmp23: movl    r10,-(sp)       # save tbblk pointer
                   16105:        addl2   r8,r10          # point to next bucket header
                   16106:        addl2   $4,r8           # bump bucket offset
                   16107:        subl2   $4*tenxt,r10    # subtract offset to merge into loop
                   16108: #
                   16109: #      LOOP TO PROCESS TEBLKS ON ONE CHAIN
                   16110: #
                   16111: dmp24: movl    4*tenxt(r10),r10# point to next teblk
                   16112:        cmpl    r10,(sp)        # jump if end of chain
                   16113:        beqlu   dmp26
                   16114:        movl    r10,r9          # else copy teblk pointer
                   16115: #
                   16116: #      LOOP TO FIND VALUE AND IGNORE IF NULL
                   16117: #
                   16118: dmp25: movl    4*teval(r9),r9  # load next value
                   16119:        cmpl    r9,$nulls       # ignore if null value
                   16120:        beqlu   dmp24
                   16121:        cmpl    (r9),$b$trt     # loop back if trapped
                   16122:        beqlu   dmp25
                   16123:        movl    r8,dmpsv        # else save offset pointer
                   16124:        jsb     prtnv           # print name = value
                   16125:        movl    dmpsv,r8        # reload offset
                   16126:        jmp     dmp24           # loop back for next teblk
                   16127: #
                   16128: #      HERE TO MOVE TO NEXT HASH CHAIN
                   16129: #
                   16130: dmp26: movl    (sp)+,r10       # restore tbblk pointer
                   16131:        cmpl    r8,4*tblen(r10) # loop back if more buckets to go
                   16132:        bnequ   dmp23
                   16133:        movl    r10,r9          # else copy table pointer
                   16134:        addl2   r8,r9           # point to following block
                   16135:        jmp     dmp14           # loop back to process next block
                   16136: #
                   16137: #      HERE AFTER COMPLETING DUMP
                   16138: #
                   16139: dmp27: jsb     prtpg           # eject printer
                   16140: #
                   16141: #      MERGE HERE IF NO DUMP GIVEN (DMARG=0)
                   16142: #
                   16143: dmp28: rsb                     # return to dump caller
                   16144: #
                   16145: #      CALL SYSTEM CORE DUMP ROUTINE
                   16146: #
                   16147: dmp29: jsb     sysdm           # call it
                   16148:        jmp     dmp28           # return
                   16149:        #page   
                   16150: #
                   16151: #      DUMPR (CONTINUED)
                   16152: #
                   16153: #      HERE TO DUMP BUFFER BLOCK
                   16154: #
                   16155: dmp30: jsb     prtnl           # print blank line
                   16156:        jsb     prtvl           # print value id for title
                   16157:        jsb     prtnl           # force new line
                   16158:        movl    $ch$dq,r6       # load double quote
                   16159:        jsb     prtch           # print it
                   16160:        movl    4*bclen(r9),r8  # load defined length
                   16161:        beqlu   dmp32           # skip characters if none
                   16162:                                # load count for loop
                   16163:        movl    r9,r7           # save bcblk ptr
                   16164:        movl    4*bcbuf(r9),r9  # point to bfblk
                   16165:        movab   cfp$f(r9),r9    # get set to load characters
                   16166: #
                   16167: #      LOOP HERE STUFFING CHARACTERS IN OUTPUT STREAM
                   16168: #
                   16169: dmp31: movzbl  (r9)+,r6        # get next character
                   16170:        jsb     prtch           # stuff it
                   16171:        sobgtr  r8,dmp31        # branch for next one
                   16172:        movl    r7,r9           # restore bcblk pointer
                   16173: #
                   16174: #      MERGE TO STUFF CLOSING QUOTE MARK
                   16175: #
                   16176: dmp32: movl    $ch$dq,r6       # stuff quote
                   16177:        jsb     prtch           # print it
                   16178:        jsb     prtnl           # print new line
                   16179:        movl    (r9),r6         # get first wd for blkln
                   16180:        jmp     dmp15           # merge to get next block
                   16181:        #enp                    # end procedure dumpr
                   16182:        #page   
                   16183: #
                   16184: #      ERMSG -- PRINT ERROR CODE AND ERROR MESSAGE
                   16185: #
                   16186: #      KVERT                 ERROR CODE
                   16187: #      JSR  ERMSG            CALL TO PRINT MESSAGE
                   16188: #      (XR,XL,WA,WB,WC,IA)   DESTROYED
                   16189: #
                   16190: ermsg: #prc                    # entry point
                   16191:        jsb     prtis           # print error ptr or blank line
                   16192:        movl    kvert,r6        # load error code
                   16193:        movl    $ermms,r9       # point to error message /error/
                   16194:        jsb     prtst           # print it
                   16195:        jsb     ertex           # get error message text
                   16196:        addl2   $thsnd,r6       # bump error code for print
                   16197:        movl    r6,r5           # fail code in int acc
                   16198:        jsb     prtin           # print code (now have error1xxx)
                   16199:        movl    prbuf,r10       # point to print buffer
                   16200:        movl    $num05,r11      # [get in scratch register]
                   16201:        movab   cfp$f(r10)[r11],r10 # point to the 1
                   16202:        movl    $ch$bl,r6       # load a blank
                   16203:        movb    r6,(r10)        # store blank over 1 (error xxx)
                   16204:        #csc    r10             # complete store characters
                   16205:        clrl    r10             # clear garbage pointer in xl
                   16206:        movl    r9,r6           # keep error text
                   16207:        movl    $ermns,r9       # point to / -- /
                   16208:        jsb     prtst           # print it
                   16209:        movl    r6,r9           # get error text again
                   16210:        jsb     prtst           # print error message text
                   16211:        jsb     prtis           # print line
                   16212:        jsb     prtis           # print blank line
                   16213:        rsb                     # return to ermsg caller
                   16214:        #enp                    # end procedure ermsg
                   16215:        #page   
                   16216: #
                   16217: #      ERTEX -- GET ERROR MESSAGE TEXT
                   16218: #
                   16219: #      (WA)                  ERROR CODE
                   16220: #      JSR  ERTEX            CALL TO GET ERROR TEXT
                   16221: #      (XR)                  PTR TO ERROR TEXT IN DYNAMIC
                   16222: #      (R$ETX)               COPY OF PTR TO ERROR TEXT
                   16223: #      (XL,WC,IA)            DESTROYED
                   16224: #
                   16225: ertex: #prc                    # entry point
                   16226:        movl    r6,ertwa        # save wa
                   16227:        movl    r7,ertwb        # save wb
                   16228:        jsb     sysem           # get failure message text
                   16229:        movl    r9,r10          # copy pointer to it
                   16230:        movl    4*sclen(r9),r6  # get length of string
                   16231:        beqlu   ert02           # jump if null
                   16232:        clrl    r7              # offset of zero
                   16233:        jsb     sbstr           # copy into dynamic store
                   16234:        movl    r9,r$etx        # store for relocation
                   16235: #
                   16236: #      RETURN
                   16237: #
                   16238: ert01: movl    ertwb,r7        # restore wb
                   16239:        movl    ertwa,r6        # restore wa
                   16240:        rsb                     # return to caller
                   16241: #
                   16242: #      RETURN ERRTEXT CONTENTS INSTEAD OF NULL
                   16243: #
                   16244: ert02: movl    r$etx,r9        # get errtext
                   16245:        jmp     ert01           # return
                   16246:        #enp    
                   16247:        #page   
                   16248: #
                   16249: #      EVALI -- EVALUATE INTEGER ARGUMENT
                   16250: #
                   16251: #      EVALI IS USED BY PATTERN PRIMITIVES LEN,TAB,RTAB,POS,RPOS
                   16252: #      WHEN THEIR ARGUMENT IS AN EXPRESSION VALUE.
                   16253: #
                   16254: #      (XR)                  NODE POINTER
                   16255: #      (WB)                  CURSOR
                   16256: #      JSR  EVALI            CALL TO EVALUATE INTEGER
                   16257: #      PPM  LOC              TRANSFER LOC FOR NON-INTEGER ARG
                   16258: #      PPM  LOC              TRANSFER LOC FOR OUT OF RANGE ARG
                   16259: #      PPM  LOC              TRANSFER LOC FOR EVALUATION FAILURE
                   16260: #      PPM  LOC              TRANSFER LOC FOR SUCCESSFUL EVAL
                   16261: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   16262: #      (XR)                  PTR TO NODE WITH INTEGER ARGUMENT
                   16263: #      (WC,XL,RA)            DESTROYED
                   16264: #
                   16265: #      ON RETURN, THE NODE POINTED TO HAS THE INTEGER ARGUMENT
                   16266: #      IN PARM1 AND THE PROPER SUCCESSOR POINTER IN PTHEN.
                   16267: #      THIS ALLOWS MERGING WITH THE NORMAL (INTEGER ARG) CASE.
                   16268: #
                   16269: evali: #prc                    # entry point (recursive)
                   16270:        jsb     evalp           # evaluate expression
                   16271:        .long   evli1           # jump on failure
                   16272:        movl    r10,-(sp)       # stack result for gtsmi
                   16273:        movl    4*pthen(r9),r10 # load successor pointer
                   16274:        jsb     gtsmi           # convert arg to small integer
                   16275:        .long   evli2           # jump if not integer
                   16276:        .long   evli3           # jump if out of range
                   16277:        movl    r9,evliv        # store result in special dummy node
                   16278:        movl    r10,evlis       # store successor pointer
                   16279:        movl    $evlin,r9       # point to dummy node with result
                   16280:        addl3   $4*3,(sp)+,r11  # take successful exit
                   16281:        jmp     *(r11)+
                   16282: #
                   16283: #      HERE IF EVALUATION FAILS
                   16284: #
                   16285: evli1: addl3   $4*2,(sp)+,r11  # take failure return
                   16286:        jmp     *(r11)+
                   16287: #
                   16288: #      HERE IF ARGUMENT IS NOT INTEGER
                   16289: #
                   16290: evli2: movl    (sp)+,r11       # take non-integer error exit
                   16291:        jmp     *(r11)+
                   16292: #
                   16293: #      HERE IF ARGUMENT IS OUT OF RANGE
                   16294: #
                   16295: evli3: addl3   $4*1,(sp)+,r11  # take out-of-range error exit
                   16296:        jmp     *(r11)+
                   16297:        #enp                    # end procedure evali
                   16298:        #page   
                   16299: #
                   16300: #      EVALP -- EVALUATE EXPRESSION DURING PATTERN MATCH
                   16301: #
                   16302: #      EVALP IS USED TO EVALUATE AN EXPRESSION (BY VALUE) DURING
                   16303: #      A PATTERN MATCH. THE EFFECT IS LIKE EVALX, BUT PATTERN
                   16304: #      VARIABLES ARE STACKED AND RESTORED IF NECESSARY.
                   16305: #
                   16306: #      EVALP ALSO DIFFERS FROM EVALX IN THAT IF THE RESULT IS
                   16307: #      AN EXPRESSION IT IS REEVALUATED. THIS OCCURS REPEATEDLY.
                   16308: #
                   16309: #      (XR)                  NODE POINTER
                   16310: #      (WB)                  PATTERN MATCH CURSOR
                   16311: #      JSR  EVALP            CALL TO EVALUATE EXPRESSION
                   16312: #      PPM  LOC              TRANSFER LOC IF EVALUATION FAILS
                   16313: #      (XL)                  RESULT
                   16314: #      (WA)                  FIRST WORD OF RESULT BLOCK
                   16315: #      (XR,WB)               DESTROYED (FAILURE CASE ONLY)
                   16316: #      (WC,RA)               DESTROYED
                   16317: #
                   16318: #      THE EXPRESSION POINTER IS STORED IN PARM1 OF THE NODE
                   16319: #
                   16320: #      CONTROL RETURNS TO FAILP ON FAILURE OF EVALUATION
                   16321: #
                   16322: evalp: #prc                    # entry point (recursive)
                   16323:        movl    4*parm1(r9),r10 # load expression pointer
                   16324:        cmpl    (r10),$b$exl    # jump if exblk case
                   16325:        beqlu   evlp1
                   16326: #
                   16327: #      HERE FOR CASE OF SEBLK
                   16328: #
                   16329: #      WE CAN GIVE A FAST RETURN IF THE VALUE OF THE VRBLK IS
                   16330: #      NOT AN EXPRESSION AND IS NOT TRAPPED.
                   16331: #
                   16332:        movl    4*sevar(r10),r10# load vrblk pointer
                   16333:        movl    4*vrval(r10),r10# load value of vrblk
                   16334:        movl    (r10),r6        # load first word of value
                   16335:        cmpl    r6,$b$t$$       # jump if not seblk, trblk or exblk
                   16336:        bgequ   evlp3
                   16337: #
                   16338: #      HERE FOR EXBLK OR SEBLK WITH EXPR VALUE OR TRAPPED VALUE
                   16339: #
                   16340: evlp1: movl    r9,-(sp)        # stack node pointer
                   16341:        movl    r7,-(sp)        # stack cursor
                   16342:        movl    r$pms,-(sp)     # stack subject string pointer
                   16343:        movl    pmssl,-(sp)     # stack subject string length
                   16344:        movl    pmdfl,-(sp)     # stack dot flag
                   16345:        movl    pmhbs,-(sp)     # stack history stack base pointer
                   16346:        movl    4*parm1(r9),r9  # load expression pointer
                   16347:        #page   
                   16348: #
                   16349: #      EVALP (CONTINUED)
                   16350: #
                   16351: #      LOOP BACK HERE TO REEVALUATE EXPRESSION RESULT
                   16352: #
                   16353: evlp2: clrl    r7              # set flag for by value
                   16354:        jsb     evalx           # evaluate expression
                   16355:        .long   evlp4           # jump on failure
                   16356:        movl    (r9),r6         # else load first word of value
                   16357:        cmpl    r6,$b$e$$       # loop back to reevaluate expression
                   16358:        blequ   evlp2
                   16359: #
                   16360: #      HERE TO RESTORE PATTERN VALUES AFTER SUCCESSFUL EVAL
                   16361: #
                   16362:        movl    r9,r10          # copy result pointer
                   16363:        movl    (sp)+,pmhbs     # restore history stack base pointer
                   16364:        movl    (sp)+,pmdfl     # restore dot flag
                   16365:        movl    (sp)+,pmssl     # restore subject string length
                   16366:        movl    (sp)+,r$pms     # restore subject string pointer
                   16367:        movl    (sp)+,r7        # restore cursor
                   16368:        movl    (sp)+,r9        # restore node pointer
                   16369: #
                   16370: #      COMMON EXIT POINT
                   16371: #
                   16372: evlp3: addl2   $4*1,(sp)       # return to evalp caller
                   16373:        rsb     
                   16374: #
                   16375: #      HERE FOR FAILURE DURING EVALUATION
                   16376: #
                   16377: evlp4: movl    (sp)+,pmhbs     # restore history stack base pointer
                   16378:        movl    (sp)+,pmdfl     # restore dot flag
                   16379:        movl    (sp)+,pmssl     # restore subject string length
                   16380:        movl    (sp)+,r$pms     # restore subject string pointer
                   16381:        addl2   $4*num02,sp     # remove node ptr, cursor
                   16382:        movl    (sp)+,r11       # take failure exit
                   16383:        jmp     *(r11)+
                   16384:        #enp                    # end procedure evalp
                   16385:        #page   
                   16386: #
                   16387: #      EVALS -- EVALUATE STRING ARGUMENT
                   16388: #
                   16389: #      EVALS IS USED BY SPAN, ANY, NOTANY, BREAK, BREAKX WHEN
                   16390: #      THEY ARE PASSED AN EXPRESSION ARGUMENT.
                   16391: #
                   16392: #      (XR)                  NODE POINTER
                   16393: #      (WB)                  CURSOR
                   16394: #      JSR  EVALS            CALL TO EVALUATE STRING
                   16395: #      PPM  LOC              TRANSFER LOC FOR NON-STRING ARG
                   16396: #      PPM  LOC              TRANSFER LOC FOR EVALUATION FAILURE
                   16397: #      PPM  LOC              TRANSFER LOC FOR SUCCESSFUL EVAL
                   16398: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   16399: #      (XR)                  PTR TO NODE WITH PARMS SET
                   16400: #      (XL,WC,RA)            DESTROYED
                   16401: #
                   16402: #      ON RETURN, THE NODE POINTED TO HAS A CHARACTER TABLE
                   16403: #      POINTER IN PARM1 AND A BIT MASK IN PARM2. THE PROPER
                   16404: #      SUCCESSOR IS STORED IN PTHEN OF THIS NODE. THUS IT IS
                   16405: #      OK FOR MERGING WITH THE NORMAL (MULTI-CHAR STRING) CASE.
                   16406: #
                   16407: evals: #prc                    # entry point (recursive)
                   16408:        jsb     evalp           # evaluate expression
                   16409:        .long   evls1           # jump if evaluation fails
                   16410:        movl    4*pthen(r9),-(sp)# save successor pointer
                   16411:        movl    r7,-(sp)        # save cursor
                   16412:        movl    r10,-(sp)       # stack result ptr for patst
                   16413:        clrl    r7              # dummy pcode for one char string
                   16414:        clrl    r8              # dummy pcode for expression arg
                   16415:        movl    $p$brk,r10      # appropriate pcode for our use
                   16416:        jsb     patst           # call routine to build node
                   16417:        .long   evls2           # jump if not string
                   16418:        movl    (sp)+,r7        # restore cursor
                   16419:        movl    (sp)+,4*pthen(r9)# store successor pointer
                   16420:        addl3   $4*2,(sp)+,r11  # take success return
                   16421:        jmp     *(r11)+
                   16422: #
                   16423: #      HERE IF EVALUATION FAILS
                   16424: #
                   16425: evls1: addl3   $4*1,(sp)+,r11  # take failure return
                   16426:        jmp     *(r11)+
                   16427: #
                   16428: #      HERE IF ARGUMENT IS NOT STRING
                   16429: #
                   16430: evls2: addl2   $4*num02,sp     # pop successor and cursor
                   16431:        movl    (sp)+,r11       # take non-string error exit
                   16432:        jmp     *(r11)+
                   16433:        #enp                    # end procedure evals
                   16434:        #page   
                   16435: #
                   16436: #      EVALX -- EVALUATE EXPRESSION
                   16437: #
                   16438: #      EVALX IS CALLED TO EVALUATE AN EXPRESSION
                   16439: #
                   16440: #      (XR)                  POINTER TO EXBLK OR SEBLK
                   16441: #      (WB)                  0 IF BY VALUE, 1 IF BY NAME
                   16442: #      JSR  EVALX            CALL TO EVALUATE EXPRESSION
                   16443: #      PPM  LOC              TRANSFER LOC IF EVALUATION FAILS
                   16444: #      (XR)                  RESULT IF CALLED BY VALUE
                   16445: #      (XL,WA)               RESULT NAME BASE,OFFSET IF BY NAME
                   16446: #      (XR)                  DESTROYED (NAME CASE ONLY)
                   16447: #      (XL,WA)               DESTROYED (VALUE CASE ONLY)
                   16448: #      (WB,WC,RA)            DESTROYED
                   16449: #
                   16450: evalx: #prc                    # entry point, recursive
                   16451:        cmpl    (r9),$b$exl     # jump if exblk case
                   16452:        beqlu   evlx2
                   16453: #
                   16454: #      HERE FOR SEBLK
                   16455: #
                   16456:        movl    4*sevar(r9),r10 # load vrblk pointer (name base)
                   16457:        movl    $4*vrval,r6     # set name offset
                   16458:        tstl    r7              # jump if called by name
                   16459:        beqlu   0f
                   16460:        jmp     evlx1
                   16461: 0:             
                   16462:        jsb     acess           # call routine to access value
                   16463:        .long   evlx9           # jump if failure on access
                   16464: #
                   16465: #      MERGE HERE TO EXIT FOR SEBLK CASE
                   16466: #
                   16467: evlx1: addl2   $4*1,(sp)       # return to evalx caller
                   16468:        rsb     
                   16469:        #page   
                   16470: #
                   16471: #      EVALX (CONTINUED)
                   16472: #
                   16473: #      HERE FOR FULL EXPRESSION (EXBLK) CASE
                   16474: #
                   16475: #      IF AN ERROR OCCURS IN THE EXPRESSION CODE AT EXECUTION
                   16476: #      TIME, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   16477: #      WITHOUT RETURNING TO THIS ROUTINE.
                   16478: #      THE FOLLOWING ENTRIES ARE MADE ON THE STACK BEFORE
                   16479: #      GIVING CONTROL TO THE EXPRESSION CODE
                   16480: #
                   16481: #                            EVALX RETURN POINT
                   16482: #                            SAVED VALUE OF R$COD
                   16483: #                            CODE POINTER (-R$COD)
                   16484: #                            SAVED VALUE OF FLPTR
                   16485: #                            0 IF BY VALUE, 1 IF BY NAME
                   16486: #      FLPTR --------------- *EXFLC, FAIL OFFSET IN EXBLK
                   16487: #
                   16488: evlx2: movl    r3,r8           # get code pointer
                   16489:        movl    r$cod,r6        # load code block pointer
                   16490:        subl2   r6,r8           # get code pointer as offset
                   16491:        movl    r6,-(sp)        # stack old code block pointer
                   16492:        movl    r8,-(sp)        # stack relative code offset
                   16493:        movl    flptr,-(sp)     # stack old failure pointer
                   16494:        movl    r7,-(sp)        # stack name/value indicator
                   16495:        movl    $4*exflc,-(sp)  # stack new fail offset
                   16496:        movl    flptr,gtcef     # keep in case of error
                   16497:        movl    r$cod,r$gtc     # keep code block pointer similarly
                   16498:        movl    sp,flptr        # set new failure pointer
                   16499:        movl    r9,r$cod        # set new code block pointer
                   16500:        movl    kvstn,4*exstm(r9)# remember stmnt number
                   16501:        addl2   $4*excod,r9     # point to first code word
                   16502:        movl    r9,r3           # set code pointer
                   16503:        cmpl    stage,$stgxt    # jump if not execution time
                   16504:        beqlu   0f
                   16505:        jmp     exits
                   16506: 0:             
                   16507:        movl    $stgee,stage    # evaluating expression
                   16508:        jmp     exits           # jump to execute first code word
                   16509:        #page   
                   16510: #
                   16511: #      EVALX (CONTINUED)
                   16512: #
                   16513: #      COME HERE IF SUCCESSFUL RETURN BY VALUE (SEE O$RVL)
                   16514: #
                   16515: evlx3: movl    (sp)+,r9        # load value
                   16516:        tstl    4*1(sp) # jump if called by value
                   16517:        beqlu   evlx5
                   16518:        jmp     er_249          # expression evaluated by name returned value
                   16519: #
                   16520: #      HERE FOR EXPRESSION RETURNING BY NAME (SEE O$RNM)
                   16521: #
                   16522: evlx4: movl    (sp)+,r6        # load name offset
                   16523:        movl    (sp)+,r10       # load name base
                   16524:        tstl    4*1(sp) # jump if called by name
                   16525:        bnequ   evlx5
                   16526:        jsb     acess           # else access value first
                   16527:        .long   evlx6           # jump if failure during access
                   16528: #
                   16529: #      HERE AFTER LOADING CORRECT RESULT INTO XR OR XL,WA
                   16530: #
                   16531: evlx5: clrl    r7              # note successful
                   16532:        jmp     evlx7           # merge
                   16533: #
                   16534: #      HERE FOR FAILURE IN EXPRESSION EVALUATION (SEE O$FEX)
                   16535: #
                   16536: evlx6: movl    sp,r7           # note unsuccessful
                   16537: #
                   16538: #      RESTORE ENVIRONMENT
                   16539: #
                   16540: evlx7: cmpl    stage,$stgee    # skip if was not previously xt
                   16541:        bnequ   evlx8
                   16542:        movl    $stgxt,stage    # execute time
                   16543: #
                   16544: #      MERGE WITH STAGE SET UP
                   16545: #
                   16546: evlx8: addl2   $4*num02,sp     # pop name/value indicator, *exfal
                   16547:        movl    (sp)+,flptr     # restore old failure pointer
                   16548:        movl    (sp)+,r8        # load code offset
                   16549:        addl2   (sp),r8         # make code pointer absolute
                   16550:        movl    (sp)+,r$cod     # restore old code block pointer
                   16551:        movl    r8,r3           # restore old code pointer
                   16552:        tstl    r7              # jump for successful return
                   16553:        bnequ   0f
                   16554:        jmp     evlx1
                   16555: 0:             
                   16556: #
                   16557: #      MERGE HERE FOR FAILURE IN SEBLK CASE
                   16558: #
                   16559: evlx9: movl    (sp)+,r11       # take failure exit
                   16560:        jmp     *(r11)+
                   16561:        #enp                    # end of procedure evalx
                   16562:        #page   
                   16563: #
                   16564: #      EXBLD -- BUILD EXBLK
                   16565: #
                   16566: #      EXBLD IS USED TO BUILD AN EXPRESSION BLOCK FROM THE
                   16567: #      CODE COMPILED MOST RECENTLY IN THE CURRENT CCBLK.
                   16568: #
                   16569: #      (XL)                  OFFSET IN CCBLK TO START OF CODE
                   16570: #      (WB)                  INTEGER IN RANGE 0 LE N LE MXLEN
                   16571: #      JSR  EXBLD            CALL TO BUILD EXBLK
                   16572: #      (XR)                  PTR TO CONSTRUCTED EXBLK
                   16573: #      (WA,WB,XL)            DESTROYED
                   16574: #
                   16575: exbld: #prc                    # entry point
                   16576:        movl    r10,r6          # copy offset to start of code
                   16577:        subl2   $4*excod,r6     # calc reduction in offset in exblk
                   16578:        movl    r6,-(sp)        # stack for later
                   16579:        movl    cwcof,r6        # load final offset
                   16580:        subl2   r10,r6          # compute length of code
                   16581:        addl2   $4*exsi$,r6     # add space for standard fields
                   16582:        jsb     alloc           # allocate space for exblk
                   16583:        movl    r9,-(sp)        # save pointer to exblk
                   16584:        movl    $b$exl,4*extyp(r9) # store type word
                   16585:        clrl    4*exstm(r9)     # zeroise stmnt number field
                   16586:        movl    r6,4*exlen(r9)  # store length
                   16587:        movl    $ofex$,4*exflc(r9) # store failure word
                   16588:        addl2   $4*exsi$,r9     # set xr for sysmw
                   16589:        movl    r10,cwcof       # reset offset to start of code
                   16590:        addl2   r$ccb,r10       # point to start of code
                   16591:        subl2   $4*exsi$,r6     # length of code to move
                   16592:        movl    r6,-(sp)        # stack length of code
                   16593:        jsb     sbmvw           # move code to exblk
                   16594:        movl    (sp)+,r6        # get length of code
                   16595:        ashl    $-2,r6,r6       # convert byte count to word count
                   16596:                                # prepare counter for loop
                   16597:        movl    (sp),r10        # copy exblk ptr, dont unstack
                   16598:        addl2   $4*excod,r10    # point to code itself
                   16599:        movl    4*1(sp),r7      # get reduction in offset
                   16600: #
                   16601: #      THIS LOOP SEARCHES FOR NEGATION AND SELECTION CODE SO
                   16602: #      THAT THE OFFSETS COMPUTED WHILST CODE WAS IN CODE BLOCK
                   16603: #      CAN BE TRANSFORMED TO REDUCED VALUES APPLICABLE IN AN
                   16604: #      EXBLK.
                   16605: #
                   16606: exbl1: movl    (r10)+,r9       # get next code word
                   16607:        cmpl    r9,$osla$       # jump if selection found
                   16608:        beqlu   exbl3
                   16609:        cmpl    r9,$onta$       # jump if negation found
                   16610:        beqlu   exbl3
                   16611:        sobgtr  r6,exbl1        # loop to end of code
                   16612: #
                   16613: #      NO SELECTION FOUND OR MERGE TO EXIT ON TERMINATION
                   16614: #
                   16615: exbl2: movl    (sp)+,r9        # pop exblk ptr into xr
                   16616:        movl    (sp)+,r10       # pop reduction constant
                   16617:        rsb                     # return to caller
                   16618:        #page   
                   16619: #
                   16620: #      EXBLD (CONTINUED)
                   16621: #
                   16622: #      SELECTION OR NEGATION FOUND
                   16623: #      REDUCE THE OFFSETS AS NEEDED. OFFSETS OCCUR IN WORDS
                   16624: #      FOLLOWING CODE WORDS -
                   16625: #           =ONTA$, =OSLA$, =OSLB$, =OSLC$
                   16626: #
                   16627: exbl3: subl2   r7,(r10)+       # adjust offset
                   16628:        sobgtr  r6,exbl4        # decrement count
                   16629: #
                   16630: exbl4: sobgtr  r6,exbl5        # decrement count
                   16631: #
                   16632: #      CONTINUE SEARCH FOR MORE OFFSETS
                   16633: #
                   16634: exbl5: movl    (r10)+,r9       # get next code word
                   16635:        cmpl    r9,$osla$       # jump if offset found
                   16636:        beqlu   exbl3
                   16637:        cmpl    r9,$oslb$       # jump if offset found
                   16638:        beqlu   exbl3
                   16639:        cmpl    r9,$oslc$       # jump if offset found
                   16640:        beqlu   exbl3
                   16641:        cmpl    r9,$onta$       # jump if offset found
                   16642:        beqlu   exbl3
                   16643:        sobgtr  r6,exbl5        # loop
                   16644:        jmp     exbl2           # merge to return
                   16645:        #enp                    # end procedure exbld
                   16646:        #page   
                   16647: #
                   16648: #      EXPAN -- ANALYZE EXPRESSION
                   16649: #
                   16650: #      THE EXPRESSION ANALYZER (EXPAN) PROCEDURE IS USED TO SCAN
                   16651: #      AN EXPRESSION AND CONVERT IT INTO A TREE REPRESENTATION.
                   16652: #      SEE DESCRIPTIONS OF CMBLK, CUBLK, CBBLK IN THE STRUCTURES
                   16653: #      SECTION FOR DETAILED FORMAT OF TREE BLOCKS.
                   16654: #
                   16655: #      THE ANALYZER USES A SIMPLE PRECEDENCE SCHEME IN WHICH
                   16656: #      OPERANDS AND OPERATORS ARE PLACED ON A SINGLE STACK
                   16657: #      AND CONDENSATIONS ARE MADE WHEN LOW PRECEDENCE OPERATORS
                   16658: #      ARE STACKED AFTER A HIGHER PRECEDENCE OPERATOR. A GLOBAL
                   16659: #      VARIABLE (IN WB) KEEPS TRACK OF THE LEVEL AS FOLLOWS.
                   16660: #
                   16661: #      0    SCANNING OUTER LEVEL OF STATEMENT OR EXPRESSION
                   16662: #      1    SCANNING OUTER LEVEL OF NORMAL GOTO
                   16663: #      2    SCANNING OUTER LEVEL OF DIRECT GOTO
                   16664: #      3    SCANNING INSIDE ARRAY BRACKETS
                   16665: #      4    SCANNING INSIDE GROUPING PARENTHESES
                   16666: #      5    SCANNING INSIDE FUNCTION PARENTHESES
                   16667: #
                   16668: #      THIS VARIABLE IS SAVED ON THE STACK ON ENCOUNTERING A
                   16669: #      GROUPING AND RESTORED AT THE END OF THE GROUPING.
                   16670: #
                   16671: #      ANOTHER GLOBAL VARIABLE (IN WC) COUNTS THE NUMBER OF
                   16672: #      ITEMS AT ONE GROUPING LEVEL AND IS INCREMENTED FOR EACH
                   16673: #      COMMA ENCOUNTERED. IT IS STACKED WITH THE LEVEL INDICATOR
                   16674: #
                   16675: #      THE SCAN IS CONTROLLED BY A THREE STATE FINITE MACHINE.
                   16676: #      A GLOBAL VARIABLE STORED IN WA IS THE CURRENT STATE.
                   16677: #
                   16678: #      WA=0                  NOTHING SCANNED AT THIS LEVEL
                   16679: #      WA=1                  OPERAND EXPECTED
                   16680: #      WA=2                  OPERATOR EXPECTED
                   16681: #
                   16682: #      (WB)                  CALL TYPE (SEE BELOW)
                   16683: #      JSR  EXPAN            CALL TO ANALYZE EXPRESSION
                   16684: #      (XR)                  POINTER TO RESULTING TREE
                   16685: #      (XL,WA,WB,WC,RA)      DESTROYED
                   16686: #
                   16687: #      THE ENTRY VALUE OF WB INDICATES THE CALL TYPE AS FOLLOWS.
                   16688: #
                   16689: #      0    SCANNING EITHER THE MAIN BODY OF A STATEMENT OR THE
                   16690: #           TEXT OF AN EXPRESSION (FROM EVAL CALL). VALID
                   16691: #           TERMINATORS ARE COLON, SEMICOLON. THE RESCAN FLAG IS
                   16692: #           SET TO RETURN THE TERMINATOR ON THE NEXT SCANE CALL.
                   16693: #
                   16694: #      1    SCANNING A NORMAL GOTO. THE ONLY VALID
                   16695: #           TERMINATOR IS A RIGHT PAREN.
                   16696: #
                   16697: #      2    SCANNING A DIRECT GOTO. THE ONLY VALID
                   16698: #           TERMINATOR IS A RIGHT BRACKET.
                   16699:        #page   
                   16700: #
                   16701: #      EXPAN (CONTINUED)
                   16702: #
                   16703: #      ENTRY POINT
                   16704: #
                   16705: expan: #prc                    # entry point
                   16706:        clrl    -(sp)           # set top of stack indicator
                   16707:        clrl    r6              # set initial state to zero
                   16708:        clrl    r8              # zero counter value
                   16709: #
                   16710: #      LOOP HERE FOR SUCCESSIVE ENTRIES
                   16711: #
                   16712: exp01: jsb     scane           # scan next element
                   16713:        addl2   r6,r10          # add state to syntax code
                   16714:        casel   r10,$0,$t$nes   # switch on element type/state
                   16715: 5:             
                   16716:        .word   exp27-5b        # unop, s=0
                   16717:        .word   exp27-5b        # unop, s=1
                   16718:        .word   exp04-5b        # unop, s=2
                   16719:        .word   exp06-5b        # left paren, s=0
                   16720:        .word   exp06-5b        # left paren, s=1
                   16721:        .word   exp04-5b        # left paren, s=2
                   16722:        .word   exp08-5b        # left brkt, s=0
                   16723:        .word   exp08-5b        # left brkt, s=1
                   16724:        .word   exp09-5b        # left brkt, s=2
                   16725:        .word   exp02-5b        # comma, s=0
                   16726:        .word   exp05-5b        # comma, s=1
                   16727:        .word   exp11-5b        # comma, s=2
                   16728:        .word   exp10-5b        # function, s=0
                   16729:        .word   exp10-5b        # function, s=1
                   16730:        .word   exp04-5b        # function, s=2
                   16731:        .word   exp03-5b        # variable, s=0
                   16732:        .word   exp03-5b        # variable, state one
                   16733:        .word   exp04-5b        # variable, s=2
                   16734:        .word   exp03-5b        # constant, s=0
                   16735:        .word   exp03-5b        # constant, s=1
                   16736:        .word   exp04-5b        # constant, s=2
                   16737:        .word   exp05-5b        # binop, s=0
                   16738:        .word   exp05-5b        # binop, s=1
                   16739:        .word   exp26-5b        # binop, s=2
                   16740:        .word   exp02-5b        # right paren, s=0
                   16741:        .word   exp05-5b        # right paren, s=1
                   16742:        .word   exp12-5b        # right paren, s=2
                   16743:        .word   exp02-5b        # right brkt, s=0
                   16744:        .word   exp05-5b        # right brkt, s=1
                   16745:        .word   exp18-5b        # right brkt, s=2
                   16746:        .word   exp02-5b        # colon, s=0
                   16747:        .word   exp05-5b        # colon, s=1
                   16748:        .word   exp19-5b        # colon, s=2
                   16749:        .word   exp02-5b        # semicolon, s=0
                   16750:        .word   exp05-5b        # semicolon, s=1
                   16751:        .word   exp19-5b        # semicolon, s=2
                   16752:        #esw                    # end switch on element type/state
                   16753:        #page   
                   16754: #
                   16755: #      EXPAN (CONTINUED)
                   16756: #
                   16757: #      HERE FOR RBR,RPR,COL,SMC,CMA IN STATE 0
                   16758: #
                   16759: #      SET TO RESCAN THE TERMINATOR ENCOUNTERED AND CREATE
                   16760: #      A NULL CONSTANT (CASE OF OMITTED NULL)
                   16761: #
                   16762: exp02: movl    sp,scnrs        # set to rescan element
                   16763:        movl    $nulls,r9       # point to null, merge
                   16764: #
                   16765: #      HERE FOR VAR OR CON IN STATES 0,1
                   16766: #
                   16767: #      STACK THE VARIABLE/CONSTANT AND SET STATE=2
                   16768: #
                   16769: exp03: movl    r9,-(sp)        # stack pointer to operand
                   16770:        movl    $num02,r6       # set state 2
                   16771:        jmp     exp01           # jump for next element
                   16772: #
                   16773: #      HERE FOR VAR,CON,LPR,FNC,UOP IN STATE 2
                   16774: #
                   16775: #      WE RESCAN THE ELEMENT AND CREATE A CONCATENATION OPERATOR
                   16776: #      THIS IS THE CASE OF THE BLANK CONCATENATION OPERATOR.
                   16777: #
                   16778: exp04: movl    sp,scnrs        # set to rescan element
                   16779:        movl    $opdvc,r9       # point to concat operator dv
                   16780:        tstl    r7              # ok if at top level
                   16781:        beqlu   exp4a
                   16782:        movl    $opdvp,r9       # else point to unmistakable concat.
                   16783: #
                   16784: #      MERGE HERE WHEN XR SET UP WITH PROPER CONCATENATION DVBLK
                   16785: #
                   16786: exp4a: tstl    scnbl           # merge bop if blanks, else error
                   16787:        beqlu   0f
                   16788:        jmp     exp26
                   16789: 0:             
                   16790:        decl    scnse           # adjust start of element location
                   16791:        jmp     er_220          # syntax error. missing operator
                   16792: #
                   16793: #      HERE FOR CMA,RPR,RBR,COL,SMC,BOP(S=1) BOP(S=0)
                   16794: #
                   16795: #      THIS IS AN ERRONOUS CONTRUCTION
                   16796: #
                   16797: exp05: decl    scnse           # adjust start of element location
                   16798:        jmp     er_221          # syntax error. missing operand
                   16799: #
                   16800: #      HERE FOR LPR (S=0,1)
                   16801: #
                   16802: exp06: movl    $num04,r10      # set new level indicator
                   16803:        clrl    r9              # set zero value for cmopn
                   16804:        #page   
                   16805: #
                   16806: #      EXPAN (CONTINUED)
                   16807: #
                   16808: #      MERGE HERE TO STORE OLD LEVEL ON STACK AND START NEW ONE
                   16809: #
                   16810: exp07: movl    r9,-(sp)        # stack cmopn value
                   16811:        movl    r8,-(sp)        # stack old counter
                   16812:        movl    r7,-(sp)        # stack old level indicator
                   16813:        jsb     sbchk           # check for stack overflow
                   16814:        clrl    r6              # set new state to zero
                   16815:        movl    r10,r7          # set new level indicator
                   16816:        movl    $num01,r8       # initialize new counter
                   16817:        jmp     exp01           # jump to scan next element
                   16818: #
                   16819: #      HERE FOR LBR (S=0,1)
                   16820: #
                   16821: #      THIS IS AN ILLEGAL USE OF LEFT BRACKET
                   16822: #
                   16823: exp08: jmp     er_222          # syntax error. invalid use of left bracket
                   16824: #
                   16825: #      HERE FOR LBR (S=2)
                   16826: #
                   16827: #      SET NEW LEVEL AND START TO SCAN SUBSCRIPTS
                   16828: #
                   16829: exp09: movl    (sp)+,r9        # load array ptr for cmopn
                   16830:        movl    $num03,r10      # set new level indicator
                   16831:        jmp     exp07           # jump to stack old and start new
                   16832: #
                   16833: #      HERE FOR FNC (S=0,1)
                   16834: #
                   16835: #      STACK OLD LEVEL AND START TO SCAN ARGUMENTS
                   16836: #
                   16837: exp10: movl    $num05,r10      # set new lev indic (xr=vrblk=cmopn)
                   16838:        jmp     exp07           # jump to stack old and start new
                   16839: #
                   16840: #      HERE FOR CMA (S=2)
                   16841: #
                   16842: #      INCREMENT ARGUMENT COUNT AND CONTINUE
                   16843: #
                   16844: exp11: incl    r8              # increment counter
                   16845:        jsb     expdm           # dump operators at this level
                   16846:        clrl    -(sp)           # set new level for parameter
                   16847:        clrl    r6              # set new state
                   16848:        cmpl    r7,$num02       # loop back unless outer level
                   16849:        blequ   0f
                   16850:        jmp     exp01
                   16851: 0:             
                   16852:        jmp     er_223          # syntax error. invalid use of comma
                   16853:        #page   
                   16854: #
                   16855: #      EXPAN (CONTINUED)
                   16856: #
                   16857: #      HERE FOR RPR (S=2)
                   16858: #
                   16859: #      AT OUTER LEVEL IN A NORMAL GOTO THIS IS A TERMINATOR
                   16860: #      OTHERWISE IT MUST TERMINATE A FUNCTION OR GROUPING
                   16861: #
                   16862: exp12: cmpl    r7,$num01       # end of normal goto
                   16863:        bnequ   0f
                   16864:        jmp     exp20
                   16865: 0:             
                   16866:        cmpl    r7,$num05       # end of function arguments
                   16867:        beqlu   exp13
                   16868:        cmpl    r7,$num04       # end of grouping / selection
                   16869:        beqlu   exp14
                   16870:        jmp     er_224          # syntax error. unbalanced right parenthesis
                   16871: #
                   16872: #      HERE AT END OF FUNCTION ARGUMENTS
                   16873: #
                   16874: exp13: movl    $c$fnc,r10      # set cmtyp value for function
                   16875:        jmp     exp15           # jump to build cmblk
                   16876: #
                   16877: #      HERE FOR END OF GROUPING
                   16878: #
                   16879: exp14: cmpl    r8,$num01       # jump if end of grouping
                   16880:        beqlu   exp17
                   16881:        movl    $c$sel,r10      # else set cmtyp for selection
                   16882: #
                   16883: #      MERGE HERE TO BUILD CMBLK FOR LEVEL JUST SCANNED AND
                   16884: #      TO POP UP TO THE PREVIOUS SCAN LEVEL BEFORE CONTINUING.
                   16885: #
                   16886: exp15: jsb     expdm           # dump operators at this level
                   16887:        movl    r8,r6           # copy count
                   16888:        addl2   $cmvls,r6       # add for standard fields at start
                   16889:        moval   0[r6],r6        # convert length to bytes
                   16890:        jsb     alloc           # allocate space for cmblk
                   16891:        movl    $b$cmt,(r9)     # store type code for cmblk
                   16892:        movl    r10,4*cmtyp(r9) # store cmblk node type indicator
                   16893:        movl    r6,4*cmlen(r9)  # store length
                   16894:        addl2   r6,r9           # point past end of block
                   16895:                                # set loop counter
                   16896: #
                   16897: #      LOOP TO MOVE REMAINING WORDS TO CMBLK
                   16898: #
                   16899: exp16: movl    (sp)+,-(r9)     # move one operand ptr from stack
                   16900:        movl    (sp)+,r7        # pop to old level indicator
                   16901:        sobgtr  r8,exp16        # loop till all moved
                   16902:        #page   
                   16903: #
                   16904: #      EXPAN (CONTINUED)
                   16905: #
                   16906: #      COMPLETE CMBLK AND STACK POINTER TO IT ON STACK
                   16907: #
                   16908:        subl2   $4*cmvls,r9     # point back to start of block
                   16909:        movl    (sp)+,r8        # restore old counter
                   16910:        movl    (sp),4*cmopn(r9)# store operand ptr in cmblk
                   16911:        movl    r9,(sp)         # stack cmblk pointer
                   16912:        movl    $num02,r6       # set new state
                   16913:        jmp     exp01           # back for next element
                   16914: #
                   16915: #      HERE AT END OF A PARENTHESIZED EXPRESSION
                   16916: #
                   16917: exp17: jsb     expdm           # dump operators at this level
                   16918:        movl    (sp)+,r9        # restore xr
                   16919:        movl    (sp)+,r7        # restore outer level
                   16920:        movl    (sp)+,r8        # restore outer count
                   16921:        movl    r9,(sp)         # store opnd over unused cmopn val
                   16922:        movl    $num02,r6       # set new state
                   16923:        jmp     exp01           # back for next ele8ent
                   16924: #
                   16925: #      HERE FOR RBR (S=2)
                   16926: #
                   16927: #      AT OUTER LEVEL IN A DIRECT GOTO, THIS IS A TERMINATOR.
                   16928: #      OTHERWISE IT MUST TERMINATE A SUBSCRIPT LIST.
                   16929: #
                   16930: exp18: movl    $c$arr,r10      # set cmtyp for array reference
                   16931:        cmpl    r7,$num03       # jump to build cmblk if end arrayref
                   16932:        beqlu   exp15
                   16933:        cmpl    r7,$num02       # jump if end of direct goto
                   16934:        bnequ   0f
                   16935:        jmp     exp20
                   16936: 0:             
                   16937:        jmp     er_225          # syntax error. unbalanced right bracket
                   16938:        #page   
                   16939: #
                   16940: #      EXPAN (CONTINUED)
                   16941: #
                   16942: #      HERE FOR COL,SMC (S=2)
                   16943: #
                   16944: #      ERROR UNLESS TERMINATING STATEMENT BODY AT OUTER LEVEL
                   16945: #
                   16946: exp19: movl    sp,scnrs        # rescan terminator
                   16947:        movl    r7,r10          # copy level indicator
                   16948:        casel   r10,$0,$6       # switch on level indicator
                   16949: 5:             
                   16950:        .word   exp20-5b        # normal outer level
                   16951:        .word   exp22-5b        # fail if normal goto
                   16952:        .word   exp23-5b        # fail if direct goto
                   16953:        .word   exp24-5b        # fail array brackets
                   16954:        .word   exp21-5b        # fail if in grouping
                   16955:        .word   exp21-5b        # fail function args
                   16956:        #esw                    # end switch on level
                   16957: #
                   16958: #      HERE AT NORMAL END OF EXPRESSION
                   16959: #
                   16960: exp20: jsb     expdm           # dump remaining operators
                   16961:        movl    (sp)+,r9        # load tree pointer
                   16962:        addl2   $4,sp           # pop off bottom of stack marker
                   16963:        rsb                     # return to expan caller
                   16964: #
                   16965: #      MISSING RIGHT PAREN
                   16966: #
                   16967: exp21: jmp     er_226          # syntax error. missing right paren
                   16968: #
                   16969: #      MISSING RIGHT PAREN IN GOTO FIELD
                   16970: #
                   16971: exp22: jmp     er_227          # syntax error. right paren missing from goto
                   16972: #
                   16973: #      MISSING BRACKET IN GOTO
                   16974: #
                   16975: exp23: jmp     er_228          # syntax error. right bracket missing from goto
                   16976: #
                   16977: #      MISSING ARRAY BRACKET
                   16978: #
                   16979: exp24: jmp     er_229          # syntax error. missing right array bracket
                   16980:        #page   
                   16981: #
                   16982: #      EXPAN (CONTINUED)
                   16983: #
                   16984: #      LOOP HERE WHEN AN OPERATOR CAUSES AN OPERATOR DUMP
                   16985: #
                   16986: exp25: movl    r9,expsv
                   16987:        jsb     expop           # pop one operator
                   16988:        movl    expsv,r9        # restore op dv pointer and merge
                   16989: #
                   16990: #      HERE FOR BOP (S=2)
                   16991: #
                   16992: #      REMOVE OPERATORS (CONDENSE) FROM STACK UNTIL NO MORE
                   16993: #      LEFT AT THIS LEVEL OR TOP ONE HAS LOWER PRECEDENCE.
                   16994: #      LOOP HERE TILL THIS CONDITION IS MET.
                   16995: #
                   16996: exp26: movl    4*1(sp),r10     # load operator dvptr from stack
                   16997:        cmpl    r10,$num05      # jump if bottom of stack level
                   16998:        blequ   exp27
                   16999:        cmpl    4*dvrpr(r9),4*dvlpr(r10) # else pop if new prec is lo
                   17000:        blssu   exp25
                   17001: #
                   17002: #      HERE FOR UOP (S=0,1)
                   17003: #
                   17004: #      BINARY OPERATOR MERGES AFTER PRECEDENCE CHECK
                   17005: #
                   17006: #      THE OPERATOR DV IS STORED ON THE STACK AND THE SCAN
                   17007: #      CONTINUES AFTER SETTING THE SCAN STATE TO ONE.
                   17008: #
                   17009: exp27: movl    r9,-(sp)        # stack operator dvptr on stack
                   17010:        jsb     sbchk           # check for stack overflow
                   17011:        movl    $num01,r6       # set new state
                   17012:        cmpl    r9,$opdvs       # back for next element unless =
                   17013:        beqlu   0f
                   17014:        jmp     exp01
                   17015: 0:             
                   17016: #
                   17017: #      HERE FOR SPECIAL CASE OF BINARY =. THE SYNTAX ALLOWS A
                   17018: #      NULL RIGHT ARGUMENT FOR THIS OPERATOR TO BE LEFT
                   17019: #      OUT. ACCORDINGLY WE RESET TO STATE ZERO TO GET PROPER
                   17020: #      ACTION ON A TERMINATOR (SUPPLY A NULL CONSTANT).
                   17021: #
                   17022:        clrl    r6              # set state zero
                   17023:        jmp     exp01           # jump for next element
                   17024:        #enp                    # end procedure expan
                   17025:        #page   
                   17026: #
                   17027: #      EXPAP -- TEST FOR PATTERN MATCH TREE
                   17028: #
                   17029: #      EXPAP IS PASSED AN EXPRESSION TREE TO DETERMINE IF IT
                   17030: #      IS A PATTERN MATCH. THE FOLLOWING ARE RECOGIZED AS
                   17031: #      MATCHES IN THE CONTEXT OF THIS CALL.
                   17032: #
                   17033: #      1)   AN EXPLICIT USE OF BINARY QUESTION MARK
                   17034: #      2)   A CONCATENATION
                   17035: #      3)   AN ALTERNATION WHOSE LEFT OPERAND IS A CONCATENATION
                   17036: #
                   17037: #      (XR)                  PTR TO EXPAN TREE
                   17038: #      JSR  EXPAP            CALL TO TEST FOR PATTERN MATCH
                   17039: #      PPM  LOC              TRANSFER LOC IF NOT A PATTERN MATCH
                   17040: #      (WA)                  DESTROYED
                   17041: #      (XR)                  UNCHANGED (IF NOT MATCH)
                   17042: #      (XR)                  PTR TO BINARY OPERATOR BLK IF MATCH
                   17043: #
                   17044: expap: #prc                    # entry point
                   17045:        movl    r10,-(sp)       # save xl
                   17046:        cmpl    (r9),$b$cmt     # no match if not complex
                   17047:        bnequ   expp2
                   17048:        movl    4*cmtyp(r9),r6  # else load type code
                   17049:        cmpl    r6,$c$cnc       # concatenation is a match
                   17050:        beqlu   expp1
                   17051:        cmpl    r6,$c$pmt       # binary question mark is a match
                   17052:        beqlu   expp1
                   17053:        cmpl    r6,$c$alt       # else not match unless alternation
                   17054:        bnequ   expp2
                   17055: #
                   17056: #      HERE FOR ALTERNATION. CHANGE (A B) / C TO A QM (B / C)
                   17057: #
                   17058:        movl    4*cmlop(r9),r10 # load left operand pointer
                   17059:        cmpl    (r10),$b$cmt    # not match if left opnd not complex
                   17060:        bnequ   expp2
                   17061:        cmpl    4*cmtyp(r10),$c$cnc # not match if left op not conc
                   17062:        bnequ   expp2
                   17063:        movl    4*cmrop(r10),4*cmlop(r9) # xr points to (b / c)
                   17064:        movl    r9,4*cmrop(r10) # set xl opnds to a, (b / c)
                   17065:        movl    r10,r9          # point to this altered node
                   17066: #
                   17067: #      EXIT HERE FOR PATTERN MATCH
                   17068: #
                   17069: expp1: movl    (sp)+,r10       # restore entry xl
                   17070:        addl2   $4*1,(sp)       # give pattern match return
                   17071:        rsb     
                   17072: #
                   17073: #      EXIT HERE IF NOT PATTERN MATCH
                   17074: #
                   17075: expp2: movl    (sp)+,r10       # restore entry xl
                   17076:        movl    (sp)+,r11       # give non-match return
                   17077:        jmp     *(r11)+
                   17078:        #enp                    # end procedure expap
                   17079:        #page   
                   17080: #
                   17081: #      EXPDM -- DUMP OPERATORS AT CURRENT LEVEL (FOR EXPAN)
                   17082: #
                   17083: #      EXPDM USES EXPOP TO CONDENSE ALL OPERATORS AT THIS SYNTAX
                   17084: #      LEVEL. THE STACK BOTTOM IS RECOGNIZED FROM THE LEVEL
                   17085: #      VALUE WHICH IS SAVED ON THE TOP OF THE STACK.
                   17086: #
                   17087: #      JSR  EXPDM            CALL TO DUMP OPERATORS
                   17088: #      (XS)                  POPPED AS REQUIRED
                   17089: #      (XR,WA)               DESTROYED
                   17090: #
                   17091:        .data   1
                   17092: expdm_s:       .long   0
                   17093:        .text   0
                   17094: expdm: movl    (sp)+,expdm_s   # entry point
                   17095:        movl    r10,r$exs       # save xl value
                   17096: #
                   17097: #      LOOP TO DUMP OPERATORS
                   17098: #
                   17099: exdm1: cmpl    4*1(sp),$num05  # jump if stack bottom (saved level
                   17100:        blequ   exdm2
                   17101:        jsb     expop           # else pop one operator
                   17102:        jmp     exdm1           # and loop back
                   17103: #
                   17104: #      HERE AFTER POPPING ALL OPERATORS
                   17105: #
                   17106: exdm2: movl    r$exs,r10       # restore xl
                   17107:        clrl    r$exs           # release save location
                   17108:        jmp     *expdm_s        # return to expdm caller
                   17109:        #enp                    # end procedure expdm
                   17110:        #page   
                   17111: #
                   17112: #      EXPOP-- POP OPERATOR (FOR EXPAN)
                   17113: #
                   17114: #      EXPOP IS USED BY THE EXPAN ROUTINE TO CONDENSE ONE
                   17115: #      OPERATOR FROM THE TOP OF THE SYNTAX STACK. AN APPROPRIATE
                   17116: #      CMBLK IS BUILT FOR THE OPERATOR (UNARY OR BINARY) AND A
                   17117: #      POINTER TO THIS CMBLK IS STACKED.
                   17118: #
                   17119: #      EXPOP IS ALSO USED BY SCNGF (GOTO FIELD SCAN) PROCEDURE
                   17120: #
                   17121: #      JSR  EXPOP            CALL TO POP OPERATOR
                   17122: #      (XS)                  POPPED APPROPRIATELY
                   17123: #      (XR,XL,WA)            DESTROYED
                   17124: #
                   17125:        .data   1
                   17126: expop_s:       .long   0
                   17127:        .text   0
                   17128: expop: movl    (sp)+,expop_s   # entry point
                   17129:        movl    4*1(sp),r9      # load operator dv pointer
                   17130:        cmpl    4*dvlpr(r9),$lluno # jump if unary
                   17131:        beqlu   expo2
                   17132: #
                   17133: #      HERE FOR BINARY OPERATOR
                   17134: #
                   17135:        movl    $4*cmbs$,r6     # set size of binary operator cmblk
                   17136:        jsb     alloc           # allocate space for cmblk
                   17137:        movl    (sp)+,4*cmrop(r9)# pop and store right operand ptr
                   17138:        movl    (sp)+,r10       # pop and load operator dv ptr
                   17139:        movl    (sp),4*cmlop(r9)# store left operand pointer
                   17140: #
                   17141: #      COMMON EXIT POINT
                   17142: #
                   17143: expo1: movl    $b$cmt,(r9)     # store type code for cmblk
                   17144:        movl    4*dvtyp(r10),4*cmtyp(r9) # store cmblk node type code
                   17145:        movl    r10,4*cmopn(r9) # store dvptr (=ptr to dac o$xxx)
                   17146:        movl    r6,4*cmlen(r9)  # store cmblk length
                   17147:        movl    r9,(sp)         # store resulting node ptr on stack
                   17148:        jmp     *expop_s        # return to expop caller
                   17149: #
                   17150: #      HERE FOR UNARY OPERATOR
                   17151: #
                   17152: expo2: movl    $4*cmus$,r6     # set size of unary operator cmblk
                   17153:        jsb     alloc           # allocate space for cmblk
                   17154:        movl    (sp)+,4*cmrop(r9)# pop and store operand pointer
                   17155:        movl    (sp),r10        # load operator dv pointer
                   17156:        jmp     expo1           # merge back to exit
                   17157:        #enp                    # end procedure expop
                   17158:        #page   
                   17159: #
                   17160: #      FLSTG -- FOLD STRING TO UPPER CASE
                   17161: #
                   17162: #      FLSTG FOLDS A CHARACTER STRING CONTAINING LOWER CASE
                   17163: #      CHARACCTERS TO ONE CONTAINING UPPER CASE CHARACTERS.
                   17164: #      FOLDING IS ONLY DONE IF &CASE (KVCAS) IS NOT ZERO.
                   17165: #
                   17166: #      (XR)                  STRING ARGUMENT
                   17167: #      (WA)                  LENGTH OF STRING
                   17168: #      JSR  FLSTG            CALL TO FOLD STRING
                   17169: #      (XR)                  RESULT STRING (POSSIBLY ORIGINAL)
                   17170: #      (WC)                  DESTROYED
                   17171: #
                   17172: flstg: #prc                    # entry point
                   17173:        tstl    kvcas           # skip if &case is 0
                   17174:        beqlu   fst99
                   17175:        movl    r10,-(sp)       # save xl across call
                   17176:        movl    r9,-(sp)        # save original scblk ptr
                   17177:        jsb     alocs           # allocate new string block
                   17178:        movl    (sp),r10        # point to original scblk
                   17179:        movl    r9,-(sp)        # save pointer to new scblk
                   17180:        movab   cfp$f(r10),r10  # point to original chars
                   17181:        movab   cfp$f(r9),r9    # point to new chars
                   17182:        clrl    -(sp)           # init did fold flag
                   17183:                                # load loop counter
                   17184: fst01: movzbl  (r10)+,r6       # load character
                   17185:        cmpl    $ch$$a,r6       # skip if less than lc a
                   17186:        bgtru   fst02
                   17187:        cmpl    r6,$ch$$$       # skip if greater than lc z
                   17188:        bgtru   fst02
                   17189:        bicl2   $ch$bl,r6       # fold character to upper case
                   17190:        movl    sp,(sp)         # set did fold character flag
                   17191: fst02: movb    r6,(r9)+        # store (possibly folded) character
                   17192:        sobgtr  r8,fst01        # loop thru entire string
                   17193:        #csc    r9              # complete store characters
                   17194:        tstl    (sp)+           # skip if folding done
                   17195:        bnequ   fst10
                   17196:        movl    (sp)+,dnamp     # do not need new scblk
                   17197:        movl    (sp)+,r9        # return original scblk
                   17198:        jmp     fst20           # merge below
                   17199: fst10: movl    (sp)+,r9        # return new scblk
                   17200:        addl2   $4,sp           # throw away original scblk pointer
                   17201: fst20: movl    4*sclen(r9),r6  # reload string length
                   17202:        movl    (sp)+,r10       # restore xl
                   17203: fst99: rsb                     # return
                   17204:        #enp    
                   17205:        #page   
                   17206: #
                   17207: #      GBCOL -- PERFORM GARBAGE COLLECTION
                   17208: #
                   17209: #      GBCOL PERFORMS A GARBAGE COLLECTION ON THE DYNAMIC REGION
                   17210: #      ALL BLOCKS WHICH ARE NO LONGER IN USE ARE ELIMINATED
                   17211: #      BY MOVING BLOCKS WHICH ARE IN USE DOWN AND RESETTING
                   17212: #      DNAMP, THE POINTER TO THE NEXT AVAILABLE LOCATION.
                   17213: #
                   17214: #      (WB)                  MOVE OFFSET (SEE BELOW)
                   17215: #      JSR  GBCOL            CALL TO COLLECT GARBAGE
                   17216: #      (XR)                  DESTROYED
                   17217: #
                   17218: #      THE FOLLOWING CONDITIONS MUST BE MET AT THE TIME WHEN
                   17219: #      GBCOL IS CALLED.
                   17220: #
                   17221: #      1)   ALL POINTERS TO BLOCKS IN THE DYNAMIC AREA MUST BE
                   17222: #           ACCESSIBLE TO THE GARBAGE COLLECTOR. THIS MEANS
                   17223: #           THAT THEY MUST OCCUR IN ONE OF THE FOLLOWING.
                   17224: #
                   17225: #           A)               MAIN STACK, WITH CURRENT TOP
                   17226: #                            ELEMENT BEING INDICATED BY XS
                   17227: #
                   17228: #           B)               IN RELOCATABLE FIELDS OF VRBLKS.
                   17229: #
                   17230: #           C)               IN REGISTER XL AT THE TIME OF CALL
                   17231: #
                   17232: #           E)               IN THE SPECIAL REGION OF WORKING
                   17233: #                            STORAGE WHERE NAMES BEGIN WITH R$.
                   17234: #
                   17235: #      2)   ALL POINTERS MUST POINT TO THE START OF BLOCKS WITH
                   17236: #           THE SOLE EXCEPTION OF THE CONTENTS OF THE CODE
                   17237: #           POINTER REGISTER WHICH POINTS INTO THE R$COD BLOCK.
                   17238: #
                   17239: #      3)   NO LOCATION WHICH APPEARS TO CONTAIN A POINTER
                   17240: #           INTO THE DYNAMIC REGION MAY OCCUR UNLESS IT IS IN
                   17241: #           FACT A POINTER TO THE START OF THE BLOCK. HOWEVER
                   17242: #           POINTERS OUTSIDE THIS AREA MAY OCCUR AND WILL
                   17243: #           NOT BE CHANGED BY THE GARBAGE COLLECTOR.
                   17244: #           IT IS ESPECIALLY IMPORTANT TO MAKE SURE THAT XL
                   17245: #           DOES NOT CONTAIN A GARBAGE VALUE FROM SOME PROCESS
                   17246: #           CARRIED OUT BEFORE THE CALL TO THE COLLECTOR.
                   17247: #
                   17248: #      GBCOL HAS THE CAPABILITY OF MOVING THE FINAL COMPACTED
                   17249: #      RESULT UP IN MEMORY (WITH ADDRESSES ADJUSTED ACCORDINGLY)
                   17250: #      THIS IS USED TO ADD SPACE TO THE STATIC REGION. THE
                   17251: #      ENTRY VALUE OF WB IS THE NUMBER OF BYTES TO MOVE UP.
                   17252: #      THE CALLER MUST GUARANTEE THAT THERE IS ENOUGH ROOM.
                   17253: #      FURTHERMORE THE VALUE IN WB IF IT IS NON-ZERO, MUST BE AT
                   17254: #      LEAST 256 SO THAT THE MWB INSTRUCTION CONDITIONS ARE MET.
                   17255:        #page   
                   17256: #
                   17257: #      GBCOL (CONTINUED)
                   17258: #
                   17259: #      THE ALGORITHM, WHICH IS A MODIFICATION OF THE LISP-2
                   17260: #      GARBAGE COLLECTOR DEVISED BY R.DEWAR AND K.BELCHER
                   17261: #      TAKES THREE PASSES AS FOLLOWS.
                   17262: #
                   17263: #      1)   ALL POINTERS IN MEMORY ARE SCANNED AND BLOCKS IN USE
                   17264: #           DETERMINED FROM THIS SCAN. NOTE THAT THIS PROCEDURE
                   17265: #           IS RECURSIVE AND USES THE MAIN STACK FOR LINKAGE.
                   17266: #           THE MARKING PROCESS IS THUS SIMILAR TO THAT USED IN
                   17267: #           A STANDARD LISP COLLECTOR. HOWEVER THE METHOD OF
                   17268: #           ACTUALLY MARKING THE BLOCKS IS DIFFERENT.
                   17269: #
                   17270: #           THE FIRST FIELD OF A BLOCK NORMALLY CONTAINS A
                   17271: #           CODE ENTRY POINT POINTER. SUCH AN ENTRY POINTER
                   17272: #           CAN BE DISTINGUISHED FROM THE ADDRESS OF ANY POINTER
                   17273: #           TO BE PROCESSED BY THE COLLECTOR. DURING GARBAGE
                   17274: #           COLLECTION, THIS WORD IS USED TO BUILD A BACK CHAIN
                   17275: #           OF POINTERS THROUGH FIELDS WHICH POINT TO THE BLOCK.
                   17276: #           THE END OF THE CHAIN IS MARKED BY THE OCCURENCE
                   17277: #           OF THE WORD WHICH USED TO BE IN THE FIRST WORD OF
                   17278: #           THE BLOCK. THIS BACKCHAIN SERVES BOTH AS A MARK
                   17279: #           INDICATING THAT THE BLOCK IS IN USE AND AS A LIST OF
                   17280: #           REFERENCES FOR THE RELOCATION PHASE.
                   17281: #
                   17282: #      2)   STORAGE IS SCANNED SEQUENTIALLY TO DISCOVER WHICH
                   17283: #           BLOCKS ARE CURRENTLY IN USE AS INDICATED BY THE
                   17284: #           PRESENCE OF A BACKCHAIN. TWO POINTERS ARE MAINTAINED
                   17285: #           ONE SCANS THROUGH LOOKING AT EACH BLOCK. THE OTHER
                   17286: #           IS INCREMENTED ONLY FOR BLOCKS FOUND TO BE IN USE.
                   17287: #           IN THIS WAY, THE EVENTUAL LOCATION OF EACH BLOCK CAN
                   17288: #           BE DETERMINED WITHOUT ACTUALLY MOVING ANY BLOCKS.
                   17289: #           AS EACH BLOCK WHICH IS IN USE IS PROCESSED, THE BACK
                   17290: #           CHAIN IS USED TO RESET ALL POINTERS WHICH POINT TO
                   17291: #           THIS BLOCK TO CONTAIN ITS NEW ADDRESS, I.E. THE
                   17292: #           ADDRESS IT WILL OCCUPY AFTER THE BLOCKS ARE MOVED.
                   17293: #           THE FIRST WORD OF THE BLOCK, TAKEN FROM THE END OF
                   17294: #           THE CHAIN IS RESTORED AT THIS POINT.
                   17295: #
                   17296: #           DURING PASS 2, THE COLLECTOR BUILDS BLOCKS WHICH
                   17297: #           DESCRIBE THE REGIONS OF STORAGE WHICH ARE TO BE
                   17298: #           MOVED IN THE THIRD PASS. THERE IS ONE DESCRIPTOR FOR
                   17299: #           EACH CONTIGUOUS SET OF GOOD BLOCKS. THE DESCRIPTOR
                   17300: #           IS BUILT JUST BEHIND THE BLOCK TO BE MOVED AND
                   17301: #           CONTAINS A POINTER TO THE NEXT BLOCK AND THE NUMBER
                   17302: #           OF WORDS TO BE MOVED.
                   17303: #
                   17304: #      3)   IN THE THIRD AND FINAL PASS, THE MOVE DESCRIPTOR
                   17305: #           BLOCKS BUILT IN PASS TWO ARE USED TO ACTUALLY MOVE
                   17306: #           THE BLOCKS DOWN TO THE BOTTOM OF THE DYNAMIC REGION.
                   17307: #           THE COLLECTION IS THEN COMPLETE AND THE NEXT
                   17308: #           AVAILABLE LOCATION POINTER IS RESET.
                   17309:        #page   
                   17310: #
                   17311: #      GBCOL (CONTINUED)
                   17312: #
                   17313: gbcol: #prc                    # entry point
                   17314:        tstl    dmvch           # fail if in mid-dump
                   17315:        beqlu   0f
                   17316:        jmp     gbc14
                   17317: 0:             
                   17318:        movl    sp,gbcfl        # note gbcol entered
                   17319:        movl    r6,gbsva        # save entry wa
                   17320:        movl    r7,gbsvb        # save entry wb
                   17321:        movl    r8,gbsvc        # save entry wc
                   17322:        movl    r10,-(sp)       # save entry xl
                   17323:        movl    r3,r6           # get code pointer value
                   17324:        subl2   r$cod,r6        # make relative
                   17325:        movl    r6,r3           # and restore
                   17326: #
                   17327: #      PROCESS STACK ENTRIES
                   17328: #
                   17329:        movl    sp,r9           # point to stack front
                   17330:        movl    stbas,r10       # point past end of stack
                   17331:        cmpl    r10,r9          # ok if d-stack
                   17332:        bgequ   gbc00
                   17333:        movl    r10,r9          # reverse if ...
                   17334:        movl    sp,r10          # ... u-stack
                   17335: #
                   17336: #      PROCESS THE STACK
                   17337: #
                   17338: gbc00: jsb     gbcpf           # process pointers on stack
                   17339: #
                   17340: #      PROCESS SPECIAL WORK LOCATIONS
                   17341: #
                   17342:        movl    $r$aaa,r9       # point to start of relocatable locs
                   17343:        movl    $r$yyy,r10      # point past end of relocatable locs
                   17344:        jsb     gbcpf           # process work fields
                   17345: #
                   17346: #      PREPARE TO PROCESS VARIABLE BLOCKS
                   17347: #
                   17348:        movl    hshtb,r6        # point to first hash slot pointer
                   17349: #
                   17350: #      LOOP THROUGH HASH SLOTS
                   17351: #
                   17352: gbc01: movl    r6,r10          # point to next slot
                   17353:        addl2   $4,r6           # bump bucket pointer
                   17354:        movl    r6,gbcnm        # save bucket pointer
                   17355:        #page   
                   17356: #
                   17357: #      GBCOL (CONTINUED)
                   17358: #
                   17359: #      LOOP THROUGH VARIABLES ON ONE HASH CHAIN
                   17360: #
                   17361: gbc02: movl    (r10),r9        # load ptr to next vrblk
                   17362:        beqlu   gbc03           # jump if end of chain
                   17363:        movl    r9,r10          # else copy vrblk pointer
                   17364:        addl2   $4*vrval,r9     # point to first reloc fld
                   17365:        addl2   $4*vrnxt,r10    # point past last (and to link ptr)
                   17366:        jsb     gbcpf           # process reloc fields in vrblk
                   17367:        jmp     gbc02           # loop back for next block
                   17368: #
                   17369: #      HERE AT END OF ONE HASH CHAIN
                   17370: #
                   17371: gbc03: movl    gbcnm,r6        # restore bucket pointer
                   17372:        cmpl    r6,hshte        # loop back if more buckets to go
                   17373:        bnequ   gbc01
                   17374:        #page   
                   17375: #
                   17376: #      GBCOL (CONTINUED)
                   17377: #
                   17378: #      NOW WE ARE READY TO START PASS TWO. REGISTERS ARE USED
                   17379: #      AS FOLLOWS IN PASS TWO.
                   17380: #
                   17381: #      (XR)                  SCANS THROUGH ALL BLOCKS
                   17382: #      (WC)                  POINTER TO EVENTUAL LOCATION
                   17383: #
                   17384: #      THE MOVE DESCRIPTION BLOCKS BUILT IN THIS PASS HAVE
                   17385: #      THE FOLLOWING FORMAT.
                   17386: #
                   17387: #      WORD 1                POINTER TO NEXT MOVE BLOCK,
                   17388: #                            ZERO IF END OF CHAIN OF BLOCKS
                   17389: #
                   17390: #      WORD 2                LENGTH OF BLOCKS TO BE MOVED IN
                   17391: #                            BYTES. SET TO THE ADDRESS OF THE
                   17392: #                            FIRST BYTE WHILE ACTUALLY SCANNING
                   17393: #                            THE BLOCKS.
                   17394: #
                   17395: #      THE FIRST ENTRY ON THIS CHAIN IS A SPECIAL ENTRY
                   17396: #      CONSISTING OF THE TWO WORDS GBCNM AND GBCNS. AFTER
                   17397: #      BUILDING THE CHAIN OF MOVE DESCRIPTORS, GBCNM POINTS TO
                   17398: #      THE FIRST REAL MOVE BLOCK, AND GBCNS IS THE LENGTH OF
                   17399: #      BLOCKS IN USE AT THE START OF STORAGE WHICH NEED NOT
                   17400: #      BE MOVED SINCE THEY ARE IN THE CORRECT POSITION.
                   17401: #
                   17402: gbc04: movl    dnamb,r9        # point to first block
                   17403:        movl    r9,r8           # set as first eventual location
                   17404:        addl2   gbsvb,r8        # add offset for eventual move up
                   17405:        clrl    gbcnm           # clear initial forward pointer
                   17406:        movl    $gbcnm,gbclm    # initialize ptr to last move block
                   17407:        movl    r9,gbcns        # initialize first address
                   17408: #
                   17409: #      LOOP THROUGH A SERIES OF BLOCKS IN USE
                   17410: #
                   17411: gbc05: cmpl    r9,dnamp        # jump if end of used region
                   17412:        beqlu   gbc07
                   17413:        movl    (r9),r6         # else get first word
                   17414:        cmpl    r6,$p$yyy       # skip if not entry ptr (in use)
                   17415:        bgequ   gbc06
                   17416:        cmpl    r6,$b$aaa       # jump if entry pointer (unused)
                   17417:        bgequ   gbc07
                   17418: #
                   17419: #      HERE FOR BLOCK IN USE, LOOP TO RELOCATE REFERENCES
                   17420: #
                   17421: gbc06: movl    r6,r10          # copy pointer
                   17422:        movl    (r10),r6        # load forward pointer
                   17423:        movl    r8,(r10)        # relocate reference
                   17424:        cmpl    r6,$p$yyy       # loop back if not end of chain
                   17425:        bgequ   gbc06
                   17426:        cmpl    r6,$b$aaa       # loop back if not end of chain
                   17427:        blequ   gbc06
                   17428:        #page   
                   17429: #
                   17430: #      GBCOL (CONTINUED)
                   17431: #
                   17432: #      AT END OF CHAIN, RESTORE FIRST WORD AND BUMP PAST
                   17433: #
                   17434:        movl    r6,(r9)         # restore first word
                   17435:        jsb     blkln           # get length of this block
                   17436:        addl2   r6,r9           # bump actual pointer
                   17437:        addl2   r6,r8           # bump eventual pointer
                   17438:        jmp     gbc05           # loop back for next block
                   17439: #
                   17440: #      HERE AT END OF A SERIES OF BLOCKS IN USE
                   17441: #
                   17442: gbc07: movl    r9,r6           # copy pointer past last block
                   17443:        movl    gbclm,r10       # point to previous move block
                   17444:        subl2   4*1(r10),r6     # subtract starting address
                   17445:        movl    r6,4*1(r10)     # store length of block to be moved
                   17446: #
                   17447: #      LOOP THROUGH A SERIES OF BLOCKS NOT IN USE
                   17448: #
                   17449: gbc08: cmpl    r9,dnamp        # jump if end of used region
                   17450:        beqlu   gbc10
                   17451:        movl    (r9),r6         # else load first word of next block
                   17452:        cmpl    r6,$p$yyy       # jump if in use
                   17453:        bgequ   gbc09
                   17454:        cmpl    r6,$b$aaa       # jump if in use
                   17455:        blequ   gbc09
                   17456:        jsb     blkln           # else get length of next block
                   17457:        addl2   r6,r9           # push pointer
                   17458:        jmp     gbc08           # and loop back
                   17459: #
                   17460: #      HERE FOR A BLOCK IN USE AFTER PROCESSING A SERIES OF
                   17461: #      BLOCKS WHICH WERE NOT IN USE, BUILD NEW MOVE BLOCK.
                   17462: #
                   17463: gbc09: subl2   $4*num02,r9     # point 2 words behind for move block
                   17464:        movl    gbclm,r10       # point to previous move block
                   17465:        movl    r9,(r10)        # set forward ptr in previous block
                   17466:        clrl    (r9)            # zero forward ptr of new block
                   17467:        movl    r9,gbclm        # remember address of this block
                   17468:        movl    r9,r10          # copy ptr to move block
                   17469:        addl2   $4*num02,r9     # point back to block in use
                   17470:        movl    r9,4*1(r10)     # store starting address
                   17471:        jmp     gbc06           # jump to process block in use
                   17472:        #page   
                   17473: #
                   17474: #      GBCOL (CONTINUED)
                   17475: #
                   17476: #      HERE FOR PASS THREE -- ACTUALLY MOVE THE BLOCKS DOWN
                   17477: #
                   17478: #      (XL)                  POINTER TO OLD LOCATION
                   17479: #      (XR)                  POINTER TO NEW LOCATION
                   17480: #
                   17481: gbc10: movl    dnamb,r9        # point to start of storage
                   17482:        addl2   gbcns,r9        # bump past unmoved blocks at start
                   17483: #
                   17484: #      LOOP THROUGH MOVE DESCRIPTORS
                   17485: #
                   17486: gbc11: movl    gbcnm,r10       # point to next move block
                   17487:        beqlu   gbc12           # jump if end of chain
                   17488:        movl    (r10)+,gbcnm    # move pointer down chain
                   17489:        movl    (r10)+,r6       # get length to move
                   17490:        jsb     sbmvw           # perform move
                   17491:        jmp     gbc11           # loop back
                   17492: #
                   17493: #      NOW TEST FOR MOVE UP
                   17494: #
                   17495: gbc12: movl    r9,dnamp        # set next available loc ptr
                   17496:        movl    gbsvb,r7        # reload move offset
                   17497:        beqlu   gbc13           # jump if no move required
                   17498:        movl    r9,r10          # else copy old top of core
                   17499:        addl2   r7,r9           # point to new top of core
                   17500:        movl    r9,dnamp        # save new top of core pointer
                   17501:        movl    r10,r6          # copy old top
                   17502:        subl2   dnamb,r6        # minus old bottom = length
                   17503:        addl2   r7,dnamb        # bump bottom to get new value
                   17504:        jsb     sbmwb           # perform move (backwards)
                   17505: #
                   17506: #      MERGE HERE TO EXIT
                   17507: #
                   17508: gbc13: movl    gbsva,r6        # restore wa
                   17509:        movl    r3,r8           # get code pointer
                   17510:        addl2   r$cod,r8        # make absolute again
                   17511:        movl    r8,r3           # and replace absolute value
                   17512:        movl    gbsvc,r8        # restore wc
                   17513:        movl    (sp)+,r10       # restore entry xl
                   17514:        incl    gbcnt           # increment count of collections
                   17515:        clrl    r9              # clear garbage value in xr
                   17516:        clrl    gbcfl           # note exit from gbcol
                   17517:        rsb                     # exit to gbcol caller
                   17518: #
                   17519: #      GARBAGE COLLECTION NOT ALLOWED WHILST DUMPING
                   17520: #
                   17521: gbc14: incl    errft           # fatal error
                   17522:        jmp     er_250          # insufficient memory to complete dump
                   17523:        #enp                    # end procedure gbcol
                   17524:        #page   
                   17525: #
                   17526: #      GBCPF -- PROCESS FIELDS FOR GARBAGE COLLECTOR
                   17527: #
                   17528: #      THIS PROCEDURE IS USED BY THE GARBAGE COLLECTOR TO
                   17529: #      PROCESS FIELDS IN PASS ONE. SEE GBCOL FOR FULL DETAILS.
                   17530: #
                   17531: #      (XR)                  PTR TO FIRST LOCATION TO PROCESS
                   17532: #      (XL)                  PTR PAST LAST LOCATION TO PROCESS
                   17533: #      JSR  GBCPF            CALL TO PROCESS FIELDS
                   17534: #      (XR,WA,WB,WC,IA)      DESTROYED
                   17535: #
                   17536: #      NOTE THAT ALTHOUGH THIS PROCEDURE USES A RECURSIVE
                   17537: #      APPROACH, IT CONTROLS ITS OWN STACK AND IS NOT RECURSIVE.
                   17538: #
                   17539: gbcpf: #prc                    # entry point
                   17540:        clrl    -(sp)           # set zero to mark bottom of stack
                   17541:        movl    r10,-(sp)       # save end pointer
                   17542: #
                   17543: #      MERGE HERE TO GO DOWN A LEVEL AND START A NEW LOOP
                   17544: #
                   17545: #      1(XS)                 NEXT LVL FIELD PTR (0 AT OUTER LVL)
                   17546: #      0(XS)                 PTR PAST LAST FIELD TO PROCESS
                   17547: #      (XR)                  PTR TO FIRST FIELD TO PROCESS
                   17548: #
                   17549: #      LOOP TO PROCESS SUCCESSIVE FIELDS
                   17550: #
                   17551: gpf01: movl    (r9),r10        # load field contents
                   17552:        movl    r9,r8           # save field pointer
                   17553:        cmpl    r10,dnamb       # jump if not ptr into dynamic area
                   17554:        blssu   gpf02
                   17555:        cmpl    r10,dnamp       # jump if not ptr into dynamic area
                   17556:        bgequ   gpf02
                   17557: #
                   17558: #      HERE WE HAVE A PTR TO A BLOCK IN THE DYNAMIC AREA.
                   17559: #      LINK THIS FIELD ONTO THE REFERENCE BACKCHAIN.
                   17560: #
                   17561:        movl    (r10),r6        # load ptr to chain (or entry ptr)
                   17562:        movl    r9,(r10)        # set this field as new head of chain
                   17563:        movl    r6,(r9)         # set forward pointer
                   17564: #
                   17565: #      NOW SEE IF THIS BLOCK HAS BEEN PROCESSED BEFORE
                   17566: #
                   17567:        cmpl    r6,$p$yyy       # jump if already processed
                   17568:        bgequ   gpf02
                   17569:        cmpl    r6,$b$aaa       # jump if not already processed
                   17570:        bgequ   gpf03
                   17571: #
                   17572: #      HERE TO MOVE TO NEXT FIELD
                   17573: #
                   17574: gpf02: movl    r8,r9           # restore field pointer
                   17575:        addl2   $4,r9           # bump to next field
                   17576:        cmpl    r9,(sp)         # loop back if more to go
                   17577:        bnequ   gpf01
                   17578:        #page   
                   17579: #
                   17580: #      GBCPF (CONTINUED)
                   17581: #
                   17582: #      HERE WE POP UP A LEVEL AFTER FINISHING A BLOCK
                   17583: #
                   17584:        movl    (sp)+,r10       # restore pointer past end
                   17585:        movl    (sp)+,r8        # restore block pointer
                   17586:        bnequ   gpf02           # continue loop unless outer levl
                   17587:        rsb                     # return to caller if outer level
                   17588: #
                   17589: #      HERE TO PROCESS AN ACTIVE BLOCK WHICH HAS NOT BEEN DONE
                   17590: #
                   17591: gpf03: movl    r10,r9          # copy block pointer
                   17592:        movl    r6,r10          # copy first word of block
                   17593:        movzwl  -2(r10),r10     # load entry point id (bl$xx)
                   17594: #
                   17595: #      BLOCK TYPE SWITCH. NOTE THAT BLOCKS WITH NO RELOCATABLE
                   17596: #      FIELDS JUST RETURN TO GPF02 HERE TO CONTINE TO NEXT FLD.
                   17597: #
                   17598:        casel   r10,$0,$bl$$$   # switch on block type
                   17599: 5:             
                   17600:        .word   gpf06-5b        # arblk
                   17601:        .word   gpf18-5b        # bcblk
                   17602:        .word   gpf08-5b        # cdblk
                   17603:        .word   gpf17-5b        # exblk
                   17604:        .word   gpf02-5b        # icblk
                   17605:        .word   gpf10-5b        # nmblk
                   17606:        .word   gpf10-5b        # p0blk
                   17607:        .word   gpf12-5b        # p1blk
                   17608:        .word   gpf12-5b        # p2blk
                   17609:        .word   gpf02-5b        # rcblk
                   17610:        .word   gpf02-5b        # scblk
                   17611:        .word   gpf02-5b        # seblk
                   17612:        .word   gpf08-5b        # tbblk
                   17613:        .word   gpf08-5b        # vcblk
                   17614:        .word   gpf02-5b        # xnblk
                   17615:        .word   gpf09-5b        # xrblk
                   17616:        .word   gpf13-5b        # pdblk
                   17617:        .word   gpf16-5b        # trblk
                   17618:        .word   gpf02-5b        # bfblk
                   17619:        .word   gpf07-5b        # ccblk
                   17620:        .word   gpf04-5b        # cmblk
                   17621:        .word   gpf02-5b        # ctblk
                   17622:        .word   gpf02-5b        # dfblk
                   17623:        .word   gpf02-5b        # efblk
                   17624:        .word   gpf10-5b        # evblk
                   17625:        .word   gpf11-5b        # ffblk
                   17626:        .word   gpf02-5b        # kvblk
                   17627:        .word   gpf14-5b        # pfblk
                   17628:        .word   gpf15-5b        # teblk
                   17629:        #esw                    # end of jump table
                   17630:        #page   
                   17631: #
                   17632: #      GBCPF (CONTINUED)
                   17633: #
                   17634: #      CMBLK
                   17635: #
                   17636: gpf04: movl    4*cmlen(r9),r6  # load length
                   17637:        movl    $4*cmtyp,r7     # set offset
                   17638: #
                   17639: #      HERE TO PUSH DOWN TO NEW LEVEL
                   17640: #
                   17641: #      (WC)                  FIELD PTR AT PREVIOUS LEVEL
                   17642: #      (XR)                  PTR TO NEW BLOCK
                   17643: #      (WA)                  LENGTH (RELOC FLDS + FLDS AT START)
                   17644: #      (WB)                  OFFSET TO FIRST RELOC FIELD
                   17645: #
                   17646: gpf05: addl2   r9,r6           # point past last reloc field
                   17647:        addl2   r7,r9           # point to first reloc field
                   17648:        movl    r8,-(sp)        # stack old field pointer
                   17649:        movl    r6,-(sp)        # stack new limit pointer
                   17650:        jsb     sbchk           # check for stack overflow
                   17651:        jmp     gpf01           # if ok, back to process
                   17652: #
                   17653: #      ARBLK
                   17654: #
                   17655: gpf06: movl    4*arlen(r9),r6  # load length
                   17656:        movl    4*arofs(r9),r7  # set offset to 1st reloc fld (arpro)
                   17657:        jmp     gpf05           # all set
                   17658: #
                   17659: #      CCBLK
                   17660: #
                   17661: gpf07: movl    4*ccuse(r9),r6  # set length in use
                   17662:        movl    $4*ccuse,r7     # 1st word (make sure at least one)
                   17663:        jmp     gpf05           # all set
                   17664:        #page   
                   17665: #
                   17666: #      GBCPF (CONTINUED)
                   17667: #
                   17668: #      CDBLK, TBBLK, VCBLK
                   17669: #
                   17670: gpf08: movl    4*offs2(r9),r6  # load length
                   17671:        movl    $4*offs3,r7     # set offset
                   17672:        jmp     gpf05           # jump back
                   17673: #
                   17674: #      XRBLK
                   17675: #
                   17676: gpf09: movl    4*xrlen(r9),r6  # load length
                   17677:        movl    $4*xrptr,r7     # set offset
                   17678:        jmp     gpf05           # jump back
                   17679: #
                   17680: #      EVBLK, NMBLK, P0BLK
                   17681: #
                   17682: gpf10: movl    $4*offs2,r6     # point past second field
                   17683:        movl    $4*offs1,r7     # offset is one (only reloc fld is 2)
                   17684:        jmp     gpf05           # all set
                   17685: #
                   17686: #      FFBLK
                   17687: #
                   17688: gpf11: movl    $4*ffofs,r6     # set length
                   17689:        movl    $4*ffnxt,r7     # set offset
                   17690:        jmp     gpf05           # all set
                   17691: #
                   17692: #      P1BLK, P2BLK
                   17693: #
                   17694: gpf12: movl    $4*parm2,r6     # length (parm2 is non-relocatable)
                   17695:        movl    $4*pthen,r7     # set offset
                   17696:        jmp     gpf05           # all set
                   17697:        #page   
                   17698: #
                   17699: #      GBCPF (CONTINUED)
                   17700: #
                   17701: #      PDBLK
                   17702: #
                   17703: gpf13: movl    4*pddfp(r9),r10 # load ptr to dfblk
                   17704:        movl    4*dfpdl(r10),r6 # get pdblk length
                   17705:        movl    $4*pdfld,r7     # set offset
                   17706:        jmp     gpf05           # all set
                   17707: #
                   17708: #      PFBLK
                   17709: #
                   17710: gpf14: movl    $4*pfarg,r6     # length past last reloc
                   17711:        movl    $4*pfcod,r7     # offset to first reloc
                   17712:        jmp     gpf05           # all set
                   17713: #
                   17714: #      TEBLK
                   17715: #
                   17716: gpf15: movl    $4*tesi$,r6     # set length
                   17717:        movl    $4*tesub,r7     # and offset
                   17718:        jmp     gpf05           # all set
                   17719: #
                   17720: #      TRBLK
                   17721: #
                   17722: gpf16: movl    $4*trsi$,r6     # set length
                   17723:        movl    $4*trval,r7     # and offset
                   17724:        jmp     gpf05           # all set
                   17725: #
                   17726: #      EXBLK
                   17727: #
                   17728: gpf17: movl    4*exlen(r9),r6  # load length
                   17729:        movl    $4*exflc,r7     # set offset
                   17730:        jmp     gpf05           # jump back
                   17731: #
                   17732: #      BCBLK
                   17733: #
                   17734: gpf18: movl    $4*bcsi$,r6     # set length
                   17735:        movl    $4*bcbuf,r7     # and offset
                   17736:        jmp     gpf05           # all set
                   17737:        #enp                    # end procedure gbcpf
                   17738:        #page   
                   17739: #
                   17740: #      GTARR -- GET ARRAY
                   17741: #
                   17742: #      GTARR IS PASSED AN OBJECT AND RETURNS AN ARRAY IF POSSIBL
                   17743: #
                   17744: #      (XR)                  VALUE TO BE CONVERTED
                   17745: #      JSR  GTARR            CALL TO GET ARRAY
                   17746: #      PPM  LOC              TRANSFER LOC FOR CONVERT IMPOSSIBLE
                   17747: #      (XR)                  RESULTING ARRAY
                   17748: #      (XL,WA,WB,WC)         DESTROYED
                   17749: #
                   17750: gtarr: #prc                    # entry point
                   17751:        movl    (r9),r6         # load type word
                   17752:        cmpl    r6,$b$art       # exit if already an array
                   17753:        bnequ   0f
                   17754:        jmp     gtar8
                   17755: 0:             
                   17756:        cmpl    r6,$b$vct       # exit if already an array
                   17757:        bnequ   0f
                   17758:        jmp     gtar8
                   17759: 0:             
                   17760:        cmpl    r6,$b$tbt       # else fail if not a table (sgd02)
                   17761:        beqlu   0f
                   17762:        jmp     gta9a
                   17763: 0:             
                   17764: #
                   17765: #      HERE WE CONVERT A TABLE TO AN ARRAY
                   17766: #
                   17767:        movl    r9,-(sp)        # replace tbblk pointer on stack
                   17768:        clrl    r9              # signal first pass
                   17769:        clrl    r7              # zero non-null element count
                   17770: #
                   17771: #      THE FOLLOWING CODE IS EXECUTED TWICE. ON THE FIRST PASS,
                   17772: #      SIGNALLED BY XR=0, THE NUMBER OF NON-NULL ELEMENTS IN
                   17773: #      THE TABLE IS COUNTED IN WB. IN THE SECOND PASS, WHERE
                   17774: #      XR IS A POINTER INTO THE ARBLK, THE NAME AND VALUE ARE
                   17775: #      ENTERED INTO THE CURRENT ARBLK LOCATION.
                   17776: #
                   17777: gtar1: movl    (sp),r10        # point to table
                   17778:        addl2   4*tblen(r10),r10# point past last bucket
                   17779:        subl2   $4*tbbuk,r10    # set first bucket offset
                   17780:        movl    r10,r6          # copy adjusted pointer
                   17781: #
                   17782: #      LOOP THROUGH BUCKETS IN TABLE BLOCK
                   17783: #      NEXT THREE LINES OF CODE RELY ON TENXT HAVING A VALUE
                   17784: #      1 LESS THAN TBBUK.
                   17785: #
                   17786: gtar2: movl    r6,r10          # copy bucket pointer
                   17787:        subl2   $4,r6           # decrement bucket pointer
                   17788: #
                   17789: #      LOOP THROUGH TEBLKS ON ONE BUCKET CHAIN
                   17790: #
                   17791: gtar3: movl    4*tenxt(r10),r10# point to next teblk
                   17792:        cmpl    r10,(sp)        # jump if chain end (tbblk ptr)
                   17793:        beqlu   gtar6
                   17794:        movl    r10,cnvtp       # else save teblk pointer
                   17795: #
                   17796: #      LOOP TO FIND VALUE DOWN TRBLK CHAIN
                   17797: #
                   17798: gtar4: movl    4*teval(r10),r10# load value
                   17799:        cmpl    (r10),$b$trt    # loop till value found
                   17800:        beqlu   gtar4
                   17801:        movl    r10,r8          # copy value
                   17802:        movl    cnvtp,r10       # restore teblk pointer
                   17803:        #page   
                   17804: #
                   17805: #      GTARR (CONTINUED)
                   17806: #
                   17807: #      NOW CHECK FOR NULL AND TEST CASES
                   17808: #
                   17809:        cmpl    r8,$nulls       # loop back to ignore null value
                   17810:        beqlu   gtar3
                   17811:        tstl    r9              # jump if second pass
                   17812:        bnequ   gtar5
                   17813:        incl    r7              # for the first pass, bump count
                   17814:        jmp     gtar3           # and loop back for next teblk
                   17815: #
                   17816: #      HERE IN SECOND PASS
                   17817: #
                   17818: gtar5: movl    4*tesub(r10),(r9)+ # store subscript name
                   17819:        movl    r8,(r9)+        # store value in arblk
                   17820:        jmp     gtar3           # loop back for next teblk
                   17821: #
                   17822: #      HERE AFTER SCANNING TEBLKS ON ONE CHAIN
                   17823: #
                   17824: gtar6: cmpl    r6,(sp)         # loop back if more buckets to go
                   17825:        bnequ   gtar2
                   17826:        tstl    r9              # else jump if second pass
                   17827:        bnequ   gtar7
                   17828: #
                   17829: #      HERE AFTER COUNTING NON-NULL ELEMENTS
                   17830: #
                   17831:        tstl    r7              # fail if no non-null elements
                   17832:        bnequ   0f
                   17833:        jmp     gtar9
                   17834: 0:             
                   17835:        movl    r7,r6           # else copy count
                   17836:        addl2   r7,r6           # double (two words/element)
                   17837:        addl2   $arvl2,r6       # add space for standard fields
                   17838:        moval   0[r6],r6        # convert length to bytes
                   17839:        cmpl    r6,mxlen        # fail if too long for array
                   17840:        blssu   0f
                   17841:        jmp     gtar9
                   17842: 0:             
                   17843:        jsb     alloc           # else allocate space for arblk
                   17844:        movl    $b$art,(r9)     # store type word
                   17845:        clrl    4*idval(r9)     # zero id for the moment
                   17846:        movl    r6,4*arlen(r9)  # store length
                   17847:        movl    $num02,4*arndm(r9) # set dimensions = 2
                   17848:        movl    intv1,r5        # get integer one
                   17849:        movl    r5,4*arlbd(r9)  # store as lbd 1
                   17850:        movl    r5,4*arlb2(r9)  # store as lbd 2
                   17851:        movl    intv2,r5        # load integer two
                   17852:        movl    r5,4*ardm2(r9)  # store as dim 2
                   17853:        movl    r7,r5           # get element count as integer
                   17854:        movl    r5,4*ardim(r9)  # store as dim 1
                   17855:        clrl    4*arpr2(r9)     # zero prototype field for now
                   17856:        movl    $4*arpr2,4*arofs(r9) # set offset field (signal pass 2)
                   17857:        movl    r9,r7           # save arblk pointer
                   17858:        addl2   $4*arvl2,r9     # point to first element location
                   17859:        jmp     gtar1           # jump back to fill in elements
                   17860:        #page   
                   17861: #
                   17862: #      GTARR (CONTINUED)
                   17863: #
                   17864: #      HERE AFTER FILLING IN ELEMENT VALUES
                   17865: #
                   17866: gtar7: movl    r7,r9           # restore arblk pointer
                   17867:        movl    r7,(sp)         # store as result
                   17868: #
                   17869: #      NOW WE NEED THE ARRAY PROTOTYPE WHICH IS OF THE FORM NN,2
                   17870: #      THIS IS OBTAINED BY BUILDING THE STRING FOR NN02 AND
                   17871: #      CHANGING THE ZERO TO A COMMA BEFORE STORING IT.
                   17872: #
                   17873:        movl    4*ardim(r9),r5  # get number of elements (nn)
                   17874:        mull2   intvh,r5        # multiply by 100
                   17875:        addl2   intv2,r5        # add 2 (nn02)
                   17876:        jsb     icbld           # build integer
                   17877:        movl    r9,-(sp)        # store ptr for gtstg
                   17878:        jsb     gtstg           # convert to string
                   17879:        .long   invalid$        # convert fail is impossible
                   17880:        movl    r9,r10          # copy string pointer
                   17881:        movl    (sp)+,r9        # reload arblk pointer
                   17882:        movl    r10,4*arpr2(r9) # store prototype ptr (nn02)
                   17883:        subl2   $num02,r6       # adjust length to point to zero
                   17884:        movab   cfp$f(r10)[r6],r10 # point to zero
                   17885:        movl    $ch$cm,r7       # load a comma
                   17886:        movb    r7,(r10)        # store a comma over the zero
                   17887:        #csc    r10             # complete store characters
                   17888: #
                   17889: #      NORMAL RETURN
                   17890: #
                   17891: gtar8: addl2   $4*1,(sp)       # return to caller
                   17892:        rsb     
                   17893: #
                   17894: #      NON-CONVERSION RETURN
                   17895: #
                   17896: gtar9: movl    (sp)+,r9        # restore stack for conv err (sgd02)
                   17897: #
                   17898: #      MERGE TO TAKE CONVERT ERROR WHEN STACK ADJUSTED OK
                   17899: #
                   17900: gta9a: movl    (sp)+,r11       # return
                   17901:        jmp     *(r11)+
                   17902:        #enp                    # procedure gtarr
                   17903:        #page   
                   17904: #
                   17905: #      GTCOD -- CONVERT TO CODE
                   17906: #
                   17907: #      (XR)                  OBJECT TO BE CONVERTED
                   17908: #      JSR  GTCOD            CALL TO CONVERT TO CODE
                   17909: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   17910: #      (XR)                  POINTER TO RESULTING CDBLK
                   17911: #      (XL,WA,WB,WC,RA)      DESTROYED
                   17912: #
                   17913: #      IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE-
                   17914: #      EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   17915: #      WITHOUT RETURNING TO THIS ROUTINE.
                   17916: #
                   17917: gtcod: #prc                    # entry point
                   17918:        cmpl    (r9),$b$cds     # jump if already code
                   17919:        beqlu   gtcd1
                   17920:        cmpl    (r9),$b$cdc     # jump if already code
                   17921:        beqlu   gtcd1
                   17922: #
                   17923: #      HERE WE MUST GENERATE A CDBLK BY COMPILATION
                   17924: #
                   17925:        movl    r9,-(sp)        # stack argument for gtstg
                   17926:        jsb     gtstg           # convert argument to string
                   17927:        .long   gtcd2           # jump if non-convertible
                   17928:        movl    flptr,gtcef     # save fail ptr in case of error
                   17929:        movl    r$cod,r$gtc     # also save code ptr
                   17930:        movl    r9,r$cim        # else set image pointer
                   17931:        movl    r6,scnil        # set image length
                   17932:        clrl    scnpt           # set scan pointer
                   17933:        movl    $stgxc,stage    # set stage for execute compile
                   17934:        movl    cmpsn,lstsn     # in case listr called
                   17935:        jsb     cmpil           # compile string
                   17936:        movl    $stgxt,stage    # reset stage for execute time
                   17937:        clrl    r$cim           # clear image
                   17938: #
                   17939: #      MERGE HERE IF NO CONVERT REQUIRED
                   17940: #
                   17941: gtcd1: addl2   $4*1,(sp)       # give normal gtcod return
                   17942:        rsb     
                   17943: #
                   17944: #      HERE IF UNCONVERTIBLE
                   17945: #
                   17946: gtcd2: movl    (sp)+,r11       # give error return
                   17947:        jmp     *(r11)+
                   17948:        #enp                    # end procedure gtcod
                   17949:        #page   
                   17950: #
                   17951: #      GTEXP -- CONVERT TO EXPRESSION
                   17952: #
                   17953: #      (XR)                  INPUT VALUE TO BE CONVERTED
                   17954: #      JSR  GTEXP            CALL TO CONVERT TO EXPRESSION
                   17955: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   17956: #      (XR)                  POINTER TO RESULT EXBLK OR SEBLK
                   17957: #      (XL,WA,WB,WC,RA)      DESTROYED
                   17958: #
                   17959: #      IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE-
                   17960: #      EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL
                   17961: #      WITHOUT RETURNING TO THIS ROUTINE.
                   17962: #
                   17963: gtexp: #prc                    # entry point
                   17964:        cmpl    (r9),$b$e$$     # jump if already an expression
                   17965:        bgtru   0f
                   17966:        jmp     gtex1
                   17967: 0:             
                   17968:        movl    r9,-(sp)        # store argument for gtstg
                   17969:        jsb     gtstg           # convert argument to string
                   17970:        .long   gtex2           # jump if unconvertible
                   17971: #
                   17972: #      CHECK THE LAST CHARACTER OF THE STRING FOR COLON OR
                   17973: #      SEMICOLON.  THESE CHARACTERS CAN LEGITIMATELY END AN
                   17974: #      EXPRESSION IN OPEN CODE, SO EXPAN WILL NOT DETECT THEM
                   17975: #      AS ERRORS, BUT THEY ARE INVALID AS TERMINATORS FOR A
                   17976: #      STRING THAT IS BEING CONVERTED TO EXPRESSION FORM.
                   17977: #
                   17978:        movl    r9,r10          # copy input string pointer (reg06)
                   17979:        movab   cfp$f(r10)[r6],r10 # point one past the string end (reg06)
                   17980:        movzbl  -(r10),r10      # fetch the last character (reg06)
                   17981:        cmpl    r10,$ch$cl      # error if it is a semicolon (reg06)
                   17982:        beqlu   gtex2
                   17983:        cmpl    r10,$ch$sm      # or if it is a colon (reg06)
                   17984:        beqlu   gtex2
                   17985: #
                   17986: #      HERE WE CONVERT A STRING BY COMPILATION
                   17987: #
                   17988:        movl    r9,r$cim        # set input image pointer
                   17989:        clrl    scnpt           # set scan pointer
                   17990:        movl    r6,scnil        # set input image length
                   17991:        clrl    r7              # set code for normal scan
                   17992:        movl    flptr,gtcef     # save fail ptr in case of error
                   17993:        movl    r$cod,r$gtc     # also save code ptr
                   17994:        movl    $stgev,stage    # adjust stage for compile
                   17995:        movl    $t$uok,scntp    # indicate unary operator acceptable
                   17996:        jsb     expan           # build tree for expression
                   17997:        clrl    scnrs           # reset rescan flag
                   17998:        cmpl    scnpt,scnil     # error if not end of image
                   17999:        bnequ   gtex2
                   18000:        clrl    r7              # set ok value for cdgex call
                   18001:        movl    r9,r10          # copy tree pointer
                   18002:        jsb     cdgex           # build expression block
                   18003:        clrl    r$cim           # clear pointer
                   18004:        movl    $stgxt,stage    # restore stage for execute time
                   18005: #
                   18006: #      MERGE HERE IF NO CONVERSION REQUIRED
                   18007: #
                   18008: gtex1: addl2   $4*1,(sp)       # return to gtexp caller
                   18009:        rsb     
                   18010: #
                   18011: #      HERE IF UNCONVERTIBLE
                   18012: #
                   18013: gtex2: movl    (sp)+,r11       # take error exit
                   18014:        jmp     *(r11)+
                   18015:        #enp                    # end procedure gtexp
                   18016:        #page   
                   18017: #
                   18018: #      GTINT -- GET INTEGER VALUE
                   18019: #
                   18020: #      GTINT IS PASSED AN OBJECT AND RETURNS AN INTEGER AFTER
                   18021: #      PERFORMING ANY NECESSARY CONVERSIONS.
                   18022: #
                   18023: #      (XR)                  VALUE TO BE CONVERTED
                   18024: #      JSR  GTINT            CALL TO CONVERT TO INTEGER
                   18025: #      PPM  LOC              TRANSFER LOC FOR CONVERT IMPOSSIBLE
                   18026: #      (XR)                  RESULTING INTEGER
                   18027: #      (WC,RA)               DESTROYED
                   18028: #      (WA,WB)               DESTROYED (ONLY ON CONVERSION ERR)
                   18029: #      (XR)                  UNCHANGED (ON CONVERT ERROR)
                   18030: #
                   18031: gtint: #prc                    # entry point
                   18032:        cmpl    (r9),$b$icl     # jump if already an integer
                   18033:        beqlu   gtin2
                   18034:        movl    r6,gtina        # else save wa
                   18035:        movl    r7,gtinb        # save wb
                   18036:        jsb     gtnum           # convert to numeric
                   18037:        .long   gtin3           # jump if unconvertible
                   18038:        cmpl    r6,$b$icl       # jump if integer
                   18039:        beqlu   gtin1
                   18040: #
                   18041: #      HERE WE CONVERT A REAL TO INTEGER
                   18042: #
                   18043:        movf    4*rcval(r9),r2  # load real value
                   18044:        cvtfl   r2,r5           # convert to integer (err if ovflow)
                   18045:        bvs     gtin3
                   18046:        jsb     icbld           # if ok build icblk
                   18047: #
                   18048: #      HERE AFTER SUCCESSFUL CONVERSION TO INTEGER
                   18049: #
                   18050: gtin1: movl    gtina,r6        # restore wa
                   18051:        movl    gtinb,r7        # restore wb
                   18052: #
                   18053: #      COMMON EXIT POINT
                   18054: #
                   18055: gtin2: addl2   $4*1,(sp)       # return to gtint caller
                   18056:        rsb     
                   18057: #
                   18058: #      HERE ON CONVERSION ERROR
                   18059: #
                   18060: gtin3: movl    (sp)+,r11       # take convert error exit
                   18061:        jmp     *(r11)+
                   18062:        #enp                    # end procedure gtint
                   18063:        #page   
                   18064: #
                   18065: #      GTNUM -- GET NUMERIC VALUE
                   18066: #
                   18067: #      GTNUM IS GIVEN AN OBJECT AND RETURNS EITHER AN INTEGER
                   18068: #      OR A REAL, PERFORMING ANY NECESSARY CONVERSIONS.
                   18069: #
                   18070: #      (XR)                  OBJECT TO BE CONVERTED
                   18071: #      JSR  GTNUM            CALL TO CONVERT TO NUMERIC
                   18072: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18073: #      (XR)                  POINTER TO RESULT (INT OR REAL)
                   18074: #      (WA)                  FIRST WORD OF RESULT BLOCK
                   18075: #      (WB,WC,RA)            DESTROYED
                   18076: #      (XR)                  UNCHANGED (ON CONVERT ERROR)
                   18077: #
                   18078: gtnum: #prc                    # entry point
                   18079:        movl    (r9),r6         # load first word of block
                   18080:        cmpl    r6,$b$icl       # jump if integer (no conversion)
                   18081:        bnequ   0f
                   18082:        jmp     gtn34
                   18083: 0:             
                   18084:        cmpl    r6,$b$rcl       # jump if real (no conversion)
                   18085:        bnequ   0f
                   18086:        jmp     gtn34
                   18087: 0:             
                   18088: #
                   18089: #      AT THIS POINT THE ONLY POSSIBILITY IS TO CONVERT A STRING
                   18090: #      TO AN INTEGER OR REAL AS APPROPRIATE.
                   18091: #
                   18092:        movl    r9,-(sp)        # stack argument in case convert err
                   18093:        movl    r9,-(sp)        # stack argument for gtstg
                   18094:        jsb     gtstg           # convert argument to string
                   18095:        .long   gtn36           # jump if unconvertible
                   18096: #
                   18097: #      INITIALIZE NUMERIC CONVERSION
                   18098: #
                   18099:        movl    intv0,r5        # initialize integer result to zero
                   18100:        tstl    r6              # jump to exit with zero if null
                   18101:        bnequ   0f
                   18102:        jmp     gtn32
                   18103: 0:             
                   18104:                                # set bct counter for following loops
                   18105:        clrl    gtnnf           # tentatively indicate result +
                   18106:        movl    r5,gtnex        # initialise exponent to zero
                   18107:        clrl    gtnsc           # zero scale in case real
                   18108:        clrl    gtndf           # reset flag for dec point found
                   18109:        clrl    gtnrd           # reset flag for digits found
                   18110:        movf    reav0,r2        # zero real accum in case real
                   18111:        movab   cfp$f(r9),r9    # point to argument characters
                   18112: #
                   18113: #      MERGE BACK HERE AFTER IGNORING LEADING BLANK
                   18114: #
                   18115: gtn01: movzbl  (r9)+,r7        # load first character
                   18116:        cmpl    r7,$ch$d0       # jump if not digit
                   18117:        blssu   gtn02
                   18118:        cmpl    r7,$ch$d9       # jump if first char is a digit
                   18119:        blequ   gtn06
                   18120:        #page   
                   18121: #
                   18122: #      GTNUM (CONTINUED)
                   18123: #
                   18124: #      HERE IF FIRST DIGIT IS NON-DIGIT
                   18125: #
                   18126: gtn02: cmpl    r7,$ch$bl       # jump if non-blank
                   18127:        bnequ   gtn03
                   18128: gtna2: sobgtr  r6,gtn01        # else decr count and loop back
                   18129:        jmp     gtn07           # jump to return zero if all blanks
                   18130: #
                   18131: #      HERE FOR FIRST CHARACTER NON-BLANK, NON-DIGIT
                   18132: #
                   18133: gtn03: cmpl    r7,$ch$pl       # jump if plus sign
                   18134:        beqlu   gtn04
                   18135:        cmpl    r7,$ch$ht       # horizontal tab equiv to blank
                   18136:        beqlu   gtna2
                   18137:        cmpl    r7,$ch$mn       # jump if not minus (may be real)
                   18138:        beqlu   0f
                   18139:        jmp     gtn12
                   18140: 0:             
                   18141:        movl    sp,gtnnf        # if minus sign, set negative flag
                   18142: #
                   18143: #      MERGE HERE AFTER PROCESSING SIGN
                   18144: #
                   18145: gtn04: sobgtr  r6,gtn05        # jump if chars left
                   18146:        jmp     gtn36           # else error
                   18147: #
                   18148: #      LOOP TO FETCH CHARACTERS OF AN INTEGER
                   18149: #
                   18150: gtn05: movzbl  (r9)+,r7        # load next character
                   18151:        cmpl    r7,$ch$d0       # jump if not a digit
                   18152:        blssu   gtn08
                   18153:        cmpl    r7,$ch$d9       # jump if not a digit
                   18154:        bgtru   gtn08
                   18155: #
                   18156: #      MERGE HERE FOR FIRST DIGIT
                   18157: #
                   18158: gtn06: movl    r5,gtnsi        # save current value
                   18159:        mull2   $10,r5          # current*10-(new dig) jump if ovflow
                   18160:        bvc     0f
                   18161:        jmp     gtn35
                   18162: 0:     bicl2   $0xfffffff0,r7
                   18163:        subl2   r7,r5
                   18164:        bvc     1f
                   18165:        jmp     gtn35
                   18166: 1:             
                   18167:        movl    sp,gtnrd        # set digit read flag
                   18168:        sobgtr  r6,gtn05        # else loop back if more chars
                   18169: #
                   18170: #      HERE TO EXIT WITH CONVERTED INTEGER VALUE
                   18171: #
                   18172: gtn07: tstl    gtnnf           # jump if negative (all set)
                   18173:        beqlu   0f
                   18174:        jmp     gtn32
                   18175: 0:             
                   18176:        mnegl   r5,r5           # else negate
                   18177:        bvs     0f
                   18178:        jmp     gtn32
                   18179: 0:             
                   18180:        jmp     gtn36           # else signal error
                   18181:        #page   
                   18182: #
                   18183: #      GTNUM (CONTINUED)
                   18184: #
                   18185: #      HERE FOR A NON-DIGIT CHARACTER WHILE ATTEMPTING TO
                   18186: #      CONVERT AN INTEGER, CHECK FOR TRAILING BLANKS OR REAL.
                   18187: #
                   18188: gtn08: cmpl    r7,$ch$bl       # jump if a blank
                   18189:        beqlu   gtna9
                   18190:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18191:        beqlu   gtna9
                   18192:        cvtlf   r5,r2           # else convert integer to real
                   18193:        mnegf   r2,r2           # negate to get positive value
                   18194:        jmp     gtn12           # jump to try for real
                   18195: #
                   18196: #      HERE WE SCAN OUT BLANKS TO END OF STRING
                   18197: #
                   18198: gtn09: movzbl  (r9)+,r7        # get next char
                   18199:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18200:        beqlu   gtna9
                   18201:        cmpl    r7,$ch$bl       # error if non-blank
                   18202:        beqlu   0f
                   18203:        jmp     gtn36
                   18204: 0:             
                   18205: gtna9: sobgtr  r6,gtn09        # loop back if more chars to check
                   18206:        jmp     gtn07           # return integer if all blanks
                   18207: #
                   18208: #      LOOP TO COLLECT MANTISSA OF REAL
                   18209: #
                   18210: gtn10: movzbl  (r9)+,r7        # load next character
                   18211:        cmpl    r7,$ch$d0       # jump if non-numeric
                   18212:        bgequ   0f
                   18213:        jmp     gtn12
                   18214: 0:             
                   18215:        cmpl    r7,$ch$d9       # jump if non-numeric
                   18216:        blequ   0f
                   18217:        jmp     gtn12
                   18218: 0:             
                   18219: #
                   18220: #      MERGE HERE TO COLLECT FIRST REAL DIGIT
                   18221: #
                   18222: gtn11: subl2   $ch$d0,r7       # convert digit to number
                   18223:        mulf2   reavt,r2        # multiply real by 10.0
                   18224:        bvc     0f
                   18225:        jmp     gtn36
                   18226: 0:             
                   18227:        movf    r2,gtnsr        # save result
                   18228:        movl    r7,r5           # get new digit as integer
                   18229:        cvtlf   r5,r2           # convert new digit to real
                   18230:        addf2   gtnsr,r2        # add to get new total
                   18231:        addl2   gtndf,gtnsc     # increment scale if after dec point
                   18232:        movl    sp,gtnrd        # set digit found flag
                   18233:        sobgtr  r6,gtn10        # loop back if more chars
                   18234:        jmp     gtn22           # else jump to scale
                   18235:        #page   
                   18236: #
                   18237: #      GTNUM (CONTINUED)
                   18238: #
                   18239: #      HERE IF NON-DIGIT FOUND WHILE COLLECTING A REAL
                   18240: #
                   18241: gtn12: cmpl    r7,$ch$dt       # jump if not dec point
                   18242:        bnequ   gtn13
                   18243:        tstl    gtndf           # if dec point, error if one already
                   18244:        beqlu   0f
                   18245:        jmp     gtn36
                   18246: 0:             
                   18247:        movl    $num01,gtndf    # else set flag for dec point
                   18248:        sobgtr  r6,gtn10        # loop back if more chars
                   18249:        jmp     gtn22           # else jump to scale
                   18250: #
                   18251: #      HERE IF NOT DECIMAL POINT
                   18252: #
                   18253: gtn13: cmpl    r7,$ch$le       # jump if e for exponent
                   18254:        beqlu   gtn15
                   18255:        cmpl    r7,$ch$ld       # jump if d for exponent
                   18256:        beqlu   gtn15
                   18257:        cmpl    r7,$ch$$e       # jump if e for exponent
                   18258:        beqlu   gtn15
                   18259:        cmpl    r7,$ch$$d       # jump if d for exponent
                   18260:        beqlu   gtn15
                   18261: #
                   18262: #      HERE CHECK FOR TRAILING BLANKS
                   18263: #
                   18264: gtn14: cmpl    r7,$ch$bl       # jump if blank
                   18265:        beqlu   gtnb4
                   18266:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18267:        beqlu   gtnb4
                   18268:        jmp     gtn36           # error if non-blank
                   18269: #
                   18270: gtnb4: movzbl  (r9)+,r7        # get next character
                   18271:        sobgtr  r6,gtn14        # loop back to check if more
                   18272:        jmp     gtn22           # else jump to scale
                   18273: #
                   18274: #      HERE TO READ AND PROCESS AN EXPONENT
                   18275: #
                   18276: gtn15: clrl    gtnes           # set exponent sign positive
                   18277:        movl    intv0,r5        # initialize exponent to zero
                   18278:        movl    sp,gtndf        # reset no dec point indication
                   18279:        sobgtr  r6,gtn16        # jump skipping past e or d
                   18280:        jmp     gtn36           # error if null exponent
                   18281: #
                   18282: #      CHECK FOR EXPONENT SIGN
                   18283: #
                   18284: gtn16: movzbl  (r9)+,r7        # load first exponent character
                   18285:        cmpl    r7,$ch$pl       # jump if plus sign
                   18286:        beqlu   gtn17
                   18287:        cmpl    r7,$ch$mn       # else jump if not minus sign
                   18288:        bnequ   gtn19
                   18289:        movl    sp,gtnes        # set sign negative if minus sign
                   18290: #
                   18291: #      MERGE HERE AFTER PROCESSING EXPONENT SIGN
                   18292: #
                   18293: gtn17: sobgtr  r6,gtn18        # jump if chars left
                   18294:        jmp     gtn36           # else error
                   18295: #
                   18296: #      LOOP TO CONVERT EXPONENT DIGITS
                   18297: #
                   18298: gtn18: movzbl  (r9)+,r7        # load next character
                   18299:        #page   
                   18300: #
                   18301: #      GTNUM (CONTINUED)
                   18302: #
                   18303: #      MERGE HERE FOR FIRST EXPONENT DIGIT
                   18304: #
                   18305: gtn19: cmpl    r7,$ch$d0       # jump if not digit
                   18306:        blssu   gtn20
                   18307:        cmpl    r7,$ch$d9       # jump if not digit
                   18308:        bgtru   gtn20
                   18309:        mull2   $10,r5          # else current*10, subtract new digit
                   18310:        bvc     0f
                   18311:        jmp     gtn36
                   18312: 0:     bicl2   $0xfffffff0,r7
                   18313:        subl2   r7,r5
                   18314:        bvc     1f
                   18315:        jmp     gtn36
                   18316: 1:             
                   18317:        sobgtr  r6,gtn18        # loop back if more chars
                   18318:        jmp     gtn21           # jump if exponent field is exhausted
                   18319: #
                   18320: #      HERE TO CHECK FOR TRAILING BLANKS AFTER EXPONENT
                   18321: #
                   18322: gtn20: cmpl    r7,$ch$bl       # jump if blank
                   18323:        beqlu   gtnc0
                   18324:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   18325:        beqlu   gtnc0
                   18326:        jmp     gtn36           # error if non-blank
                   18327: #
                   18328: gtnc0: movzbl  (r9)+,r7        # get next character
                   18329:        sobgtr  r6,gtn20        # loop back till all blanks scanned
                   18330: #
                   18331: #      MERGE HERE AFTER COLLECTING EXPONENT
                   18332: #
                   18333: gtn21: movl    r5,gtnex        # save collected exponent
                   18334:        tstl    gtnes           # jump if it was negative
                   18335:        bnequ   gtn22
                   18336:        mnegl   r5,r5           # else complement
                   18337:        bvc     0f
                   18338:        jmp     gtn36
                   18339: 0:             
                   18340:        movl    r5,gtnex        # and store positive exponent
                   18341: #
                   18342: #      MERGE HERE WITH EXPONENT (0 IF NONE GIVEN)
                   18343: #
                   18344: gtn22: tstl    gtnrd           # error if not digits collected
                   18345:        bnequ   0f
                   18346:        jmp     gtn36
                   18347: 0:             
                   18348:        tstl    gtndf           # error if no exponent or dec point
                   18349:        bnequ   0f
                   18350:        jmp     gtn36
                   18351: 0:             
                   18352:        movl    gtnsc,r5        # else load scale as integer
                   18353:        subl2   gtnex,r5        # subtract exponent
                   18354:        bvc     0f
                   18355:        jmp     gtn36
                   18356: 0:             
                   18357:        tstl    r5              # jump if we must scale up
                   18358:        blss    gtn26
                   18359: #
                   18360: #      HERE WE HAVE A NEGATIVE EXPONENT, SO SCALE DOWN
                   18361: #
                   18362:        movl    r5,r6           # load scale factor, err if ovflow
                   18363:        bgeq    0f
                   18364:        jmp     gtn36
                   18365: 0:             
                   18366: #
                   18367: #      LOOP TO SCALE DOWN IN STEPS OF 10**10
                   18368: #
                   18369: gtn23: cmpl    r6,$num10       # jump if 10 or less to go
                   18370:        blequ   gtn24
                   18371:        divf2   reatt,r2        # else divide by 10**10
                   18372:        subl2   $num10,r6       # decrement scale
                   18373:        jmp     gtn23           # and loop back
                   18374:        #page   
                   18375: #
                   18376: #      GTNUM (CONTINUED)
                   18377: #
                   18378: #      HERE SCALE REST OF WAY FROM POWERS OF TEN TABLE
                   18379: #
                   18380: gtn24: tstl    r6              # jump if scaled
                   18381:        beqlu   gtn30
                   18382:        movl    $cfp$r,r7       # else get indexing factor
                   18383:        movl    $reav1,r9       # point to powers of ten table
                   18384:        moval   0[r6],r6        # convert remaining scale to byte ofs
                   18385: #
                   18386: #      LOOP TO POINT TO POWERS OF TEN TABLE ENTRY
                   18387: #
                   18388: gtn25: addl2   r6,r9           # bump pointer
                   18389:        sobgtr  r7,gtn25        # once for each value word
                   18390:        divf2   (r9),r2         # scale down as required
                   18391:        jmp     gtn30           # and jump
                   18392: #
                   18393: #      COME HERE TO SCALE RESULT UP (POSITIVE EXPONENT)
                   18394: #
                   18395: gtn26: mnegl   r5,r5           # get absolute value of exponent
                   18396:        bvc     0f
                   18397:        jmp     gtn36
                   18398: 0:             
                   18399:        movl    r5,r6           # acquire scale, error if ovflow
                   18400:        bgeq    0f
                   18401:        jmp     gtn36
                   18402: 0:             
                   18403: #
                   18404: #      LOOP TO SCALE UP IN STEPS OF 10**10
                   18405: #
                   18406: gtn27: cmpl    r6,$num10       # jump if 10 or less to go
                   18407:        blequ   gtn28
                   18408:        mulf2   reatt,r2        # else multiply by 10**10
                   18409:        bvc     0f
                   18410:        jmp     gtn36
                   18411: 0:             
                   18412:        subl2   $num10,r6       # else decrement scale
                   18413:        jmp     gtn27           # and loop back
                   18414: #
                   18415: #      HERE TO SCALE UP REST OF WAY WITH TABLE
                   18416: #
                   18417: gtn28: tstl    r6              # jump if scaled
                   18418:        beqlu   gtn30
                   18419:        movl    $cfp$r,r7       # else get indexing factor
                   18420:        movl    $reav1,r9       # point to powers of ten table
                   18421:        moval   0[r6],r6        # convert remaining scale to byte ofs
                   18422: #
                   18423: #      LOOP TO POINT TO PROPER ENTRY IN POWERS OF TEN TABLE
                   18424: #
                   18425: gtn29: addl2   r6,r9           # bump pointer
                   18426:        sobgtr  r7,gtn29        # once for each word in value
                   18427:        mulf2   (r9),r2         # scale up
                   18428:        bvc     0f
                   18429:        jmp     gtn36
                   18430: 0:             
                   18431:        #page   
                   18432: #
                   18433: #      GTNUM (CONTINUED)
                   18434: #
                   18435: #      HERE WITH REAL VALUE SCALED AND READY EXCEPT FOR SIGN
                   18436: #
                   18437: gtn30: tstl    gtnnf           # jump if positive
                   18438:        beqlu   gtn31
                   18439:        mnegf   r2,r2           # else negate
                   18440: #
                   18441: #      HERE WITH PROPERLY SIGNED REAL VALUE IN (RA)
                   18442: #
                   18443: gtn31: jsb     rcbld           # build real block
                   18444:        jmp     gtn33           # merge to exit
                   18445: #
                   18446: #      HERE WITH PROPERLY SIGNED INTEGER VALUE IN (IA)
                   18447: #
                   18448: gtn32: jsb     icbld           # build icblk
                   18449: #
                   18450: #      REAL MERGES HERE
                   18451: #
                   18452: gtn33: movl    (r9),r6         # load first word of result block
                   18453:        addl2   $4,sp           # pop argument off stack
                   18454: #
                   18455: #      COMMON EXIT POINT
                   18456: #
                   18457: gtn34: addl2   $4*1,(sp)       # return to gtnum caller
                   18458:        rsb     
                   18459: #
                   18460: #      COME HERE IF OVERFLOW OCCURS DURING COLLECTION OF INTEGER
                   18461: #
                   18462: gtn35: movl    gtnsi,r5        # reload integer so far
                   18463:        cvtlf   r5,r2           # convert to real
                   18464:        mnegf   r2,r2           # make value positive
                   18465:        jmp     gtn11           # merge with real circuit
                   18466: #
                   18467: #      HERE FOR UNCONVERTIBLE TO STRING OR CONVERSION ERROR
                   18468: #
                   18469: gtn36: movl    (sp)+,r9        # reload original argument
                   18470:        movl    (sp)+,r11       # take convert-error exit
                   18471:        jmp     *(r11)+
                   18472:        #enp                    # end procedure gtnum
                   18473:        #page   
                   18474: #
                   18475: #      GTNVR -- CONVERT TO NATURAL VARIABLE
                   18476: #
                   18477: #      GTNVR LOCATES A VARIABLE BLOCK (VRBLK) GIVEN EITHER AN
                   18478: #      APPROPRIATE NAME (NMBLK) OR A NON-NULL STRING (SCBLK).
                   18479: #
                   18480: #      (XR)                  ARGUMENT
                   18481: #      JSR  GTNVR            CALL TO CONVERT TO NATURAL VARIABLE
                   18482: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18483: #      (XR)                  POINTER TO VRBLK
                   18484: #      (WA,WB)               DESTROYED (CONVERSION ERROR ONLY)
                   18485: #      (WC)                  DESTROYED
                   18486: #
                   18487: gtnvr: #prc                    # entry point
                   18488:        cmpl    (r9),$b$nml     # jump if not name
                   18489:        bnequ   gnv02
                   18490:        movl    4*nmbas(r9),r9  # else load name base if name
                   18491:        cmpl    r9,state        # skip if vrblk (in static region)
                   18492:        bgtru   0f
                   18493:        jmp     gnv07
                   18494: 0:             
                   18495: #
                   18496: #      COMMON ERROR EXIT
                   18497: #
                   18498: gnv01: movl    (sp)+,r11       # take convert-error exit
                   18499:        jmp     *(r11)+
                   18500: #
                   18501: #      HERE IF NOT NAME
                   18502: #
                   18503: gnv02: movl    r6,gnvsa        # save wa
                   18504:        movl    r7,gnvsb        # save wb
                   18505:        movl    r9,-(sp)        # stack argument for gtstg
                   18506:        jsb     gtstg           # convert argument to string
                   18507:        .long   gnv01           # jump if conversion error
                   18508:        tstl    r6              # null string is an error
                   18509:        beqlu   gnv01
                   18510:        jsb     flstg           # fold lower case to upper case
                   18511:        movl    r10,-(sp)       # save xl
                   18512:        movl    r9,-(sp)        # stack string ptr for later
                   18513:        movl    r9,r7           # copy string pointer
                   18514:        addl2   $4*schar,r7     # point to characters of string
                   18515:        movl    r7,gnvst        # save pointer to characters
                   18516:        movl    r6,r7           # copy length
                   18517:        movab   3+(4*0)(r7),r7  # get number of words in name
                   18518:        ashl    $-2,r7,r7
                   18519:        movl    r7,gnvnw        # save for later
                   18520:        jsb     hashs           # compute hash index for string
                   18521:        ashq    $-32,r4,r4      # compute hash offset by taking mod
                   18522:        ediv    hshnb,r4,r11,r5
                   18523:        movl    r5,r8           # get as offset
                   18524:        moval   0[r8],r8        # convert offset to bytes
                   18525:        addl2   hshtb,r8        # point to proper hash chain
                   18526:        subl2   $4*vrnxt,r8     # subtract offset to merge into loop
                   18527:        #page   
                   18528: #
                   18529: #      GTNVR (CONTINUED)
                   18530: #
                   18531: #      LOOP TO SEARCH HASH CHAIN
                   18532: #
                   18533: gnv03: movl    r8,r10          # copy hash chain pointer
                   18534:        movl    4*vrnxt(r10),r10# point to next vrblk on chain
                   18535:        beqlu   gnv08           # jump if end of chain
                   18536:        movl    r10,r8          # save pointer to this vrblk
                   18537:        tstl    4*vrlen(r10)    # jump if not system variable
                   18538:        bnequ   gnv04
                   18539:        movl    4*vrsvp(r10),r10# else point to svblk
                   18540:        subl2   $4*vrsof,r10    # adjust offset for merge
                   18541: #
                   18542: #      MERGE HERE WITH STRING PTR (LIKE VRBLK) IN XL
                   18543: #
                   18544: gnv04: cmpl    r6,4*vrlen(r10) # back for next vrblk if lengths ne
                   18545:        bnequ   gnv03
                   18546:        addl2   $4*vrchs,r10    # else point to chars of chain entry
                   18547:        movl    gnvnw,r7        # get word counter to control loop
                   18548:        movl    gnvst,r9        # point to chars of new name
                   18549: #
                   18550: #      LOOP TO COMPARE CHARACTERS OF THE TWO NAMES
                   18551: #
                   18552: gnv05: cmpl    (r9),(r10)      # jump if no match for next vrblk
                   18553:        bnequ   gnv03
                   18554:        addl2   $4,r9           # bump new name pointer
                   18555:        addl2   $4,r10          # bump vrblk in chain name pointer
                   18556:        sobgtr  r7,gnv05        # else loop till all compared
                   18557:        movl    r8,r9           # we have found a match, get vrblk
                   18558: #
                   18559: #      EXIT POINT AFTER FINDING VRBLK OR BUILDING NEW ONE
                   18560: #
                   18561: gnv06: movl    gnvsa,r6        # restore wa
                   18562:        movl    gnvsb,r7        # restore wb
                   18563:        addl2   $4,sp           # pop string pointer
                   18564:        movl    (sp)+,r10       # restore xl
                   18565: #
                   18566: #      COMMON EXIT POINT
                   18567: #
                   18568: gnv07: addl2   $4*1,(sp)       # return to gtnvr caller
                   18569:        rsb     
                   18570: #
                   18571: #      NOT FOUND, PREPARE TO SEARCH SYSTEM VARIABLE TABLE
                   18572: #
                   18573: gnv08: clrl    r9              # clear garbage xr pointer
                   18574:        movl    r8,gnvhe        # save ptr to end of hash chain
                   18575:        cmpl    r6,$num09       # cannot be system var if length gt 9
                   18576:        bgtru   gnv14
                   18577:        movl    r6,r10          # else copy length
                   18578:        moval   0[r10],r10      # convert to byte offset
                   18579:        movl    l^vsrch(r10),r10# point to first svblk of this length
                   18580:        #page   
                   18581: #
                   18582: #      GTNVR (CONTINUED)
                   18583: #
                   18584: #      LOOP TO SEARCH ENTRIES IN STANDARD VARIABLE TABLE
                   18585: #
                   18586: gnv09: movl    r10,gnvsp       # save table pointer
                   18587:        movl    (r10)+,r8       # load svbit bit string
                   18588:        movl    (r10)+,r7       # load length from table entry
                   18589:        cmpl    r6,r7           # jump if end of right length entires
                   18590:        bnequ   gnv14
                   18591:        movl    gnvnw,r7        # get word counter to control loop
                   18592:        movl    gnvst,r9        # point to chars of new name
                   18593: #
                   18594: #      LOOP TO CHECK FOR MATCHING NAMES
                   18595: #
                   18596: gnv10: cmpl    (r9),(r10)      # jump if name mismatch
                   18597:        bnequ   gnv11
                   18598:        addl2   $4,r9           # else bump new name pointer
                   18599:        addl2   $4,r10          # bump svblk pointer
                   18600:        sobgtr  r7,gnv10        # else loop until all checked
                   18601: #
                   18602: #      HERE WE HAVE A MATCH IN THE STANDARD VARIABLE TABLE
                   18603: #
                   18604:        clrl    r8              # set vrlen value zero
                   18605:        movl    $4*vrsi$,r6     # set standard size
                   18606:        jmp     gnv15           # jump to build vrblk
                   18607: #
                   18608: #      HERE IF NO MATCH WITH TABLE ENTRY IN SVBLKS TABLE
                   18609: #
                   18610: gnv11: addl2   $4,r10          # bump past word of chars
                   18611:        sobgtr  r7,gnv11        # loop back if more to go
                   18612:        ashl    $-svnbt,r8,r8   # remove uninteresting bits
                   18613: #
                   18614: #      LOOP TO BUMP TABLE PTR FOR EACH FLAGGED WORD
                   18615: #
                   18616: gnv12: movl    bits1,r7        # load bit to test
                   18617:        mcoml   r8,r11          # test for word present
                   18618:        bicl2   r11,r7
                   18619:        beqlu   gnv13           # jump if not present
                   18620:        addl2   $4,r10          # else bump table pointer
                   18621: #
                   18622: #      HERE AFTER DEALING WITH ONE WORD (ONE BIT)
                   18623: #
                   18624: gnv13: ashl    $-1,r8,r8       # remove bit already processed
                   18625:        tstl    r8              # loop back if more bits to test
                   18626:        bnequ   gnv12
                   18627:        jmp     gnv09           # else loop back for next svblk
                   18628: #
                   18629: #      HERE IF NOT SYSTEM VARIABLE
                   18630: #
                   18631: gnv14: movl    r6,r8           # copy vrlen value
                   18632:        movl    $vrchs,r6       # load standard size -chars
                   18633:        addl2   gnvnw,r6        # adjust for chars of name
                   18634:        moval   0[r6],r6        # convert length to bytes
                   18635:        #page   
                   18636: #
                   18637: #      GTNVR (CONTINUED)
                   18638: #
                   18639: #      MERGE HERE TO BUILD VRBLK
                   18640: #
                   18641: gnv15: jsb     alost           # allocate space for vrblk (static)
                   18642:        movl    r9,r7           # save vrblk pointer
                   18643:        movl    $stnvr,r10      # point to model variable block
                   18644:        movl    $4*vrlen,r6     # set length of standard fields
                   18645:        jsb     sbmvw           # set initial fields of new block
                   18646:        movl    gnvhe,r10       # load pointer to end of hash chain
                   18647:        movl    r7,4*vrnxt(r10) # add new block to end of chain
                   18648:        movl    r8,(r9)+        # set vrlen field, bump ptr
                   18649:        movl    gnvnw,r6        # get length in words
                   18650:        moval   0[r6],r6        # convert to length in bytes
                   18651:        tstl    r8              # jump if system variable
                   18652:        beqlu   gnv16
                   18653: #
                   18654: #      HERE FOR NON-SYSTEM VARIABLE -- SET CHARS OF NAME
                   18655: #
                   18656:        movl    (sp),r10        # point back to string name
                   18657:        addl2   $4*schar,r10    # point to chars of name
                   18658:        jsb     sbmvw           # move characters into place
                   18659:        movl    r7,r9           # restore vrblk pointer
                   18660:        jmp     gnv06           # jump back to exit
                   18661: #
                   18662: #      HERE FOR SYSTEM VARIABLE CASE TO FILL IN FIELDS WHERE
                   18663: #      NECESSARY FROM THE FIELDS PRESENT IN THE SVBLK.
                   18664: #
                   18665: gnv16: movl    gnvsp,r10       # load pointer to svblk
                   18666:        movl    r10,(r9)        # set svblk ptr in vrblk
                   18667:        movl    r7,r9           # restore vrblk pointer
                   18668:        movl    4*svbit(r10),r7 # load bit indicators
                   18669:        addl2   $4*svchs,r10    # point to characters of name
                   18670:        addl2   r6,r10          # point past characters
                   18671: #
                   18672: #      SKIP PAST KEYWORD NUMBER (SVKNM) IF PRESENT
                   18673: #
                   18674:        movl    btknm,r8        # load test bit
                   18675:        mcoml   r7,r11          # and to test
                   18676:        bicl2   r11,r8
                   18677:        beqlu   gnv17           # jump if no keyword number
                   18678:        addl2   $4,r10          # else bump pointer
                   18679:        #page   
                   18680: #
                   18681: #      GTNVR (CONTINUED)
                   18682: #
                   18683: #      HERE TEST FOR FUNCTION (SVFNC AND SVNAR)
                   18684: #
                   18685: gnv17: movl    btfnc,r8        # get test bit
                   18686:        mcoml   r7,r11          # and to test
                   18687:        bicl2   r11,r8
                   18688:        beqlu   gnv18           # skip if no system function
                   18689:        movl    r10,4*vrfnc(r9) # else point vrfnc to svfnc field
                   18690:        addl2   $4*num02,r10    # and bump past svfnc, svnar fields
                   18691: #
                   18692: #      NOW TEST FOR LABEL (SVLBL)
                   18693: #
                   18694: gnv18: movl    btlbl,r8        # get test bit
                   18695:        mcoml   r7,r11          # and to test
                   18696:        bicl2   r11,r8
                   18697:        beqlu   gnv19           # jump if bit is off (no system labl)
                   18698:        movl    r10,4*vrlbl(r9) # else point vrlbl to svlbl field
                   18699:        addl2   $4,r10          # bump past svlbl field
                   18700: #
                   18701: #      NOW TEST FOR VALUE (SVVAL)
                   18702: #
                   18703: gnv19: movl    btval,r8        # load test bit
                   18704:        mcoml   r7,r11          # and to test
                   18705:        bicl2   r11,r8
                   18706:        bnequ   0f              # all done if no value
                   18707:        jmp     gnv06
                   18708: 0:             
                   18709:        movl    (r10),4*vrval(r9)# else set initial value
                   18710:        movl    $b$vre,4*vrsto(r9) # set error store access
                   18711:        jmp     gnv06           # merge back to exit to caller
                   18712:        #enp                    # end procedure gtnvr
                   18713:        #page   
                   18714: #
                   18715: #      GTPAT -- GET PATTERN
                   18716: #
                   18717: #      GTPAT IS PASSED AN OBJECT IN (XR) AND RETURNS A
                   18718: #      PATTERN AFTER PERFORMING ANY NECESSARY CONVERSIONS
                   18719: #
                   18720: #      (XR)                  INPUT ARGUMENT
                   18721: #      JSR  GTPAT            CALL TO CONVERT TO PATTERN
                   18722: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18723: #      (XR)                  RESULTING PATTERN
                   18724: #      (WA)                  DESTROYED
                   18725: #      (WB)                  DESTROYED (ONLY ON CONVERT ERROR)
                   18726: #      (XR)                  UNCHANGED (ONLY ON CONVERT ERROR)
                   18727: #
                   18728: gtpat: #prc                    # entry point
                   18729:        cmpl    (r9),$p$aaa     # jump if pattern already
                   18730:        bgequ   gtpt5
                   18731: #
                   18732: #      HERE IF NOT PATTERN, TRY FOR STRING
                   18733: #
                   18734:        movl    r7,gtpsb        # save wb
                   18735:        movl    r9,-(sp)        # stack argument for gtstg
                   18736:        jsb     gtstg           # convert argument to string
                   18737:        .long   gtpt2           # jump if impossible
                   18738: #
                   18739: #      HERE WE HAVE A STRING
                   18740: #
                   18741:        tstl    r6              # jump if non-null
                   18742:        bnequ   gtpt1
                   18743: #
                   18744: #      HERE FOR NULL STRING. GENERATE POINTER TO NULL PATTERN.
                   18745: #
                   18746:        movl    $ndnth,r9       # point to nothen node
                   18747:        jmp     gtpt4           # jump to exit
                   18748:        #page   
                   18749: #
                   18750: #      GTPAT (CONTINUED)
                   18751: #
                   18752: #      HERE FOR NON-NULL STRING
                   18753: #
                   18754: gtpt1: movl    $p$str,r7       # load pcode for multi-char string
                   18755:        cmpl    r6,$num01       # jump if multi-char string
                   18756:        bnequ   gtpt3
                   18757: #
                   18758: #      HERE FOR ONE CHARACTER STRING, SHARE ONE CHARACTER ANY
                   18759: #
                   18760:        movab   cfp$f(r9),r9    # point to character
                   18761:        movzbl  (r9),r6         # load character
                   18762:        movl    r6,r9           # set as parm1
                   18763:        movl    $p$ans,r7       # point to pcode for 1-char any
                   18764:        jmp     gtpt3           # jump to build node
                   18765: #
                   18766: #      HERE IF ARGUMENT IS NOT CONVERTIBLE TO STRING
                   18767: #
                   18768: gtpt2: movl    $p$exa,r7       # set pcode for expression in case
                   18769:        cmpl    (r9),$b$e$$     # jump to build node if expression
                   18770:        blequ   gtpt3
                   18771: #
                   18772: #      HERE WE HAVE AN ERROR (CONVERSION IMPOSSIBLE)
                   18773: #
                   18774:        movl    (sp)+,r11       # take convert error exit
                   18775:        jmp     *(r11)+
                   18776: #
                   18777: #      MERGE HERE TO BUILD NODE FOR STRING OR EXPRESSION
                   18778: #
                   18779: gtpt3: jsb     pbild           # call routine to build pattern node
                   18780: #
                   18781: #      COMMON EXIT AFTER SUCCESSFUL CONVERSION
                   18782: #
                   18783: gtpt4: movl    gtpsb,r7        # restore wb
                   18784: #
                   18785: #      MERGE HERE TO EXIT OF NO CONVERSION REQUIRED
                   18786: #
                   18787: gtpt5: addl2   $4*1,(sp)       # return to gtpat caller
                   18788:        rsb     
                   18789:        #enp                    # end procedure gtpat
                   18790:        #page   
                   18791: #
                   18792: #      GTREA -- GET REAL VALUE
                   18793: #
                   18794: #      GTREA IS PASSED AN OBJECT AND RETURNS A REAL VALUE
                   18795: #      PERFORMING ANY NECESSARY CONVERSIONS.
                   18796: #
                   18797: #      (XR)                  OBJECT TO BE CONVERTED
                   18798: #      JSR  GTREA            CALL TO CONVERT OBJECT TO REAL
                   18799: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18800: #      (XR)                  POINTER TO RESULTING REAL
                   18801: #      (WA,WB,WC,RA)         DESTROYED
                   18802: #      (XR)                  UNCHANGED (CONVERT ERROR ONLY)
                   18803: #
                   18804: gtrea: #prc                    # entry point
                   18805:        movl    (r9),r6         # get first word of block
                   18806:        cmpl    r6,$b$rcl       # jump if real
                   18807:        beqlu   gtre2
                   18808:        jsb     gtnum           # else convert argument to numeric
                   18809:        .long   gtre3           # jump if unconvertible
                   18810:        cmpl    r6,$b$rcl       # jump if real was returned
                   18811:        beqlu   gtre2
                   18812: #
                   18813: #      HERE FOR CASE OF AN INTEGER TO CONVERT TO REAL
                   18814: #
                   18815: gtre1: movl    4*icval(r9),r5  # load integer
                   18816:        cvtlf   r5,r2           # convert to real
                   18817:        jsb     rcbld           # build rcblk
                   18818: #
                   18819: #      EXIT WITH REAL
                   18820: #
                   18821: gtre2: addl2   $4*1,(sp)       # return to gtrea caller
                   18822:        rsb     
                   18823: #
                   18824: #      HERE ON CONVERSION ERROR
                   18825: #
                   18826: gtre3: movl    (sp)+,r11       # take convert error exit
                   18827:        jmp     *(r11)+
                   18828:        #enp                    # end procedure gtrea
                   18829:        #page   
                   18830: #
                   18831: #      GTSMI -- GET SMALL INTEGER
                   18832: #
                   18833: #      GTSMI IS PASSED A SNOBOL OBJECT AND RETURNS AN ADDRESS
                   18834: #      INTEGER IN THE RANGE (0 LE N LE DNAMB). SUCH A VALUE CAN
                   18835: #      ONLY BE DERIVED FROM AN INTEGER IN THE APPROPRIATE RANGE.
                   18836: #      SMALL INTEGERS NEVER APPEAR AS SNOBOL VALUES. HOWEVER,
                   18837: #      THEY ARE USED INTERNALLY FOR A VARIETY OF PURPOSES.
                   18838: #
                   18839: #      -(XS)                 ARGUMENT TO CONVERT (ON STACK)
                   18840: #      JSR  GTSMI            CALL TO CONVERT TO SMALL INTEGER
                   18841: #      PPM  LOC              TRANSFER LOC FOR NOT INTEGER
                   18842: #      PPM  LOC              TRANSFER LOC FOR LT 0, GT DNAMB
                   18843: #      (XR,WC)               RESULTING SMALL INT (TWO COPIES)
                   18844: #      (XS)                  POPPED
                   18845: #      (RA)                  DESTROYED
                   18846: #      (WA,WB)               DESTROYED (ON CONVERT ERROR ONLY)
                   18847: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   18848: #
                   18849:        .data   1
                   18850: gtsmi_s:       .long   0
                   18851:        .text   0
                   18852: gtsmi: movl    (sp)+,gtsmi_s   # entry point
                   18853:        movl    (sp)+,r9        # load argument
                   18854:        cmpl    (r9),$b$icl     # skip if already an integer
                   18855:        beqlu   gtsm1
                   18856: #
                   18857: #      HERE IF NOT AN INTEGER
                   18858: #
                   18859:        jsb     gtint           # convert argument to integer
                   18860:        .long   gtsm2           # jump if convert is impossible
                   18861: #
                   18862: #      MERGE HERE WITH INTEGER
                   18863: #
                   18864: gtsm1: movl    4*icval(r9),r5  # load integer value
                   18865:        movl    r5,r8           # move as one word, jump if ovflow
                   18866:        bgeq    0f
                   18867:        jmp     gtsm3
                   18868: 0:             
                   18869:        cmpl    r8,mxlen        # or if too small
                   18870:        bgtru   gtsm3
                   18871:        movl    r8,r9           # copy result to xr
                   18872:        addl3   $4*2,gtsmi_s,r11        # return to gtsmi caller
                   18873:        jmp     (r11)
                   18874: #
                   18875: #      HERE IF UNCONVERTIBLE TO INTEGER
                   18876: #
                   18877: gtsm2: movl    gtsmi_s,r11     # take non-integer error exit
                   18878:        jmp     *(r11)+
                   18879: #
                   18880: #      HERE IF OUT OF RANGE
                   18881: #
                   18882: gtsm3: addl3   $4*1,gtsmi_s,r11        # take out-of-range error exit
                   18883:        jmp     *(r11)+
                   18884:        #enp                    # end procedure gtsmi
                   18885:        #page   
                   18886: #
                   18887: #      GTSTG -- GET STRING
                   18888: #
                   18889: #      GTSTG IS PASSED AN OBJECT AND RETURNS A STRING WITH
                   18890: #      ANY NECESSARY CONVERSIONS PERFORMED.
                   18891: #
                   18892: #      -(XS)                 INPUT ARGUMENT (ON STACK)
                   18893: #      JSR  GTSTG            CALL TO CONVERT TO STRING
                   18894: #      PPM  LOC              TRANSFER LOC IF CONVERT IMPOSSIBLE
                   18895: #      (XR)                  POINTER TO RESULTING STRING
                   18896: #      (WA)                  LENGTH OF STRING IN CHARACTERS
                   18897: #      (XS)                  POPPED
                   18898: #      (RA)                  DESTROYED
                   18899: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   18900: #
                   18901:        .data   1
                   18902: gtstg_s:       .long   0
                   18903:        .text   0
                   18904: gtstg: movl    (sp)+,gtstg_s   # entry point
                   18905:        movl    (sp)+,r9        # load argument, pop stack
                   18906:        cmpl    (r9),$b$scl     # jump if already a string
                   18907:        bnequ   0f
                   18908:        jmp     gts30
                   18909: 0:             
                   18910: #
                   18911: #      HERE IF NOT A STRING ALREADY
                   18912: #
                   18913: gts01: movl    r9,-(sp)        # restack argument in case error
                   18914:        movl    r10,-(sp)       # save xl
                   18915:        movl    r7,gtsvb        # save wb
                   18916:        movl    r8,gtsvc        # save wc
                   18917:        movl    (r9),r6         # load first word of block
                   18918:        cmpl    r6,$b$icl       # jump to convert integer
                   18919:        beqlu   gts05
                   18920:        cmpl    r6,$b$rcl       # jump to convert real
                   18921:        bnequ   0f
                   18922:        jmp     gts10
                   18923: 0:             
                   18924:        cmpl    r6,$b$nml       # jump to convert name
                   18925:        beqlu   gts03
                   18926:        cmpl    r6,$b$bct       # jump to convert buffer
                   18927:        bnequ   0f
                   18928:        jmp     gts32
                   18929: 0:             
                   18930: #
                   18931: #      HERE ON CONVERSION ERROR
                   18932: #
                   18933: gts02: movl    (sp)+,r10       # restore xl
                   18934:        movl    (sp)+,r9        # reload input argument
                   18935:        movl    gtstg_s,r11     # take convert error exit
                   18936:        jmp     *(r11)+
                   18937:        #page   
                   18938: #
                   18939: #      GTSTG (CONTINUED)
                   18940: #
                   18941: #      HERE TO CONVERT A NAME (ONLY POSSIBLE IF NATURAL VAR)
                   18942: #
                   18943: gts03: movl    4*nmbas(r9),r10 # load name base
                   18944:        cmpl    r10,state       # error if not natural var (static)
                   18945:        bgequ   gts02
                   18946:        addl2   $4*vrsof,r10    # else point to possible string name
                   18947:        movl    4*sclen(r10),r6 # load length
                   18948:        bnequ   gts04           # jump if not system variable
                   18949:        movl    4*vrsvo(r10),r10# else point to svblk
                   18950:        movl    4*svlen(r10),r6 # and load name length
                   18951: #
                   18952: #      MERGE HERE WITH STRING IN XR, LENGTH IN WA
                   18953: #
                   18954: gts04: clrl    r7              # set offset to zero
                   18955:        jsb     sbstr           # use sbstr to copy string
                   18956:        jmp     gts29           # jump to exit
                   18957: #
                   18958: #      COME HERE TO CONVERT AN INTEGER
                   18959: #
                   18960: gts05: movl    4*icval(r9),r5  # load integer value
                   18961:        movl    $num01,gtssf    # set sign flag negative
                   18962:        tstl    r5              # skip if integer is negative
                   18963:        blss    gts06
                   18964:        mnegl   r5,r5           # else negate integer
                   18965:        clrl    gtssf           # and reset negative flag
                   18966:        #page   
                   18967: #
                   18968: #      GTSTG (CONTINUED)
                   18969: #
                   18970: #      HERE WITH SIGN FLAG SET AND SIGN FORCED NEGATIVE AS
                   18971: #      REQUIRED BY THE CVD INSTRUCTION.
                   18972: #
                   18973: gts06: movl    gtswk,r9        # point to result work area
                   18974:        movl    $nstmx,r7       # initialize counter to max length
                   18975:        movab   cfp$f(r9)[r7],r9# prepare to store (right-left)
                   18976: #
                   18977: #      LOOP TO CONVERT DIGITS INTO WORK AREA
                   18978: #
                   18979: gts07: ashq    $-32,r4,r4      # convert one digit into wa
                   18980:        ediv    $10,r4,r5,r6
                   18981:        mnegl   r6,r6
                   18982:        bisb2   $0x30,r6
                   18983:        movb    r6,-(r9)        # store in work area
                   18984:        decl    r7              # decrement counter
                   18985:        tstl    r5              # loop if more digits to go
                   18986:        bneq    gts07
                   18987:        #csc    r9              # complete store characters
                   18988: #
                   18989: #      MERGE HERE AFTER CONVERTING INTEGER OR REAL INTO WORK
                   18990: #      AREA. WB IS SET TO NSTMX - (NUMBER OF CHARS IN RESULT).
                   18991: #
                   18992: gts08: movl    $nstmx,r6       # get max number of characters
                   18993:        subl2   r7,r6           # compute length of result
                   18994:        movl    r6,r10          # remember length for move later on
                   18995:        addl2   gtssf,r6        # add one for negative sign if needed
                   18996:        jsb     alocs           # allocate string for result
                   18997:        movl    r9,r8           # save result pointer for the moment
                   18998:        movab   cfp$f(r9),r9    # point to chars of result block
                   18999:        tstl    gtssf           # skip if positive
                   19000:        beqlu   gts09
                   19001:        movl    $ch$mn,r6       # else load negative sign
                   19002:        movb    r6,(r9)+        # and store it
                   19003:        #csc    r9              # complete store characters
                   19004: #
                   19005: #      HERE AFTER DEALING WITH SIGN
                   19006: #
                   19007: gts09: movl    r10,r6          # recall length to move
                   19008:        movl    gtswk,r10       # point to result work area
                   19009:        movab   cfp$f(r10)[r7],r10 # point to first result character
                   19010:        jsb     sbmvc           # move chars to result string
                   19011:        movl    r8,r9           # restore result pointer
                   19012:        jmp     gts29           # jump to exit
                   19013:        #page   
                   19014: #
                   19015: #      GTSTG (CONTINUED)
                   19016: #
                   19017: #      HERE TO CONVERT A REAL
                   19018: #
                   19019: gts10: movf    4*rcval(r9),r2  # load real
                   19020:        clrl    gtssf           # reset negative flag
                   19021:        tstf    r2              # skip if zero
                   19022:        bneq    0f
                   19023:        jmp     gts31
                   19024: 0:             
                   19025:        tstf    r2              # jump if real is positive
                   19026:        bgeq    gts11
                   19027:        movl    $num01,gtssf    # else set negative flag
                   19028:        mnegf   r2,r2           # and get absolute value of real
                   19029: #
                   19030: #      NOW SCALE THE REAL TO THE RANGE (0.1 LE X LT 1.0)
                   19031: #
                   19032: gts11: movl    intv0,r5        # initialize exponent to zero
                   19033: #
                   19034: #      LOOP TO SCALE UP IN STEPS OF 10**10
                   19035: #
                   19036: gts12: movf    r2,gtsrs        # save real value
                   19037:        subf2   reap1,r2        # subtract 0.1 to compare
                   19038:        tstf    r2              # jump if scale up not required
                   19039:        bgeq    gts13
                   19040:        movf    gtsrs,r2        # else reload value
                   19041:        mulf2   reatt,r2        # multiply by 10**10
                   19042:        subl2   intvt,r5        # decrement exponent by 10
                   19043:        jmp     gts12           # loop back to test again
                   19044: #
                   19045: #      TEST FOR SCALE DOWN REQUIRED
                   19046: #
                   19047: gts13: movf    gtsrs,r2        # reload value
                   19048:        subf2   reav1,r2        # subtract 1.0
                   19049:        tstf    r2              # jump if no scale down required
                   19050:        blss    gts17
                   19051:        movf    gtsrs,r2        # else reload value
                   19052: #
                   19053: #      LOOP TO SCALE DOWN IN STEPS OF 10**10
                   19054: #
                   19055: gts14: subf2   reatt,r2        # subtract 10**10 to compare
                   19056:        tstf    r2              # jump if large step not required
                   19057:        blss    gts15
                   19058:        movf    gtsrs,r2        # else restore value
                   19059:        divf2   reatt,r2        # divide by 10**10
                   19060:        movf    r2,gtsrs        # store new value
                   19061:        addl2   intvt,r5        # increment exponent by 10
                   19062:        jmp     gts14           # loop back
                   19063:        #page   
                   19064: #
                   19065: #      GTSTG (CONTINUED)
                   19066: #
                   19067: #      AT THIS POINT WE HAVE (1.0 LE X LT 10**10)
                   19068: #      COMPLETE SCALING WITH POWERS OF TEN TABLE
                   19069: #
                   19070: gts15: movl    $reav1,r9       # point to powers of ten table
                   19071: #
                   19072: #      LOOP TO LOCATE CORRECT ENTRY IN TABLE
                   19073: #
                   19074: gts16: movf    gtsrs,r2        # reload value
                   19075:        addl2   intv1,r5        # increment exponent
                   19076:        addl2   $4*cfp$r,r9     # point to next entry in table
                   19077:        subf2   (r9),r2         # subtract it to compare
                   19078:        tstf    r2              # loop till we find a larger entry
                   19079:        bgeq    gts16
                   19080:        movf    gtsrs,r2        # then reload the value
                   19081:        divf2   (r9),r2         # and complete scaling
                   19082:        movf    r2,gtsrs        # store value
                   19083: #
                   19084: #      WE ARE NOW SCALED, SO ROUND BY ADDING 0.5 * 10**(-CFP$S)
                   19085: #
                   19086: gts17: movf    gtsrs,r2        # get value again
                   19087:        addf2   gtsrn,r2        # add rounding factor
                   19088:        movf    r2,gtsrs        # store result
                   19089: #
                   19090: #      THE ROUNDING OPERATION MAY HAVE PUSHED US UP PAST
                   19091: #      1.0 AGAIN, SO CHECK ONE MORE TIME.
                   19092: #
                   19093:        subf2   reav1,r2        # subtract 1.0 to compare
                   19094:        tstf    r2              # skip if ok
                   19095:        blss    gts18
                   19096:        addl2   intv1,r5        # else increment exponent
                   19097:        movf    gtsrs,r2        # reload value
                   19098:        divf2   reavt,r2        # divide by 10.0 to rescale
                   19099:        jmp     gts19           # jump to merge
                   19100: #
                   19101: #      HERE IF ROUNDING DID NOT MUCK UP SCALING
                   19102: #
                   19103: gts18: movf    gtsrs,r2        # reload rounded value
                   19104:        #page   
                   19105: #
                   19106: #      GTSTG (CONTINUED)
                   19107: #
                   19108: #      NOW WE HAVE COMPLETED THE SCALING AS FOLLOWS
                   19109: #
                   19110: #      (IA)                  SIGNED EXPONENT
                   19111: #      (RA)                  SCALED REAL (ABSOLUTE VALUE)
                   19112: #
                   19113: #      IF THE EXPONENT IS NEGATIVE OR GREATER THAN CFP$S, THEN
                   19114: #      WE CONVERT THE NUMBER IN THE FORM.
                   19115: #
                   19116: #      (NEG SIGN) 0 . (CPF$S DIGITS) E (EXP SIGN) (EXP DIGITS)
                   19117: #
                   19118: #      IF THE EXPONENT IS POSITIVE AND LESS THAN OR EQUAL TO
                   19119: #      CFP$S, THE NUMBER IS CONVERTED IN THE FORM.
                   19120: #
                   19121: #      (NEG SIGN) (EXPONENT DIGITS) . (CFP$S-EXPONENT DIGITS)
                   19122: #
                   19123: #      IN BOTH CASES, THE FORMATS OBTAINED FROM THE ABOVE
                   19124: #      RULES ARE MODIFIED BY DELETING TRAILING ZEROS AFTER THE
                   19125: #      DECIMAL POINT. THERE ARE NO LEADING ZEROS IN THE EXPONENT
                   19126: #      AND THE EXPONENT SIGN IS ALWAYS PRESENT.
                   19127: #
                   19128: gts19: movl    $cfp$s,r10      # set num dec digits = cfp$s
                   19129:        movl    $ch$mn,gtses    # set exponent sign negative
                   19130:        tstl    r5              # all set if exponent is negative
                   19131:        blss    gts21
                   19132:        movl    r5,r6           # else fetch exponent
                   19133:        cmpl    r6,$cfp$s       # skip if we can use special format
                   19134:        blequ   gts20
                   19135:        movl    r6,r5           # else restore exponent
                   19136:        mnegl   r5,r5           # set negative for cvd
                   19137:        movl    $ch$pl,gtses    # set plus sign for exponent sign
                   19138:        jmp     gts21           # jump to generate exponent
                   19139: #
                   19140: #      HERE IF WE CAN USE THE FORMAT WITHOUT AN EXPONENT
                   19141: #
                   19142: gts20: subl2   r6,r10          # compute digits after decimal point
                   19143:        movl    intv0,r5        # reset exponent to zero
                   19144:        #page   
                   19145: #
                   19146: #      GTSTG (CONTINUED)
                   19147: #
                   19148: #      MERGE HERE AS FOLLOWS
                   19149: #
                   19150: #      (IA)                  EXPONENT ABSOLUTE VALUE
                   19151: #      GTSES                 CHARACTER FOR EXPONENT SIGN
                   19152: #      (RA)                  POSITIVE FRACTION
                   19153: #      (XL)                  NUMBER OF DIGITS AFTER DEC POINT
                   19154: #
                   19155: gts21: movl    gtswk,r9        # point to work area
                   19156:        movl    $nstmx,r7       # set character ctr to max length
                   19157:        movab   cfp$f(r9)[r7],r9# prepare to store (right to left)
                   19158:        tstl    r5              # skip exponent if it is zero
                   19159:        beql    gts23
                   19160: #
                   19161: #      LOOP TO GENERATE DIGITS OF EXPONENT
                   19162: #
                   19163: gts22: ashq    $-32,r4,r4      # convert a digit into wa
                   19164:        ediv    $10,r4,r5,r6
                   19165:        mnegl   r6,r6
                   19166:        bisb2   $0x30,r6
                   19167:        movb    r6,-(r9)        # store in work area
                   19168:        decl    r7              # decrement counter
                   19169:        tstl    r5              # loop back if more digits to go
                   19170:        bneq    gts22
                   19171: #
                   19172: #      HERE GENERATE EXPONENT SIGN AND E
                   19173: #
                   19174:        movl    gtses,r6        # load exponent sign
                   19175:        movb    r6,-(r9)        # store in work area
                   19176:        movl    $ch$le,r6       # get character letter e
                   19177:        movb    r6,-(r9)        # store in work area
                   19178:        subl2   $num02,r7       # decrement counter for sign and e
                   19179: #
                   19180: #      HERE TO GENERATE THE FRACTION
                   19181: #
                   19182: gts23: mulf2   gtssc,r2        # convert real to integer (10**cfp$s)
                   19183:        cvtfl   r2,r5           # get integer (overflow impossible)
                   19184:        mnegl   r5,r5           # negate as required by cvd
                   19185: #
                   19186: #      LOOP TO SUPPRESS TRAILING ZEROS
                   19187: #
                   19188: gts24: tstl    r10             # jump if no digits left to do
                   19189:        beqlu   gts27
                   19190:        ashq    $-32,r4,r4      # else convert one digit
                   19191:        ediv    $10,r4,r5,r6
                   19192:        mnegl   r6,r6
                   19193:        bisb2   $0x30,r6
                   19194:        cmpl    r6,$ch$d0       # jump if not a zero
                   19195:        bnequ   gts26
                   19196:        decl    r10             # decrement counter
                   19197:        jmp     gts24           # loop back for next digit
                   19198:        #page   
                   19199: #
                   19200: #      GTSTG (CONTINUED)
                   19201: #
                   19202: #      LOOP TO GENERATE DIGITS AFTER DECIMAL POINT
                   19203: #
                   19204: gts25: ashq    $-32,r4,r4      # convert a digit into wa
                   19205:        ediv    $10,r4,r5,r6
                   19206:        mnegl   r6,r6
                   19207:        bisb2   $0x30,r6
                   19208: #
                   19209: #      MERGE HERE FIRST TIME
                   19210: #
                   19211: gts26: movb    r6,-(r9)        # store digit
                   19212:        decl    r7              # decrement counter
                   19213:        decl    r10             # decrement counter
                   19214:        bnequ   gts25           # loop back if more to go
                   19215: #
                   19216: #      HERE GENERATE THE DECIMAL POINT
                   19217: #
                   19218: gts27: movl    $ch$dt,r6       # load decimal point
                   19219:        movb    r6,-(r9)        # store in work area
                   19220:        decl    r7              # decrement counter
                   19221: #
                   19222: #      HERE GENERATE THE DIGITS BEFORE THE DECIMAL POINT
                   19223: #
                   19224: gts28: ashq    $-32,r4,r4      # convert a digit into wa
                   19225:        ediv    $10,r4,r5,r6
                   19226:        mnegl   r6,r6
                   19227:        bisb2   $0x30,r6
                   19228:        movb    r6,-(r9)        # store in work area
                   19229:        decl    r7              # decrement counter
                   19230:        tstl    r5              # loop back if more to go
                   19231:        bneq    gts28
                   19232:        #csc    r9              # complete store characters
                   19233:        jmp     gts08           # else jump back to exit
                   19234: #
                   19235: #      EXIT POINT AFTER SUCCESSFUL CONVERSION
                   19236: #
                   19237: gts29: movl    (sp)+,r10       # restore xl
                   19238:        addl2   $4,sp           # pop argument
                   19239:        movl    gtsvb,r7        # restore wb
                   19240:        movl    gtsvc,r8        # restore wc
                   19241: #
                   19242: #      MERGE HERE IF NO CONVERSION REQUIRED
                   19243: #
                   19244: gts30: movl    4*sclen(r9),r6  # load string length
                   19245:        addl3   $4*1,gtstg_s,r11        # return to caller
                   19246:        jmp     (r11)
                   19247: #
                   19248: #      HERE TO RETURN STRING FOR REAL ZERO
                   19249: #
                   19250: gts31: movl    $scre0,r10      # point to string
                   19251:        movl    $num02,r6       # 2 chars
                   19252:        clrl    r7              # zero offset
                   19253:        jsb     sbstr           # copy string
                   19254:        jmp     gts29           # return
                   19255:        #page   
                   19256: #
                   19257: #      HERE TO CONVERT A BUFFER BLOCK
                   19258: #
                   19259: gts32: movl    r9,r10          # copy arg ptr
                   19260:        movl    4*bclen(r10),r6 # get size to allocate
                   19261:        beqlu   gts33           # if null then return null
                   19262:        jsb     alocs           # allocate string frame
                   19263:        movl    r9,r7           # save string ptr
                   19264:        movl    4*sclen(r9),r6  # get length to move
                   19265:        movab   3+(4*0)(r6),r6  # get as multiple of word size
                   19266:        bicl2   $3,r6
                   19267:        movl    4*bcbuf(r10),r10# point to bfblk
                   19268:        addl2   $4*scsi$,r9     # point to start of character area
                   19269:        addl2   $4*bfsi$,r10    # point to start of buffer chars
                   19270:        jsb     sbmvw           # copy words
                   19271:        movl    r7,r9           # restore scblk ptr
                   19272:        jmp     gts29           # exit with scblk
                   19273: #
                   19274: #      HERE WHEN NULL BUFFER IS BEING CONVERTED
                   19275: #
                   19276: gts33: movl    $nulls,r9       # point to null
                   19277:        jmp     gts29           # exit with null
                   19278:        #enp                    # end procedure gtstg
                   19279:        #page   
                   19280: #
                   19281: #      GTVAR -- GET VARIABLE FOR I/O/TRACE ASSOCIATION
                   19282: #
                   19283: #      GTVAR IS USED TO POINT TO AN ACTUAL VARIABLE LOCATION
                   19284: #      FOR THE DETACH,INPUT,OUTPUT,TRACE,STOPTR SYSTEM FUNCTIONS
                   19285: #
                   19286: #      (XR)                  ARGUMENT TO FUNCTION
                   19287: #      JSR  GTVAR            CALL TO LOCATE VARIABLE POINTER
                   19288: #      PPM  LOC              TRANSFER LOC IF NOT OK VARIABLE
                   19289: #      (XL,WA)               NAME BASE,OFFSET OF VARIABLE
                   19290: #      (XR,RA)               DESTROYED
                   19291: #      (WB,WC)               DESTROYED (CONVERT ERROR ONLY)
                   19292: #      (XR)                  INPUT ARG (CONVERT ERROR ONLY)
                   19293: #
                   19294: gtvar: #prc                    # entry point
                   19295:        cmpl    (r9),$b$nml     # jump if not a name
                   19296:        bnequ   gtvr2
                   19297:        movl    4*nmofs(r9),r6  # else load name offset
                   19298:        movl    4*nmbas(r9),r10 # load name base
                   19299:        cmpl    (r10),$b$evt    # error if expression variable
                   19300:        beqlu   gtvr1
                   19301:        cmpl    (r10),$b$kvt    # all ok if not keyword variable
                   19302:        bnequ   gtvr3
                   19303: #
                   19304: #      HERE ON CONVERSION ERROR
                   19305: #
                   19306: gtvr1: movl    (sp)+,r11       # take convert error exit
                   19307:        jmp     *(r11)+
                   19308: #
                   19309: #      HERE IF NOT A NAME, TRY CONVERT TO NATURAL VARIABLE
                   19310: #
                   19311: gtvr2: movl    r8,gtvrc        # save wc
                   19312:        jsb     gtnvr           # locate vrblk if possible
                   19313:        .long   gtvr1           # jump if convert error
                   19314:        movl    r9,r10          # else copy vrblk name base
                   19315:        movl    $4*vrval,r6     # and set offset
                   19316:        movl    gtvrc,r8        # restore wc
                   19317: #
                   19318: #      HERE FOR NAME OBTAINED
                   19319: #
                   19320: gtvr3: cmpl    r10,state       # all ok if not natural variable
                   19321:        bgequ   gtvr4
                   19322:        cmpl    4*vrsto(r10),$b$vre # error if protected variable
                   19323:        beqlu   gtvr1
                   19324: #
                   19325: #      COMMON EXIT POINT
                   19326: #
                   19327: gtvr4: addl2   $4*1,(sp)       # return to caller
                   19328:        rsb     
                   19329:        #enp                    # end procedure gtvar
                   19330:        #page   
                   19331: #
                   19332: #      HASHS -- COMPUTE HASH INDEX FOR STRING
                   19333: #
                   19334: #      HASHS IS USED TO CONVERT A STRING TO A UNIQUE INTEGER
                   19335: #      VALUE. THE RESULTING HASH VALUE IS A POSITIVE INTEGER
                   19336: #      IN THE RANGE 0 TO CFP$M
                   19337: #
                   19338: #      (XR)                  STRING TO BE HASHED
                   19339: #      JSR  HASHS            CALL TO HASH STRING
                   19340: #      (IA)                  HASH VALUE
                   19341: #      (XR,WB,WC)            DESTROYED
                   19342: #
                   19343: #      THE HASH FUNCTION USED IS AS FOLLOWS.
                   19344: #
                   19345: #      START WITH THE LENGTH OF THE STRING (SGD07)
                   19346: #
                   19347: #      TAKE THE FIRST E$HNW WORDS OF THE CHARACTERS FROM
                   19348: #      THE STRING OR ALL THE WORDS IF FEWER THAN E$HNW.
                   19349: #
                   19350: #      COMPUTE THE EXCLUSIVE OR OF ALL THESE WORDS TREATING
                   19351: #      THEM AS ONE WORD BIT STRING VALUES.
                   19352: #
                   19353: #      MOVE THE RESULT AS AN INTEGER WITH THE MTI INSTRUCTION.
                   19354: #
                   19355: hashs: #prc                    # entry point
                   19356:        movl    4*sclen(r9),r8  # load string length in characters
                   19357:        movl    r8,r7           # initialize with length
                   19358:        tstl    r8              # jump if null string
                   19359:        beqlu   hshs3
                   19360:        movab   3+(4*0)(r8),r8  # else get number of words of chars
                   19361:        ashl    $-2,r8,r8
                   19362:        addl2   $4*schar,r9     # point to characters of string
                   19363:        cmpl    r8,$e$hnw       # use whole string if short
                   19364:        blequ   hshs1
                   19365:        movl    $e$hnw,r8       # else set to involve first e$hnw wds
                   19366: #
                   19367: #      HERE WITH COUNT OF WORDS TO CHECK IN WC
                   19368: #
                   19369: hshs1:                         # set counter to control loop
                   19370: #
                   19371: #      LOOP TO COMPUTE EXCLUSIVE OR
                   19372: #
                   19373: hshs2: xorl2   (r9)+,r7        # exclusive or next word of chars
                   19374:        sobgtr  r8,hshs2        # loop till all processed
                   19375: #
                   19376: #      MERGE HERE WITH EXCLUSIVE OR IN WB
                   19377: #
                   19378: hshs3: #zgb    r7              # zeroise undefined bits
                   19379:        mcoml   bitsm,r11       # ensure in range 0 to cfp$m
                   19380:        bicl2   r11,r7
                   19381:        movl    r7,r5           # move result as integer
                   19382:        clrl    r9              # clear garbage value in xr
                   19383:        rsb                     # return to hashs caller
                   19384:        #enp                    # end procedure hashs
                   19385:        #page   
                   19386: #
                   19387: #      ICBLD -- BUILD INTEGER BLOCK
                   19388: #
                   19389: #      (IA)                  INTEGER VALUE FOR ICBLK
                   19390: #      JSR  ICBLD            CALL TO BUILD INTEGER BLOCK
                   19391: #      (XR)                  POINTER TO RESULT ICBLK
                   19392: #      (WA)                  DESTROYED
                   19393: #
                   19394: icbld: #prc                    # entry point
                   19395:        movl    r5,r9           # copy small integers
                   19396:        bgeq    0f
                   19397:        jmp     icbl1
                   19398: 0:             
                   19399:        cmpl    r9,$num02       # jump if 0,1 or 2
                   19400:        blequ   icbl3
                   19401: #
                   19402: #      CONSTRUCT ICBLK
                   19403: #
                   19404: icbl1: movl    dnamp,r9        # load pointer to next available loc
                   19405:        addl2   $4*icsi$,r9     # point past new icblk
                   19406:        cmpl    r9,dname        # jump if there is room
                   19407:        blequ   icbl2
                   19408:        movl    $4*icsi$,r6     # else load length of icblk
                   19409:        jsb     alloc           # use standard allocator to get block
                   19410:        addl2   r6,r9           # point past block to merge
                   19411: #
                   19412: #      MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED
                   19413: #
                   19414: icbl2: movl    r9,dnamp        # set new pointer
                   19415:        subl2   $4*icsi$,r9     # point back to start of block
                   19416:        movl    $b$icl,(r9)     # store type word
                   19417:        movl    r5,4*icval(r9)  # store integer value in icblk
                   19418:        rsb                     # return to icbld caller
                   19419: #
                   19420: #      OPTIMISE BY NOT BUILDING ICBLKS FOR SMALL INTEGERS
                   19421: #
                   19422: icbl3: moval   0[r9],r9        # convert integer to offset
                   19423:        movl    l^intab(r9),r9  # point to pre-built icblk
                   19424:        rsb                     # return
                   19425:        #enp                    # end procedure icbld
                   19426:        #page   
                   19427: #
                   19428: #      IDENT -- COMPARE TWO VALUES
                   19429: #
                   19430: #      IDENT COMPARES TWO VALUES IN THE SENSE OF THE IDENT
                   19431: #      DIFFER FUNCTIONS AVAILABLE AT THE SNOBOL LEVEL.
                   19432: #
                   19433: #      (XR)                  FIRST ARGUMENT
                   19434: #      (XL)                  SECOND ARGUMENT
                   19435: #      JSR  IDENT            CALL TO COMPARE ARGUMENTS
                   19436: #      PPM  LOC              TRANSFER LOC IF IDENT
                   19437: #      (NORMAL RETURN IF DIFFER)
                   19438: #      (XR,XL,WC,RA)         DESTROYED
                   19439: #
                   19440: ident: #prc                    # entry point
                   19441:        cmpl    r9,r10          # jump if same pointer (ident)
                   19442:        bnequ   0f
                   19443:        jmp     iden7
                   19444: 0:             
                   19445:        movl    (r9),r8         # else load arg 1 type word
                   19446:        cmpl    r8,(r10)        # differ if arg 2 type word differ
                   19447:        bnequ   iden1
                   19448:        cmpl    r8,$b$scl       # jump if strings
                   19449:        beqlu   iden2
                   19450:        cmpl    r8,$b$icl       # jump if integers
                   19451:        beqlu   iden4
                   19452:        cmpl    r8,$b$rcl       # jump if reals
                   19453:        beqlu   iden5
                   19454:        cmpl    r8,$b$nml       # jump if names
                   19455:        beqlu   iden6
                   19456: #
                   19457: #      FOR ALL OTHER DATATYPES, MUST BE DIFFER IF XR NE XL
                   19458: #
                   19459: #      MERGE HERE FOR DIFFER
                   19460: #
                   19461: iden1: addl2   $4*1,(sp)       # take differ exit
                   19462:        rsb     
                   19463: #
                   19464: #      HERE FOR STRINGS, IDENT ONLY IF LENGTHS AND CHARS SAME
                   19465: #
                   19466: iden2: movl    4*sclen(r9),r8  # load arg 1 length
                   19467:        cmpl    r8,4*sclen(r10) # differ if lengths differ
                   19468:        bnequ   iden1
                   19469:        movab   3+(4*0)(r8),r8  # get number of words in strings
                   19470:        ashl    $-2,r8,r8
                   19471:        addl2   $4*schar,r9     # point to chars of arg 1
                   19472:        addl2   $4*schar,r10    # point to chars of arg 2
                   19473:                                # set loop counter
                   19474: #
                   19475: #      LOOP TO COMPARE CHARACTERS. NOTE THAT WA CANNOT BE ZERO
                   19476: #      SINCE ALL NULL STRINGS POINT TO NULLS AND GIVE XL=XR.
                   19477: #
                   19478: iden3: cmpl    (r9),(r10)      # differ if chars do not match
                   19479:        bnequ   iden8
                   19480:        addl2   $4,r9           # else bump arg one pointer
                   19481:        addl2   $4,r10          # bump arg two pointer
                   19482:        sobgtr  r8,iden3        # loop back till all checked
                   19483:        #page   
                   19484: #
                   19485: #      IDENT (CONTINUED)
                   19486: #
                   19487: #      HERE TO EXIT FOR CASE OF TWO IDENT STRINGS
                   19488: #
                   19489:        clrl    r10             # clear garbage value in xl
                   19490:        clrl    r9              # clear garbage value in xr
                   19491:        movl    (sp)+,r11       # take ident exit
                   19492:        jmp     *(r11)+
                   19493: #
                   19494: #      HERE FOR INTEGERS, IDENT IF SAME VALUES
                   19495: #
                   19496: iden4: movl    4*icval(r9),r5  # load arg 1
                   19497:        subl2   4*icval(r10),r5 # subtract arg 2 to compare
                   19498:        bvs     iden1
                   19499:        tstl    r5              # differ if result is not zero
                   19500:        bneq    iden1
                   19501:        movl    (sp)+,r11       # take ident exit
                   19502:        jmp     *(r11)+
                   19503: #
                   19504: #      HERE FOR REALS, IDENT IF SAME VALUES
                   19505: #
                   19506: iden5: movf    4*rcval(r9),r2  # load arg 1
                   19507:        subf2   4*rcval(r10),r2 # subtract arg 2 to compare
                   19508:        bvs     iden1
                   19509:        tstf    r2              # differ if result is not zero
                   19510:        bneq    iden1
                   19511:        movl    (sp)+,r11       # take ident exit
                   19512:        jmp     *(r11)+
                   19513: #
                   19514: #      HERE FOR NAMES, IDENT IF BASES AND OFFSETS SAME
                   19515: #
                   19516: iden6: cmpl    4*nmofs(r9),4*nmofs(r10) # differ if different offset
                   19517:        bnequ   iden1
                   19518:        cmpl    4*nmbas(r9),4*nmbas(r10) # differ if different base
                   19519:        bnequ   iden1
                   19520: #
                   19521: #      MERGE HERE TO SIGNAL IDENT FOR IDENTICAL POINTERS
                   19522: #
                   19523: iden7: movl    (sp)+,r11       # take ident exit
                   19524:        jmp     *(r11)+
                   19525: #
                   19526: #      HERE FOR DIFFER STRINGS
                   19527: #
                   19528: iden8: clrl    r9              # clear garbage ptr in xr
                   19529:        clrl    r10             # clear garbage ptr in xl
                   19530:        addl2   $4*1,(sp)       # return to caller (differ)
                   19531:        rsb     
                   19532:        #enp                    # end procedure ident
                   19533:        #page   
                   19534: #
                   19535: #      INOUT - USED TO INITIALISE INPUT AND OUTPUT VARIABLES
                   19536: #
                   19537: #      (XL)                  POINTER TO VBL NAME STRING
                   19538: #      (WB)                  TRBLK TYPE
                   19539: #      JSR  INOUT            CALL TO PERFORM INITIALISATION
                   19540: #      (XL)                  VRBLK PTR
                   19541: #      (XR)                  TRBLK PTR
                   19542: #      (WA,WC)               DESTROYED
                   19543: #
                   19544: #      NOTE THAT TRTER (= TRTRF) FIELD OF STANDARD I/O VARIABLES
                   19545: #      POINTS TO CORRESPONDING SVBLK NOT TO A TRBLK AS IS THE
                   19546: #      CASE FOR ORDINARY VARIABLES.
                   19547: #
                   19548: inout: #prc                    # entry point
                   19549:        movl    r7,-(sp)        # stack trblk type
                   19550:        movl    4*sclen(r10),r6 # get name length
                   19551:        clrl    r7              # point to start of name
                   19552:        jsb     sbstr           # build a proper scblk
                   19553:        jsb     gtnvr           # build vrblk
                   19554:        .long   invalid$        # no error return
                   19555:        movl    r9,r8           # save vrblk pointer
                   19556:        movl    (sp)+,r7        # get trter field
                   19557:        clrl    r10             # zero trfpt
                   19558:        jsb     trbld           # build trblk
                   19559:        movl    r8,r10          # recall vrblk pointer
                   19560:        movl    4*vrsvp(r10),4*trter(r9) # store svblk pointer
                   19561:        movl    r9,4*vrval(r10) # store trblk ptr in vrblk
                   19562:        movl    $b$vra,4*vrget(r10) # set trapped access
                   19563:        movl    $b$vrv,4*vrsto(r10) # set trapped store
                   19564:        rsb                     # return to caller
                   19565:        #enp                    # end procedure inout
                   19566:        #page   
                   19567: #
                   19568: #      INSBF -- INSERT STRING IN BUFFER
                   19569: #
                   19570: #      THIS ROUTINE WILL REPLACE A SECTION OF A BUFFER WITH THE
                   19571: #      CONTENTS OF A GIVEN STRING.  IF THE LENGTH OF THE
                   19572: #      SECTION TO BE REPLACED IS DIFFERENT THAN THE LENGTH OF
                   19573: #      THE GIVEN STRING, AND THE REPLACEMENT IS NOT AN APPEND,
                   19574: #      THEN THE UPPER SECTION OF THE BUFFER IS SHIFTED UP OR
                   19575: #      DOWN TO CREATE THE PROPER SPACE FOR THE INSERT.
                   19576: #
                   19577: #      (XR)                  POINTER TO BFBLK
                   19578: #      (XL)                  OBJECT WHICH IS STRING CONVERTABLE
                   19579: #      (WA)                  OFFSET OF START OF INSERT IN (XR)
                   19580: #      (WB)                  LENGTH OF SECTION IN (XR) REPLACED
                   19581: #      JSR  INSBF            CALL TO INSERT CHARACTERS IN BUFFER
                   19582: #      PPM  LOC              THREAD IF (XR) NOT CONVERTABLE
                   19583: #      PPM  LOC              THREAD IF INSERT NOT POSSIBLE
                   19584: #
                   19585: #      THE SECOND ALTERNATE EXIT IS TAKEN IF THE INSERT WOULD
                   19586: #      OVERFLOW THE BUFFER, OR IF THE INSERT IS OUT PAST THE
                   19587: #      DEFINED END OF THE BUFFER AS GIVEN.
                   19588: #
                   19589: insbf: #prc                    # entry point
                   19590:        movl    r6,inssa        # save entry wa
                   19591:        movl    r7,inssb        # save entry wb
                   19592:        movl    r8,inssc        # save entry wc
                   19593:        addl2   r7,r6           # add to get offset past replace part
                   19594:        movl    r6,insab        # save wa+wb
                   19595:        movl    4*bclen(r9),r8  # get current defined length
                   19596:        cmpl    inssa,r8        # fail if start offset too big
                   19597:        blequ   0f
                   19598:        jmp     ins07
                   19599: 0:             
                   19600:        cmpl    r6,r8           # fail if final offset too big
                   19601:        blequ   0f
                   19602:        jmp     ins07
                   19603: 0:             
                   19604:        movl    r10,-(sp)       # save entry xl
                   19605:        movl    r9,-(sp)        # save bcblk ptr
                   19606:        movl    r10,-(sp)       # stack again for gtstg
                   19607:        jsb     gtstg           # call to convert to string
                   19608:        .long   ins05           # take string convert err exit
                   19609:        movl    r9,r10          # save string ptr
                   19610:        movl    (sp),r9         # restore bcblk ptr
                   19611:        addl2   r8,r6           # add buffer len to string len
                   19612:        subl2   inssb,r6        # bias out component being replaced
                   19613:        movl    4*bcbuf(r9),r9  # point to bfblk
                   19614:        cmpl    r6,4*bfalc(r9)  # fail if result exceeds allocation
                   19615:        blequ   0f
                   19616:        jmp     ins06
                   19617: 0:             
                   19618:        movl    (sp),r9         # restore bcblk ptr
                   19619:        movl    r8,r6           # get buffer length
                   19620:        subl2   insab,r6        # subtract to get shift length
                   19621:        addl2   4*sclen(r10),r8 # add length of new
                   19622:        subl2   inssb,r8        # subtract old to get total new len
                   19623:        movl    4*bclen(r9),r7  # get old bclen
                   19624:        movl    r8,4*bclen(r9)  # stuff new length
                   19625:        tstl    r6              # skip shift if nothing to do
                   19626:        bnequ   0f
                   19627:        jmp     ins04
                   19628: 0:             
                   19629:        cmpl    inssb,4*sclen(r10) # skip shift if lengths match
                   19630:        bnequ   0f
                   19631:        jmp     ins04
                   19632: 0:             
                   19633:        movl    4*bcbuf(r9),r9  # point to bfblk
                   19634:        movl    r10,-(sp)       # save scblk ptr
                   19635:        cmpl    inssb,4*sclen(r10) # brn if shft is for more room
                   19636:        blequ   ins01
                   19637:        #page   
                   19638: #
                   19639: #      INSBF (CONTINUED)
                   19640: #
                   19641: #      WE ARE SHIFTING THE UPPER SEGMENT DOWN TO COMPACT
                   19642: #      THE BUFFER.  (THE STRING LENGTH IS SMALLER THAN THE
                   19643: #      SEGMENT BEING REPLACED.)  REGISTERS ARE SET AS:
                   19644: #
                   19645: #      (WA)                  MOVE (SHIFT DOWN) LENGTH
                   19646: #      (WB)                  OLD BCLEN
                   19647: #      (WC)                  NEW BCLEN
                   19648: #      (XR)                  BFBLK PTR
                   19649: #      (XL),(XS)             SCBLK PTR
                   19650: #
                   19651:        movl    inssa,r7        # get offset to insert
                   19652:        addl2   4*sclen(r10),r7 # add insert length to get dest off
                   19653:        movl    r9,r10          # make copy
                   19654:        movl    insab,r11       # [get in scratch register]
                   19655:        movab   cfp$f(r10)[r11],r10 # prepare source for move
                   19656:        movab   cfp$f(r9)[r7],r9# prepare destination reg for move
                   19657:        jsb     sbmvc           # move em out
                   19658:        jmp     ins02           # branch to pad
                   19659: #
                   19660: #      WE ARE SHIFTING THE UPPER SEGMENT UP TO EXPAND
                   19661: #      THE BUFFER.  (THE STRING LENGTH IS LARGER THAN THE
                   19662: #      SEGMENT BEING REPLACED.)
                   19663: #
                   19664: ins01: movl    r9,r10          # copy bfblk ptr
                   19665:        movab   cfp$f(r10)[r7],r10 # set source reg for move backwards
                   19666:        movab   cfp$f(r9)[r8],r9# set destination ptr for move
                   19667:        jsb     sbmcb           # move backwards (possible overlap)
                   19668: #
                   19669: #      MERGE HERE AFTER MOVE TO ADJUST PADDING AT NEW BUFFER END
                   19670: #
                   19671: ins02: movl    (sp)+,r10       # restore scblk ptr
                   19672:        movl    r8,r6           # copy new buffer end
                   19673:        movab   3+(4*0)(r6),r6  # round out
                   19674:        bicl2   $3,r6
                   19675:        subl2   r8,r6           # subtract to get remainder
                   19676:        bnequ   0f              # no pad if already even boundary
                   19677:        jmp     ins04
                   19678: 0:             
                   19679:        movl    (sp),r9         # get bcblk ptr
                   19680:        movl    4*bcbuf(r9),r9  # get bfblk ptr
                   19681:        movab   cfp$f(r9)[r8],r9# prepare to pad
                   19682:        clrl    r7              # clear wb
                   19683:                                # load loop count
                   19684: #
                   19685: #      LOOP HERE TO STUFF PAD CHARACTERS
                   19686: #
                   19687: ins03: movb    r7,(r9)+        # stuff zero pad
                   19688:        sobgtr  r6,ins03        # branch for more
                   19689:        #page   
                   19690: #
                   19691: #      INSBF (CONTINUED)
                   19692: #
                   19693: #      MERGE HERE WHEN PADDING OK.  NOW COPY IN THE INSERT
                   19694: #      STRING TO THE HOLE.
                   19695: #
                   19696: ins04: movl    (sp),r9         # get bcblk ptr
                   19697:        movl    4*bcbuf(r9),r9  # get bfblk ptr
                   19698:        movl    4*sclen(r10),r6 # get move length
                   19699:        movab   cfp$f(r10),r10  # prepare to copy from first char
                   19700:        movl    inssa,r11       # [get in scratch register]
                   19701:        movab   cfp$f(r9)[r11],r9# prepare to store in hole
                   19702:        jsb     sbmvc           # copy the characters
                   19703:        movl    (sp)+,r9        # restore entry xr
                   19704:        movl    (sp)+,r10       # restore entry xl
                   19705:        movl    inssa,r6        # restore entry wa
                   19706:        movl    inssb,r7        # restore entry wb
                   19707:        movl    inssc,r8        # restore entry wc
                   19708:        addl2   $4*2,(sp)       # return to caller
                   19709:        rsb     
                   19710: #
                   19711: #      HERE TO TAKE STRING CONVERT ERROR EXIT
                   19712: #
                   19713: ins05: movl    (sp)+,r9        # restore entry xr
                   19714:        movl    (sp)+,r10       # restore entry xl
                   19715:        movl    inssa,r6        # restore entry wa
                   19716:        movl    inssb,r7        # restore entry wb
                   19717:        movl    inssc,r8        # restore entry wc
                   19718:        movl    (sp)+,r11       # alternate exit
                   19719:        jmp     *(r11)+
                   19720: #
                   19721: #      HERE FOR INVALID OFFSET OR LENGTH
                   19722: #
                   19723: ins06: movl    (sp)+,r9        # restore entry xr
                   19724:        movl    (sp)+,r10       # restore entry xl
                   19725: #
                   19726: #      MERGE FOR LENGTH FAILURE EXIT WITH STACK SET
                   19727: #
                   19728: ins07: movl    inssa,r6        # restore entry wa
                   19729:        movl    inssb,r7        # restore entry wb
                   19730:        movl    inssc,r8        # restore entry wc
                   19731:        addl3   $4*1,(sp)+,r11  # alternate exit
                   19732:        jmp     *(r11)+
                   19733:        #enp                    # end procedure insbf
                   19734:        #page   
                   19735: #
                   19736: #      IOFCB -- GET INPUT/OUTPUT FCBLK POINTER
                   19737: #
                   19738: #      USED BY ENDFILE, EJECT AND REWIND TO FIND THE FCBLK
                   19739: #      (IF ANY) CORRESPONDING TO THEIR ARGUMENT.
                   19740: #
                   19741: #      -(XS)                 ARGUMENT
                   19742: #      JSR  IOFCB            CALL TO FIND FCBLK
                   19743: #      PPM  LOC              ARG IS AN UNSUITABLE NAME
                   19744: #      PPM  LOC              ARG IS NULL STRING
                   19745: #      (XS)                  POPPED
                   19746: #      (XL)                  PTR TO FILEARG1 VRBLK
                   19747: #      (XR)                  ARGUMENT
                   19748: #      (WA)                  FCBLK PTR OR 0
                   19749: #      (WB)                  DESTROYED
                   19750: #
                   19751:        .data   1
                   19752: iofcb_s:       .long   0
                   19753:        .text   0
                   19754: iofcb: movl    (sp)+,iofcb_s   # entry point
                   19755:        jsb     gtstg           # get arg as string
                   19756:        .long   iofc2           # fail
                   19757:        movl    r9,r10          # copy string ptr
                   19758:        jsb     gtnvr           # get as natural variable
                   19759:        .long   iofc3           # fail if null
                   19760:        movl    r10,r7          # copy string pointer again
                   19761:        movl    r9,r10          # copy vrblk ptr for return
                   19762:        clrl    r6              # in case no trblk found
                   19763: #
                   19764: #      LOOP TO FIND FILE ARG1 TRBLK
                   19765: #
                   19766: iofc1: movl    4*vrval(r9),r9  # get possible trblk ptr
                   19767:        cmpl    (r9),$b$trt     # fail if end of chain
                   19768:        bnequ   iofc2
                   19769:        cmpl    4*trtyp(r9),$trtfc # loop if not file arg trblk
                   19770:        bnequ   iofc1
                   19771:        movl    4*trfpt(r9),r6  # get fcblk ptr
                   19772:        movl    r7,r9           # copy arg
                   19773:        addl3   $4*2,iofcb_s,r11        # return
                   19774:        jmp     (r11)
                   19775: #
                   19776: #      FAIL RETURN
                   19777: #
                   19778: iofc2: movl    iofcb_s,r11     # fail
                   19779:        jmp     *(r11)+
                   19780: #
                   19781: #      NULL ARG
                   19782: #
                   19783: iofc3: addl3   $4*1,iofcb_s,r11        # null arg return
                   19784:        jmp     *(r11)+
                   19785:        #enp                    # end procedure iofcb
                   19786:        #page   
                   19787: #
                   19788: #      IOPPF -- PROCESS FILEARG2 FOR IOPUT
                   19789: #
                   19790: #      (R$XSC)               FILEARG2 PTR
                   19791: #      JSR  IOPPF            CALL TO PROCESS FILEARG2
                   19792: #      (XL)                  FILEARG1 PTR
                   19793: #      (XR)                  FILE ARG2 PTR
                   19794: #      -(XS)..-(XS)          FIELDS EXTRACTED FROM FILEARG2
                   19795: #      (WC)                  NO. OF FIELDS EXTRACTED
                   19796: #      (WB)                  INPUT/OUTPUT FLAG
                   19797: #      (WA)                  FCBLK PTR OR 0
                   19798: #
                   19799:        .data   1
                   19800: ioppf_s:       .long   0
                   19801:        .text   0
                   19802: ioppf: movl    (sp)+,ioppf_s   # entry point
                   19803:        clrl    r7              # to count fields extracted
                   19804: #
                   19805: #      LOOP TO EXTRACT FIELDS
                   19806: #
                   19807: iopp1: movl    $iodel,r10      # get delimiter
                   19808:        movl    r10,r8          # copy it
                   19809:        jsb     xscan           # get next field
                   19810:        movl    r9,-(sp)        # stack it
                   19811:        incl    r7              # increment count
                   19812:        tstl    r6              # loop
                   19813:        bnequ   iopp1
                   19814:        movl    r7,r8           # count of fields
                   19815:        movl    ioptt,r7        # i/o marker
                   19816:        movl    r$iof,r6        # fcblk ptr or 0
                   19817:        movl    r$io2,r9        # file arg2 ptr
                   19818:        movl    r$io1,r10       # filearg1
                   19819:        jmp     *ioppf_s        # return
                   19820:        #enp                    # end procedure ioppf
                   19821:        #page   
                   19822: #
                   19823: #      IOPUT -- ROUTINE USED BY INPUT AND OUTPUT
                   19824: #
                   19825: #      IOPUT SETS UP INPUT/OUTPUT  ASSOCIATIONS. IT BUILDS
                   19826: #      SUCH TRACE AND FILE CONTROL BLOCKS AS ARE NECESSARY AND
                   19827: #      CALLS SYSFC,SYSIO TO PERFORM CHECKS ON THE
                   19828: #      ARGUMENTS AND TO OPEN THE FILES.
                   19829: #
                   19830: #         +-----------+   +---------------+       +-----------+
                   19831: #      +-.I           I   I               I------.I   =B$XRT  I
                   19832: #      I  +-----------+   +---------------+       +-----------+
                   19833: #      I  /           /        (R$FCB)            I    *4     I
                   19834: #      I  /           /                           +-----------+
                   19835: #      I  +-----------+   +---------------+       I           I-
                   19836: #      I  I   NAME    +--.I    =B$TRT     I       +-----------+
                   19837: #      I  /           /   +---------------+       I           I
                   19838: #      I   (FIRST ARG)    I =TRTIN/=TRTOU I       +-----------+
                   19839: #      I                  +---------------+             I
                   19840: #      I                  I     VALUE     I             I
                   19841: #      I                  +---------------+             I
                   19842: #      I                  I(TRTRF) 0   OR I--+          I
                   19843: #      I                  +---------------+  I          I
                   19844: #      I                  I(TRFPT) 0   OR I----+        I
                   19845: #      I                  +---------------+  I I        I
                   19846: #      I                     (I/O TRBLK)     I I        I
                   19847: #      I  +-----------+                      I I        I
                   19848: #      I  I           I                      I I        I
                   19849: #      I  +-----------+                      I I        I
                   19850: #      I  I           I                      I I        I
                   19851: #      I  +-----------+   +---------------+  I I        I
                   19852: #      I  I           +--.I    =B$TRT     I.-+ I        I
                   19853: #      I  +-----------+   +---------------+    I        I
                   19854: #      I  /           /   I    =TRTFC     I    I        I
                   19855: #      I  /           /   +---------------+    I        I
                   19856: #      I    (FILEARG1     I     VALUE     I    I        I
                   19857: #      I         VRBLK)   +---------------+    I        I
                   19858: #      I                  I(TRTRF) 0   OR I--+ I        .
                   19859: #      I                  +---------------+  I .  +-----------+
                   19860: #      I                  I(TRFPT) 0   OR I------./   FCBLK   /
                   19861: #      I                  +---------------+  I    +-----------+
                   19862: #      I                       (TRTRF)       I
                   19863: #      I                                     I
                   19864: #      I                                     I
                   19865: #      I                  +---------------+  I
                   19866: #      I                  I    =B$XRT     I.-+
                   19867: #      I                  +---------------+
                   19868: #      I                  I      *5       I
                   19869: #      I                  +---------------+
                   19870: #      +------------------I               I
                   19871: #                         +---------------+       +-----------+
                   19872: #                         I(TRTRF) O   OR I------.I  =B$XRT   I
                   19873: #                         +---------------+       +-----------+
                   19874: #                         I  NAME OFFSET  I       I    ETC    I
                   19875: #                         +---------------+
                   19876: #                           (IOCHN - CHAIN OF NAME POINTERS)
                   19877:        #page   
                   19878: #
                   19879: #      IOPUT (CONTINUED)
                   19880: #
                   19881: #      NO ADDITIONAL TRAP BLOCKS ARE USED FOR STANDARD INPUT/OUT
                   19882: #      FILES. OTHERWISE AN I/O TRAP BLOCK IS ATTACHED TO SECOND
                   19883: #      ARG (FILEARG1) VRBLK. SEE DIAGRAM ABOVE FOR DETAILS OF
                   19884: #      THE STRUCTURE BUILT.
                   19885: #
                   19886: #      -(XS)                 1ST ARG (VBL TO BE ASSOCIATED)
                   19887: #      -(XS)                 2ND ARG (FILE ARG1)
                   19888: #      -(XS)                 3RD ARG (FILE ARG2)
                   19889: #      (WB)                  0 FOR INPUT, 3 FOR OUTPUT ASSOC.
                   19890: #      JSR  IOPUT            CALL FOR INPUT/OUTPUT ASSOCIATION
                   19891: #      PPM  LOC              3RD ARG NOT A STRING
                   19892: #      PPM  LOC              2ND ARG NOT A SUITABLE NAME
                   19893: #      PPM  LOC              1ST ARG NOT A SUITABLE NAME
                   19894: #      PPM  LOC              INAPPROPRIATE FILE SPEC FOR I/O
                   19895: #      PPM  LOC              I/O FILE DOES NOT EXIST
                   19896: #      PPM  LOC              I/O FILE CANNOT BE READ/WRITTEN
                   19897: #      (XS)                  POPPED
                   19898: #      (XL,XR,WA,WB,WC)      DESTROYED
                   19899: #
                   19900:        .data   1
                   19901: ioput_s:       .long   0
                   19902:        .text   0
                   19903: ioput: movl    (sp)+,ioput_s   # entry point
                   19904:        clrl    r$iot           # in case no trtrf block used
                   19905:        clrl    r$iof           # in case no fcblk alocated
                   19906:        movl    r7,ioptt        # store i/o trace type
                   19907:        jsb     xscni           # prepare to scan filearg2
                   19908:        .long   iop13           # fail
                   19909:        .long   iopa0           # null file arg2
                   19910: #
                   19911: iopa0: movl    r9,r$io2        # keep file arg2
                   19912:        movl    r6,r10          # copy length
                   19913:        jsb     gtstg           # convert filearg1 to string
                   19914:        .long   iop14           # fail
                   19915:        movl    r9,r$io1        # keep filearg1 ptr
                   19916:        jsb     gtnvr           # convert to natural variable
                   19917:        .long   iop00           # jump if null
                   19918:        jmp     iop04           # jump to process non-null args
                   19919: #
                   19920: #      NULL FILEARG1
                   19921: #
                   19922: iop00: tstl    r10             # skip if both args null
                   19923:        bnequ   0f
                   19924:        jmp     iop01
                   19925: 0:             
                   19926:        jsb     ioppf           # process filearg2
                   19927:        jsb     sysfc           # call for filearg2 check
                   19928:        .long   iop16           # fail
                   19929:        jmp     iop11           # complete file association
                   19930:        #page   
                   19931: #
                   19932: #      IOPUT (CONTINUED)
                   19933: #
                   19934: #      HERE WITH 0 OR FCBLK PTR IN (XL)
                   19935: #
                   19936: iop01: movl    ioptt,r7        # get trace type
                   19937:        movl    r$iot,r9        # get 0 or trtrf ptr
                   19938:        jsb     trbld           # build trblk
                   19939:        movl    r9,r8           # copy trblk pointer
                   19940:        movl    (sp)+,r9        # get variable from stack
                   19941:        jsb     gtvar           # point to variable
                   19942:        .long   iop15           # fail
                   19943:        movl    r10,r$ion       # save name pointer
                   19944:        movl    r10,r9          # copy name pointer
                   19945:        addl2   r6,r9           # point to variable
                   19946:        subl2   $4*vrval,r9     # subtract offset,merge into loop
                   19947: #
                   19948: #      LOOP TO END OF TRBLK CHAIN IF ANY
                   19949: #
                   19950: iop02: movl    r9,r10          # copy blk ptr
                   19951:        movl    4*vrval(r9),r9  # load ptr to next trblk
                   19952:        cmpl    (r9),$b$trt     # jump if not trapped
                   19953:        bnequ   iop03
                   19954:        cmpl    4*trtyp(r9),ioptt# loop if not same assocn
                   19955:        bnequ   iop02
                   19956:        movl    4*trnxt(r9),r9  # get value and delete old trblk
                   19957: #
                   19958: #      IOPUT (CONTINUED)
                   19959: #
                   19960: #      STORE NEW ASSOCIATION
                   19961: #
                   19962: iop03: movl    r8,4*vrval(r10) # link to this trblk
                   19963:        movl    r8,r10          # copy pointer
                   19964:        movl    r9,4*trnxt(r10) # store value in trblk
                   19965:        movl    r$ion,r9        # restore possible vrblk pointer
                   19966:        movl    r6,r7           # keep offset to name
                   19967:        jsb     setvr           # if vrblk, set vrget,vrsto
                   19968:        movl    r$iot,r9        # get 0 or trtrf ptr
                   19969:        beqlu   0f              # jump if trtrf block exists
                   19970:        jmp     iop19
                   19971: 0:             
                   19972:        addl3   $4*6,ioput_s,r11        # return to caller
                   19973:        jmp     (r11)
                   19974: #
                   19975: #      NON STANDARD FILE
                   19976: #      SEE IF AN FCBLK HAS ALREADY BEEN ALLOCATED.
                   19977: #
                   19978: iop04: clrl    r6              # in case no fcblk found
                   19979:        #page   
                   19980: #
                   19981: #      IOPUT (CONTINUED)
                   19982: #
                   19983: #      SEARCH POSSIBLE TRBLK CHAIN TO PICK UP THE FCBLK
                   19984: #
                   19985: iop05: movl    r9,r7           # remember blk ptr
                   19986:        movl    4*vrval(r9),r9  # chain along
                   19987:        cmpl    (r9),$b$trt     # jump if end of trblk chain
                   19988:        bnequ   iop06
                   19989:        cmpl    4*trtyp(r9),$trtfc # loop if more to go
                   19990:        bnequ   iop05
                   19991:        movl    r9,r$iot        # point to file arg1 trblk
                   19992:        movl    4*trfpt(r9),r6  # get fcblk ptr from trblk
                   19993: #
                   19994: #      WA = 0 OR FCBLK PTR
                   19995: #      WB = PTR TO PRECEDING BLK TO WHICH ANY TRTRF BLOCK
                   19996: #           FOR FILE ARG1 MUST BE CHAINED.
                   19997: #
                   19998: iop06: movl    r6,r$iof        # keep possible fcblk ptr
                   19999:        movl    r7,r$iop        # keep preceding blk ptr
                   20000:        jsb     ioppf           # process filearg2
                   20001:        jsb     sysfc           # see if fcblk required
                   20002:        .long   iop16           # fail
                   20003:        tstl    r6              # skip if no new fcblk wanted
                   20004:        bnequ   0f
                   20005:        jmp     iop12
                   20006: 0:             
                   20007:        cmpl    r8,$num02       # jump if fcblk in dynamic
                   20008:        blssu   iop6a
                   20009:        jsb     alost           # get it in static
                   20010:        jmp     iop6b           # skip
                   20011: #
                   20012: #      OBTAIN FCBLK IN DYNAMIC
                   20013: #
                   20014: iop6a: jsb     alloc           # get space for fcblk
                   20015: #
                   20016: #      MERGE
                   20017: #
                   20018: iop6b: movl    r9,r10          # point to fcblk
                   20019:        movl    r6,r7           # copy its length
                   20020:        ashl    $-2,r7,r7       # get count as words (sgd apr80)
                   20021:                                # loop counter
                   20022: #
                   20023: #      CLEAR FCBLK
                   20024: #
                   20025: iop07: clrl    (r9)+           # clear a word
                   20026:        sobgtr  r7,iop07        # loop
                   20027:        cmpl    r8,$num02       # skip if in static - dont set fields
                   20028:        bnequ   0f
                   20029:        jmp     iop09
                   20030: 0:             
                   20031:        movl    $b$xnt,(r10)    # store xnblk code in case
                   20032:        movl    r6,4*1(r10)     # store length
                   20033:        tstl    r8              # jump if xnblk wanted
                   20034:        beqlu   0f
                   20035:        jmp     iop09
                   20036: 0:             
                   20037:        movl    $b$xrt,(r10)    # xrblk code requested
                   20038: #
                   20039:        #page   
                   20040: #      IOPUT (CONTINUED)
                   20041: #
                   20042: #      COMPLETE FCBLK INITIALISATION
                   20043: #
                   20044: iop09: movl    r$iot,r9        # get possible trblk ptr
                   20045:        movl    r10,r$iof       # store fcblk ptr
                   20046:        tstl    r9              # jump if trblk already found
                   20047:        bnequ   iop10
                   20048: #
                   20049: #      A NEW TRBLK IS NEEDED
                   20050: #
                   20051:        movl    $trtfc,r7       # trtyp for fcblk trap blk
                   20052:        jsb     trbld           # make the block
                   20053:        movl    r9,r$iot        # copy trtrf ptr
                   20054:        movl    r$iop,r10       # point to preceding blk
                   20055:        movl    4*vrval(r10),4*vrval(r9) # copy value field to trblk
                   20056:        movl    r9,4*vrval(r10) # link new trblk into chain
                   20057:        movl    r10,r9          # point to predecessor blk
                   20058:        jsb     setvr           # set trace intercepts
                   20059:        movl    4*vrval(r9),r9  # recover trblk ptr
                   20060: #
                   20061: #      XR IS PTR TO TRBLK, XL IS FCBLK PTR OR 0
                   20062: #
                   20063: iop10: movl    r$iof,4*trfpt(r9)# store fcblk ptr
                   20064: #
                   20065: #      CALL SYSIO TO COMPLETE FILE ACCESSING
                   20066: #
                   20067: iop11: movl    r$iof,r6        # copy fcblk ptr or 0
                   20068:        movl    ioptt,r7        # get input/output flag
                   20069:        movl    r$io2,r9        # get file arg2
                   20070:        movl    r$io1,r10       # get file arg1
                   20071:        jsb     sysio           # associate to the file
                   20072:        .long   iop17           # fail
                   20073:        .long   iop18           # fail
                   20074:        tstl    r$iot           # not std input if non-null trtrf blk
                   20075:        beqlu   0f
                   20076:        jmp     iop01
                   20077: 0:             
                   20078:        tstl    ioptt           # jump if output
                   20079:        beqlu   0f
                   20080:        jmp     iop01
                   20081: 0:             
                   20082:        tstl    r8              # no change to standard read length
                   20083:        bnequ   0f
                   20084:        jmp     iop01
                   20085: 0:             
                   20086:        movl    r8,cswin        # store new read length for std file
                   20087:        jmp     iop01           # merge to finish the task
                   20088: #
                   20089: #      SYSFC MAY HAVE RETURNED A POINTER TO A PRIVATE FCBLK
                   20090: #
                   20091: iop12: tstl    r10             # jump if private fcblk
                   20092:        beqlu   0f
                   20093:        jmp     iop09
                   20094: 0:             
                   20095:        jmp     iop11           # finish the association
                   20096: #
                   20097: #      FAILURE RETURNS
                   20098: #
                   20099: iop13: movl    ioput_s,r11     # 3rd arg not a string
                   20100:        jmp     *(r11)+
                   20101: iop14: addl3   $4*1,ioput_s,r11        # 2nd arg unsuitable
                   20102:        jmp     *(r11)+
                   20103: iop15: addl3   $4*2,ioput_s,r11        # 1st arg unsuitable
                   20104:        jmp     *(r11)+
                   20105: iop16: addl3   $4*3,ioput_s,r11        # file spec wrong
                   20106:        jmp     *(r11)+
                   20107: iop17: addl3   $4*4,ioput_s,r11        # i/o file does not exist
                   20108:        jmp     *(r11)+
                   20109: iop18: addl3   $4*5,ioput_s,r11        # i/o file cannot be read/written
                   20110:        jmp     *(r11)+
                   20111:        #page   
                   20112: #
                   20113: #      IOPUT (CONTINUED)
                   20114: #
                   20115: #      ADD TO IOCHN CHAIN OF ASSSOCIATED VARIABLES UNLESS ALREAD
                   20116: #      PRESENT.
                   20117: #
                   20118: iop19: movl    r$ion,r8        # wc = name base, wb = name offset
                   20119: #
                   20120: #      SEARCH LOOP
                   20121: #
                   20122: iop20: movl    4*trtrf(r9),r9  # next link of chain
                   20123:        beqlu   iop21           # not found
                   20124:        cmpl    r8,4*ionmb(r9)  # no match
                   20125:        bnequ   iop20
                   20126:        cmpl    r7,4*ionmo(r9)  # exit if matched
                   20127:        beqlu   iop22
                   20128:        jmp     iop20           # loop
                   20129: #
                   20130: #      NOT FOUND
                   20131: #
                   20132: iop21: movl    $4*num05,r6     # space needed
                   20133:        jsb     alloc           # get it
                   20134:        movl    $b$xrt,(r9)     # store xrblk code
                   20135:        movl    r6,4*1(r9)      # store length
                   20136:        movl    r8,4*ionmb(r9)  # store name base
                   20137:        movl    r7,4*ionmo(r9)  # store name offset
                   20138:        movl    r$iot,r10       # point to trtrf blk
                   20139:        movl    4*trtrf(r10),r6 # get ptr field contents
                   20140:        movl    r9,4*trtrf(r10) # store ptr to new block
                   20141:        movl    r6,4*trtrf(r9)  # complete the linking
                   20142: #
                   20143: #      INSERT FCBLK ON FCBLK CHAIN FOR SYSEJ, SYSXI
                   20144: #
                   20145: iop22: tstl    r$iof           # skip if no fcblk
                   20146:        beqlu   iop25
                   20147:        movl    r$fcb,r10       # ptr to head of existing chain
                   20148: #
                   20149: #      SEE IF FCBLK ALREADY ON CHAIN
                   20150: #
                   20151: iop23: tstl    r10             # not on if end of chain
                   20152:        beqlu   iop24
                   20153:        cmpl    4*3(r10),r$iof  # dont duplicate if find it
                   20154:        beqlu   iop25
                   20155:        movl    4*2(r10),r10    # get next link
                   20156:        jmp     iop23           # loop
                   20157: #
                   20158: #      NOT FOUND SO ADD AN ENTRY FOR THIS FCBLK
                   20159: #
                   20160: iop24: movl    $4*num04,r6     # space needed
                   20161:        jsb     alloc           # get it
                   20162:        movl    $b$xrt,(r9)     # store block code
                   20163:        movl    r6,4*1(r9)      # store length
                   20164:        movl    r$fcb,4*2(r9)   # store previous link in this node
                   20165:        movl    r$iof,4*3(r9)   # store fcblk ptr
                   20166:        movl    r9,r$fcb        # insert node into fcblk chain
                   20167: #
                   20168: #      RETURN
                   20169: #
                   20170: iop25: addl3   $4*6,ioput_s,r11        # return to caller
                   20171:        jmp     (r11)
                   20172:        #enp                    # end procedure ioput
                   20173:        #page   
                   20174: #
                   20175: #      KTREX -- EXECUTE KEYWORD TRACE
                   20176: #
                   20177: #      KTREX IS USED TO EXECUTE A POSSIBLE KEYWORD TRACE. IT
                   20178: #      INCLUDES THE TEST ON TRACE AND TESTS FOR TRACE ACTIVE.
                   20179: #
                   20180: #      (XL)                  PTR TO TRBLK (OR 0 IF UNTRACED)
                   20181: #      JSR  KTREX            CALL TO EXECUTE KEYWORD TRACE
                   20182: #      (XL,WA,WB,WC)         DESTROYED
                   20183: #      (RA)                  DESTROYED
                   20184: #
                   20185: ktrex: #prc                    # entry point (recursive)
                   20186:        tstl    r10             # immediate exit if keyword untraced
                   20187:        beqlu   ktrx3
                   20188:        tstl    kvtra           # immediate exit if trace = 0
                   20189:        beqlu   ktrx3
                   20190:        decl    kvtra           # else decrement trace
                   20191:        movl    r9,-(sp)        # save xr
                   20192:        movl    r10,r9          # copy trblk pointer
                   20193:        movl    4*trkvr(r9),r10 # load vrblk pointer (nmbas)
                   20194:        movl    $4*vrval,r6     # set name offset
                   20195:        tstl    4*trfnc(r9)     # jump if print trace
                   20196:        beqlu   ktrx1
                   20197:        jsb     trxeq           # else execute full trace
                   20198:        jmp     ktrx2           # and jump to exit
                   20199: #
                   20200: #      HERE FOR PRINT TRACE
                   20201: #
                   20202: ktrx1: movl    r10,-(sp)       # stack vrblk ptr for kwnam
                   20203:        movl    r6,-(sp)        # stack offset for kwnam
                   20204:        jsb     prtsn           # print statement number
                   20205:        movl    $ch$am,r6       # load ampersand
                   20206:        jsb     prtch           # print ampersand
                   20207:        jsb     prtnm           # print keyword name
                   20208:        movl    $tmbeb,r9       # point to blank-equal-blank
                   20209:        jsb     prtst           # print blank-equal-blank
                   20210:        jsb     kwnam           # get keyword pseudo-variable name
                   20211:        movl    r9,dnamp        # reset ptr to delete kvblk
                   20212:        jsb     acess           # get keyword value
                   20213:        .long   invalid$        # failure is impossible
                   20214:        jsb     prtvl           # print keyword value
                   20215:        jsb     prtnl           # terminate print line
                   20216: #
                   20217: #      HERE TO EXIT AFTER COMPLETING TRACE
                   20218: #
                   20219: ktrx2: movl    (sp)+,r9        # restore entry xr
                   20220: #
                   20221: #      MERGE HERE TO EXIT IF NO TRACE REQUIRED
                   20222: #
                   20223: ktrx3: rsb                     # return to ktrex caller
                   20224:        #enp                    # end procedure ktrex
                   20225:        #page   
                   20226: #
                   20227: #      KWNAM -- GET PSEUDO-VARIABLE NAME FOR KEYWORD
                   20228: #
                   20229: #      1(XS)                 NAME BASE FOR VRBLK
                   20230: #      0(XS)                 OFFSET (SHOULD BE *VRVAL)
                   20231: #      JSR  KWNAM            CALL TO GET PSEUDO-VARIABLE NAME
                   20232: #      (XS)                  POPPED TWICE
                   20233: #      (XL,WA)               RESULTING PSEUDO-VARIABLE NAME
                   20234: #      (XR,WA,WB)            DESTROYED
                   20235: #
                   20236:        .data   1
                   20237: kwnam_s:       .long   0
                   20238:        .text   0
                   20239: kwnam: movl    (sp)+,kwnam_s   # entry point
                   20240:        addl2   $4,sp           # ignore name offset
                   20241:        movl    (sp)+,r9        # load name base
                   20242:        cmpl    r9,state        # jump if not natural variable name
                   20243:        bgequ   kwnm1
                   20244:        tstl    4*vrlen(r9)     # error if not system variable
                   20245:        bnequ   kwnm1
                   20246:        movl    4*vrsvp(r9),r9  # else point to svblk
                   20247:        movl    4*svbit(r9),r6  # load bit mask
                   20248:        mcoml   btknm,r11       # and with keyword bit
                   20249:        bicl2   r11,r6
                   20250:        beqlu   kwnm1           # error if no keyword association
                   20251:        movl    4*svlen(r9),r6  # else load name length in characters
                   20252:        movab   3+(4*svchs)(r6),r6 # compute offset to field we want
                   20253:        bicl2   $3,r6
                   20254:        addl2   r6,r9           # point to svknm field
                   20255:        movl    (r9),r7         # load svknm value
                   20256:        movl    $4*kvsi$,r6     # set size of kvblk
                   20257:        jsb     alloc           # allocate kvblk
                   20258:        movl    $b$kvt,(r9)     # store type word
                   20259:        movl    r7,4*kvnum(r9)  # store keyword number
                   20260:        movl    $trbkv,4*kvvar(r9) # set dummy trblk pointer
                   20261:        movl    r9,r10          # copy kvblk pointer
                   20262:        movl    $4*kvvar,r6     # set proper offset
                   20263:        jmp     *kwnam_s        # return to kvnam caller
                   20264: #
                   20265: #      HERE IF NOT KEYWORD NAME
                   20266: #
                   20267: kwnm1: jmp     er_251          # keyword operand is not name of defined keyword
                   20268:        #enp                    # end procedure kwnam
                   20269:        #page   
                   20270: #
                   20271: #      LCOMP-- COMPARE TWO STRINGS LEXICALLY
                   20272: #
                   20273: #      1(XS)                 FIRST ARGUMENT
                   20274: #      0(XS)                 SECOND ARGUMENT
                   20275: #      JSR  LCOMP            CALL TO COMPARE ARUMENTS
                   20276: #      PPM  LOC              TRANSFER LOC FOR ARG1 NOT STRING
                   20277: #      PPM  LOC              TRANSFER LOC FOR ARG2 NOT STRING
                   20278: #      PPM  LOC              TRANSFER LOC IF ARG1 LLT ARG2
                   20279: #      PPM  LOC              TRANSFER LOC IF ARG1 LEQ ARG2
                   20280: #      PPM  LOC              TRANSFER LOC IF ARG1 LGT ARG2
                   20281: #      (THE NORMAL RETURN IS NEVER TAKEN)
                   20282: #      (XS)                  POPPED TWICE
                   20283: #      (XR,XL)               DESTROYED
                   20284: #      (WA,WB,WC,RA)         DESTROYED
                   20285: #
                   20286:        .data   1
                   20287: lcomp_s:       .long   0
                   20288:        .text   0
                   20289: lcomp: movl    (sp)+,lcomp_s   # entry point
                   20290:        jsb     gtstg           # convert second arg to string
                   20291:        .long   lcmp6           # jump if second arg not string
                   20292:        movl    r9,r10          # else save pointer
                   20293:        movl    r6,r7           # and length
                   20294:        jsb     gtstg           # convert first argument to string
                   20295:        .long   lcmp5           # jump if not string
                   20296:        movl    r6,r8           # save arg 1 length
                   20297:        movab   cfp$f(r9),r9    # point to chars of arg 1
                   20298:        movab   cfp$f(r10),r10  # point to chars of arg 2
                   20299:        cmpl    r6,r7           # jump if arg 1 length is smaller
                   20300:        blequ   lcmp1
                   20301:        movl    r7,r6           # else set arg 2 length as smaller
                   20302: #
                   20303: #      HERE WITH SMALLER LENGTH IN (WA)
                   20304: #
                   20305: lcmp1: jsb     sbcmc           # compare strings, jump if unequal
                   20306:        .long   lcmp4
                   20307:        .long   lcmp3
                   20308:        cmpl    r7,r8           # if equal, jump if lengths unequal
                   20309:        bnequ   lcmp2
                   20310:        addl3   $4*3,lcomp_s,r11        # else identical strings, leq exit
                   20311:        jmp     *(r11)+
                   20312:        #page   
                   20313: #
                   20314: #      LCOMP (CONTINUED)
                   20315: #
                   20316: #      HERE IF INITIAL STRINGS IDENTICAL, BUT LENGTHS UNEQUAL
                   20317: #
                   20318: lcmp2: cmpl    r8,r7           # jump if arg 1 length gt arg 2 leng
                   20319:        bgequ   lcmp4
                   20320: #
                   20321: #      HERE IF FIRST ARG LLT SECOND ARG
                   20322: #
                   20323: lcmp3: addl3   $4*2,lcomp_s,r11        # take llt exit
                   20324:        jmp     *(r11)+
                   20325: #
                   20326: #      HERE IF FIRST ARG LGT SECOND ARG
                   20327: #
                   20328: lcmp4: addl3   $4*4,lcomp_s,r11        # take lgt exit
                   20329:        jmp     *(r11)+
                   20330: #
                   20331: #      HERE IF FIRST ARG IS NOT A STRING
                   20332: #
                   20333: lcmp5: movl    lcomp_s,r11     # take bad first arg exit
                   20334:        jmp     *(r11)+
                   20335: #
                   20336: #      HERE FOR SECOND ARG NOT A STRING
                   20337: #
                   20338: lcmp6: addl3   $4*1,lcomp_s,r11        # take bad second arg error exit
                   20339:        jmp     *(r11)+
                   20340:        #enp                    # end procedure lcomp
                   20341:        #page   
                   20342: #
                   20343: #      LISTR -- LIST SOURCE LINE
                   20344: #
                   20345: #      LISTR IS USED TO LIST A SOURCE LINE DURING THE INITIAL
                   20346: #      COMPILATION. IT IS CALLED FROM SCANE AND SCANL.
                   20347: #
                   20348: #      JSR  LISTR            CALL TO LIST LINE
                   20349: #      (XR,XL,WA,WB,WC)      DESTROYED
                   20350: #
                   20351: #      GLOBAL LOCATIONS USED BY LISTR
                   20352: #
                   20353: #      ERLST                 IF LISTING ON ACCOUNT OF AN ERROR
                   20354: #
                   20355: #      LSTLC                 COUNT LINES ON CURRENT PAGE
                   20356: #
                   20357: #      LSTNP                 MAX NUMBER OF LINES/PAGE
                   20358: #
                   20359: #      LSTPF                 SET NON-ZERO IF THE CURRENT SOURCE
                   20360: #                            LINE HAS BEEN LISTED, ELSE ZERO.
                   20361: #
                   20362: #      LSTPG                 COMPILER LISTING PAGE NUMBER
                   20363: #
                   20364: #      LSTSN                 SET IF STMNT NUM TO BE LISTED
                   20365: #
                   20366: #      R$CIM                 POINTER TO CURRENT INPUT LINE.
                   20367: #
                   20368: #      R$TTL                 TITLE FOR SOURCE LISTING
                   20369: #
                   20370: #      R$STL                 PTR TO SUB-TITLE STRING
                   20371: #
                   20372: #      ENTRY POINT
                   20373: #
                   20374: listr: #prc                    # entry point
                   20375:        tstl    cnttl           # jump if -title or -stitl
                   20376:        beqlu   0f
                   20377:        jmp     list5
                   20378: 0:             
                   20379:        tstl    lstpf           # immediate exit if already listed
                   20380:        beqlu   0f
                   20381:        jmp     list4
                   20382: 0:             
                   20383:        cmpl    lstlc,lstnp     # jump if no room
                   20384:        blssu   0f
                   20385:        jmp     list6
                   20386: 0:             
                   20387: #
                   20388: #      HERE AFTER PRINTING TITLE (IF NEEDED)
                   20389: #
                   20390: list0: movl    r$cim,r9        # load pointer to current image
                   20391:        movab   cfp$f(r9),r9    # point to characters
                   20392:        movzbl  (r9),r6         # load first character
                   20393:        movl    lstsn,r9        # load statement number
                   20394:        beqlu   list2           # jump if no statement number
                   20395:        movl    r9,r5           # else get stmnt number as integer
                   20396:        cmpl    stage,$stgic    # skip if execute time
                   20397:        bnequ   list1
                   20398:        cmpl    r6,$ch$as       # no stmnt number list if comment
                   20399:        beqlu   list2
                   20400:        cmpl    r6,$ch$mn       # no stmnt no. if control card
                   20401:        beqlu   list2
                   20402: #
                   20403: #      PRINT STATEMENT NUMBER
                   20404: #
                   20405: list1: jsb     prtin           # else print statement number
                   20406:        clrl    lstsn           # and clear for next time in
                   20407:        #page   
                   20408: #
                   20409: #      LISTR (CONTINUED)
                   20410: #
                   20411: #      MERGE HERE AFTER PRINTING STATEMENT NUMBER (IF REQUIRED)
                   20412: #
                   20413: list2: movl    $stnpd,profs    # point past statement number
                   20414:        movl    r$cim,r9        # load pointer to current image
                   20415:        jsb     prtst           # print it
                   20416:        incl    lstlc           # bump line counter
                   20417:        tstl    erlst           # jump if error copy to int.ch.
                   20418:        bnequ   list3
                   20419:        jsb     prtnl           # terminate line
                   20420:        tstl    cswdb           # jump if -single mode
                   20421:        beqlu   list3
                   20422:        jsb     prtnl           # else add a blank line
                   20423:        incl    lstlc           # and bump line counter
                   20424: #
                   20425: #      HERE AFTER PRINTING SOURCE IMAGE
                   20426: #
                   20427: list3: movl    sp,lstpf        # set flag for line printed
                   20428: #
                   20429: #      MERGE HERE TO EXIT
                   20430: #
                   20431: list4: rsb                     # return to listr caller
                   20432: #
                   20433: #      PRINT TITLE AFTER -TITLE OR -STITL CARD
                   20434: #
                   20435: list5: clrl    cnttl           # clear flag
                   20436: #
                   20437: #      EJECT TO NEW PAGE AND LIST TITLE
                   20438: #
                   20439: list6: jsb     prtps           # eject
                   20440:        tstl    prich           # skip if listing to regular printer
                   20441:        beqlu   list7
                   20442:        cmpl    r$ttl,$nulls    # terminal listing omits null title
                   20443:        bnequ   0f
                   20444:        jmp     list0
                   20445: 0:             
                   20446: #
                   20447: #      LIST TITLE
                   20448: #
                   20449: list7: jsb     listt           # list title
                   20450:        jmp     list0           # merge
                   20451:        #enp                    # end procedure listr
                   20452:        #page   
                   20453: #
                   20454: #      LISTT -- LIST TITLE AND SUBTITLE
                   20455: #
                   20456: #      USED DURING COMPILATION TO PRINT PAGE HEADING
                   20457: #
                   20458: #      JSR  LISTT            CALL TO LIST TITLE
                   20459: #      (XR,WA)               DESTROYED
                   20460: #
                   20461: listt: #prc                    # entry point
                   20462:        movl    r$ttl,r9        # point to source listing title
                   20463:        jsb     prtst           # print title
                   20464:        movl    lstpo,profs     # set offset
                   20465:        movl    $lstms,r9       # set page message
                   20466:        jsb     prtst           # print page message
                   20467:        incl    lstpg           # bump page number
                   20468:        movl    lstpg,r5        # load page number as integer
                   20469:        jsb     prtin           # print page number
                   20470:        jsb     prtnl           # terminate title line
                   20471:        addl2   $num02,lstlc    # count title line and blank line
                   20472: #
                   20473: #      PRINT SUB-TITLE (IF ANY)
                   20474: #
                   20475:        movl    r$stl,r9        # load pointer to sub-title
                   20476:        beqlu   lstt1           # jump if no sub-title
                   20477:        jsb     prtst           # else print sub-title
                   20478:        jsb     prtnl           # terminate line
                   20479:        incl    lstlc           # bump line count
                   20480: #
                   20481: #      RETURN POINT
                   20482: #
                   20483: lstt1: jsb     prtnl           # print a blank line
                   20484:        rsb                     # return to caller
                   20485:        #enp                    # end procedure listt
                   20486:        #page   
                   20487: #
                   20488: #      NEXTS -- ACQUIRE NEXT SOURCE IMAGE
                   20489: #
                   20490: #      NEXTS IS USED TO ACQUIRE THE NEXT SOURCE IMAGE AT COMPILE
                   20491: #      TIME. IT ASSUMES THAT A PRIOR CALL TO READR HAS INPUT
                   20492: #      A LINE IMAGE (SEE PROCEDURE READR). BEFORE THE CURRENT
                   20493: #      IMAGE IS FINALLY LOST IT MAY BE LISTED HERE.
                   20494: #
                   20495: #      JSR  NEXTS            CALL TO ACQUIRE NEXT INPUT LINE
                   20496: #      (XR,XL,WA,WB,WC)      DESTROYED
                   20497: #
                   20498: #      GLOBAL VALUES AFFECTED
                   20499: #
                   20500: #      R$CNI                 ON INPUT, NEXT IMAGE. ON
                   20501: #                            EXIT RESET TO ZERO
                   20502: #
                   20503: #      R$CIM                 ON EXIT, SET TO POINT TO IMAGE
                   20504: #
                   20505: #      SCNIL                 INPUT IMAGE LENGTH ON EXIT
                   20506: #
                   20507: #      SCNSE                 RESET TO ZERO ON EXIT
                   20508: #
                   20509: #      LSTPF                 SET ON EXIT IF LINE IS LISTED
                   20510: #
                   20511: nexts: #prc                    # entry point
                   20512:        tstl    cswls           # jump if -nolist
                   20513:        beqlu   nxts2
                   20514:        movl    r$cim,r9        # point to image
                   20515:        beqlu   nxts2           # jump if no image
                   20516:        movab   cfp$f(r9),r9    # get char ptr
                   20517:        movzbl  (r9),r6         # get first char
                   20518:        cmpl    r6,$ch$mn       # jump if not ctrl card
                   20519:        bnequ   nxts1
                   20520:        tstl    cswpr           # jump if -noprint
                   20521:        beqlu   nxts2
                   20522: #
                   20523: #      HERE TO CALL LISTER
                   20524: #
                   20525: nxts1: jsb     listr           # list line
                   20526: #
                   20527: #      HERE AFTER POSSIBLE LISTING
                   20528: #
                   20529: nxts2: movl    r$cni,r9        # point to next image
                   20530:        movl    r9,r$cim        # set as next image
                   20531:        clrl    r$cni           # clear next image pointer
                   20532:        movl    4*sclen(r9),r6  # get input image length
                   20533:        movl    cswin,r7        # get max allowable length
                   20534:        cmpl    r6,r7           # skip if not too long
                   20535:        blequ   nxts3
                   20536:        movl    r7,r6           # else truncate
                   20537: #
                   20538: #      HERE WITH LENGTH IN (WA)
                   20539: #
                   20540: nxts3: movl    r6,scnil        # use as record length
                   20541:        clrl    scnse           # reset scnse
                   20542:        clrl    lstpf           # set line not listed yet
                   20543:        rsb                     # return to nexts caller
                   20544:        #enp                    # end procedure nexts
                   20545:        #page   
                   20546: #
                   20547: #      PATIN -- PATTERN CONSTRUCTION FOR LEN,POS,RPOS,TAB,RTAB
                   20548: #
                   20549: #      THESE PATTERN TYPES ALL GENERATE A SIMILAR NODE TYPE. SO
                   20550: #      THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION
                   20551: #      FOR ACTUAL ENTRY POINTS FOR THESE FIVE FUNCTIONS.
                   20552: #
                   20553: #      (WA)                  PCODE FOR EXPRESSION ARG CASE
                   20554: #      (WB)                  PCODE FOR INTEGER ARG CASE
                   20555: #      JSR  PATIN            CALL TO BUILD PATTERN NODE
                   20556: #      PPM  LOC              TRANSFER LOC FOR NOT INTEGER OR EXP
                   20557: #      PPM  LOC              TRANSFER LOC FOR INT OUT OF RANGE
                   20558: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20559: #      (XL,WA,WB,WC,IA)      DESTROYED
                   20560: #
                   20561:        .data   1
                   20562: patin_s:       .long   0
                   20563:        .text   0
                   20564: patin: movl    (sp)+,patin_s   # entry point
                   20565:        movl    r6,r10          # preserve expression arg pcode
                   20566:        jsb     gtsmi           # try to convert arg as small integer
                   20567:        .long   ptin2           # jump if not integer
                   20568:        .long   ptin3           # jump if out of range
                   20569: #
                   20570: #      COMMON SUCCESSFUL EXIT POINT
                   20571: #
                   20572: ptin1: jsb     pbild           # build pattern node
                   20573:        addl3   $4*2,patin_s,r11        # return to caller
                   20574:        jmp     (r11)
                   20575: #
                   20576: #      HERE IF ARGUMENT IS NOT AN INTEGER
                   20577: #
                   20578: ptin2: movl    r10,r7          # copy expr arg case pcode
                   20579:        cmpl    (r9),$b$e$$     # all ok if expression arg
                   20580:        blequ   ptin1
                   20581:        movl    patin_s,r11     # else take error exit for wrong type
                   20582:        jmp     *(r11)+
                   20583: #
                   20584: #      HERE FOR ERROR OF OUT OF RANGE INTEGER ARGUMENT
                   20585: #
                   20586: ptin3: addl3   $4*1,patin_s,r11        # take out-of-range error exit
                   20587:        jmp     *(r11)+
                   20588:        #enp                    # end procedure patin
                   20589:        #page   
                   20590: #
                   20591: #      PATST -- PATTERN CONSTRUCTION FOR ANY,NOTANY,
                   20592: #               BREAK,SPAN AND BREAKX PATTERN FUNCTIONS.
                   20593: #
                   20594: #      THESE PATTERN FUNCTIONS BUILD SIMILAR TYPES OF NODES AND
                   20595: #      THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION
                   20596: #      FOR ACTUAL ENTRY POINTS FOR THESE FIVE PATTERN FUNCTIONS.
                   20597: #
                   20598: #      0(XS)                 STRING ARGUMENT
                   20599: #      (WB)                  PCODE FOR ONE CHAR ARGUMENT
                   20600: #      (XL)                  PCODE FOR MULTI-CHAR ARGUMENT
                   20601: #      (WC)                  PCODE FOR EXPRESSION ARGUMENT
                   20602: #      JSR  PATST            CALL TO BUILD NODE
                   20603: #      PPM  LOC              TRANSFER LOC IF NOT STRING OR EXPR
                   20604: #      (XS)                  POPPED PAST STRING ARGUMENT
                   20605: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20606: #      (XL)                  DESTROYED
                   20607: #      (WA,WB,WC,RA)         DESTROYED
                   20608: #
                   20609: #      NOTE THAT THERE IS A SPECIAL CALL TO PATST IN THE EVALS
                   20610: #      PROCEDURE WITH A SLIGHTLY DIFFERENT FORM. SEE EVALS
                   20611: #      FOR DETAILS OF THE FORM OF THIS CALL.
                   20612: #
                   20613:        .data   1
                   20614: patst_s:       .long   0
                   20615:        .text   0
                   20616: patst: movl    (sp)+,patst_s   # entry point
                   20617:        jsb     gtstg           # convert argument as string
                   20618:        .long   pats7           # jump if not string
                   20619:        cmpl    r6,$num01       # jump if not one char string
                   20620:        bnequ   pats2
                   20621: #
                   20622: #      HERE FOR ONE CHAR STRING CASE
                   20623: #
                   20624:        tstl    r7              # treat as multi-char if evals call
                   20625:        beqlu   pats2
                   20626:        movab   cfp$f(r9),r9    # point to character
                   20627:        movzbl  (r9),r9         # load character
                   20628: #
                   20629: #      COMMON EXIT POINT AFTER SUCCESSFUL CONSTRUCTION
                   20630: #
                   20631: pats1: jsb     pbild           # call routine to build node
                   20632:        addl3   $4*1,patst_s,r11        # return to patst caller
                   20633:        jmp     (r11)
                   20634:        #page   
                   20635: #
                   20636: #      PATST (CONTINUED)
                   20637: #
                   20638: #      HERE FOR MULTI-CHARACTER STRING CASE
                   20639: #
                   20640: pats2: movl    r10,-(sp)       # save multi-char pcode
                   20641:        movl    r9,-(sp)        # save string pointer
                   20642:        movl    ctmsk,r8        # load current mask bit
                   20643:        ashl    $1,r8,r8                # shift to next position
                   20644:        tstl    r8              # skip if position left in this tbl
                   20645:        bnequ   pats4
                   20646: #
                   20647: #      HERE WE MUST ALLOCATE A NEW CHARACTER TABLE
                   20648: #
                   20649:        movl    $4*ctsi$,r6     # set size of ctblk
                   20650:        jsb     alloc           # allocate ctblk
                   20651:        movl    r9,r$ctp        # store ptr to new ctblk
                   20652:        movl    $b$ctt,(r9)+    # store type code, bump ptr
                   20653:        movl    $cfp$a,r7       # set number of words to clear
                   20654:        movl    bits0,r8        # load all zero bits
                   20655: #
                   20656: #      LOOP TO CLEAR ALL BITS IN TABLE TO ZEROS
                   20657: #
                   20658: pats3: movl    r8,(r9)+        # move word of zero bits
                   20659:        sobgtr  r7,pats3        # loop till all cleared
                   20660:        movl    bits1,r8        # set initial bit position
                   20661: #
                   20662: #      MERGE HERE WITH BIT POSITION AVAILABLE
                   20663: #
                   20664: pats4: movl    r8,ctmsk        # save parm2 (new bit position)
                   20665:        movl    (sp)+,r10       # restore pointer to argument string
                   20666:        movl    4*sclen(r10),r7 # load string length
                   20667:        beqlu   pats6           # jump if null string case
                   20668:                                # else set loop counter
                   20669:        movab   cfp$f(r10),r10  # point to characters in argument
                   20670:        #page   
                   20671: #
                   20672: #      PATST (CONTINUED)
                   20673: #
                   20674: #      LOOP TO SET BITS IN COLUMN OF TABLE
                   20675: #
                   20676: pats5: movzbl  (r10)+,r6       # load next character
                   20677:        moval   0[r6],r6        # convert to byte offset
                   20678:        movl    r$ctp,r9        # point to ctblk
                   20679:        addl2   r6,r9           # point to ctblk entry
                   20680:        movl    r8,r6           # copy bit mask
                   20681:        bisl2   4*ctchs(r9),r6  # or in bits already set
                   20682:        movl    r6,4*ctchs(r9)  # store resulting bit string
                   20683:        sobgtr  r7,pats5        # loop till all bits set
                   20684: #
                   20685: #      COMPLETE PROCESSING FOR MUTI-CHAR STRING CASE
                   20686: #
                   20687: pats6: movl    r$ctp,r9        # load ctblk ptr as parm1 for pbild
                   20688:        clrl    r10             # clear garbage ptr in xl
                   20689:        movl    (sp)+,r7        # load pcode for multi-char str case
                   20690:        jmp     pats1           # back to exit (wc=bitstring=parm2)
                   20691: #
                   20692: #      HERE IF ARGUMENT IS NOT A STRING
                   20693: #
                   20694: #      NOTE THAT THE CALL FROM EVALS CANNOT PASS AN EXPRESSION
                   20695: #      SINCE EVALP ALWAYS REEVALUATES EXPRESSIONS.
                   20696: #
                   20697: pats7: movl    r8,r7           # set pcode for expression argument
                   20698:        cmpl    (r9),$b$e$$     # jump to exit if expression arg
                   20699:        bgtru   0f
                   20700:        jmp     pats1
                   20701: 0:             
                   20702:        movl    patst_s,r11     # else take wrong type error exit
                   20703:        jmp     *(r11)+
                   20704:        #enp                    # end procedure patst
                   20705:        #page   
                   20706: #
                   20707: #      PBILD -- BUILD PATTERN NODE
                   20708: #
                   20709: #      (XR)                  PARM1 (ONLY IF REQUIRED)
                   20710: #      (WB)                  PCODE FOR NODE
                   20711: #      (WC)                  PARM2 (ONLY IF REQUIRED)
                   20712: #      JSR  PBILD            CALL TO BUILD NODE
                   20713: #      (XR)                  POINTER TO CONSTRUCTED NODE
                   20714: #      (WA)                  DESTROYED
                   20715: #
                   20716: pbild: #prc                    # entry point
                   20717:        movl    r9,-(sp)        # stack possible parm1
                   20718:        movl    r7,r9           # copy pcode
                   20719:        movzwl  -2(r9),r9       # load entry point id (bl$px)
                   20720:        cmpl    r9,$bl$p1       # jump if one parameter
                   20721:        beqlu   pbld1
                   20722:        cmpl    r9,$bl$p0       # jump if no parameters
                   20723:        beqlu   pbld3
                   20724: #
                   20725: #      HERE FOR TWO PARAMETER CASE
                   20726: #
                   20727:        movl    $4*pcsi$,r6     # set size of p2blk
                   20728:        jsb     alloc           # allocate block
                   20729:        movl    r8,4*parm2(r9)  # store second parameter
                   20730:        jmp     pbld2           # merge with one parm case
                   20731: #
                   20732: #      HERE FOR ONE PARAMETER CASE
                   20733: #
                   20734: pbld1: movl    $4*pbsi$,r6     # set size of p1blk
                   20735:        jsb     alloc           # allocate node
                   20736: #
                   20737: #      MERGE HERE FROM TWO PARM CASE
                   20738: #
                   20739: pbld2: movl    (sp),4*parm1(r9)# store first parameter
                   20740:        jmp     pbld4           # merge with no parameter case
                   20741: #
                   20742: #      HERE FOR CASE OF NO PARAMETERS
                   20743: #
                   20744: pbld3: movl    $4*pasi$,r6     # set size of p0blk
                   20745:        jsb     alloc           # allocate node
                   20746: #
                   20747: #      MERGE HERE FROM OTHER CASES
                   20748: #
                   20749: pbld4: movl    r7,(r9)         # store pcode
                   20750:        addl2   $4,sp           # pop first parameter
                   20751:        movl    $ndnth,4*pthen(r9) # set nothen successor pointer
                   20752:        rsb                     # return to pbild caller
                   20753:        #enp                    # end procedure pbild
                   20754:        #page   
                   20755: #
                   20756: #      PCONC -- CONCATENATE TWO PATTERNS
                   20757: #
                   20758: #      (XL)                  PTR TO RIGHT PATTERN
                   20759: #      (XR)                  PTR TO LEFT PATTERN
                   20760: #      JSR  PCONC            CALL TO CONCATENATE PATTERNS
                   20761: #      (XR)                  PTR TO CONCATENATED PATTERN
                   20762: #      (XL,WA,WB,WC)         DESTROYED
                   20763: #
                   20764: #
                   20765: #      TO CONCATENATE TWO PATTERNS, ALL SUCCESSORS IN THE LEFT
                   20766: #      PATTERN WHICH POINT TO THE NOTHEN NODE MUST BE CHANGED TO
                   20767: #      POINT TO THE RIGHT PATTERN. HOWEVER, THIS MODIFICATION
                   20768: #      MUST BE PERFORMED ON A COPY OF THE LEFT ARGUMENT RATHER
                   20769: #      THAN THE LEFT ARGUMENT ITSELF, SINCE THE LEFT ARGUMENT
                   20770: #      MAY BE POINTED TO BY SOME OTHER VARIABLE VALUE.
                   20771: #
                   20772: #      ACCORDINGLY, IT IS NECESSARY TO COPY THE LEFT ARGUMENT.
                   20773: #      THIS IS NOT A TRIVIAL PROCESS SINCE WE MUST AVOID COPYING
                   20774: #      NODES MORE THAN ONCE AND THE PATTERN IS A GRAPH STRUCTURE
                   20775: #      THE FOLLOWING ALGORITHM IS EMPLOYED.
                   20776: #
                   20777: #      THE STACK IS USED TO STORE A LIST OF NODES WHICH
                   20778: #      HAVE ALREADY BEEN COPIED. THE FORMAT OF THE ENTRIES ON
                   20779: #      THIS LIST CONSISTS OF A TWO WORD BLOCK. THE FIRST WORD
                   20780: #      IS THE OLD ADDRESS AND THE SECOND WORD IS THE ADDRESS
                   20781: #      OF THE COPY. THIS LIST IS SEARCHED BY THE PCOPY
                   20782: #      ROUTINE TO AVOID MAKING DUPLICATE COPIES. A TRICK IS
                   20783: #      USED TO ACCOMPLISH THE CONCATENATION AT THE SAME TIME.
                   20784: #      A SPECIAL ENTRY IS MADE TO START WITH ON THE STACK. THIS
                   20785: #      ENTRY RECORDS THAT THE NOTHEN NODE HAS BEEN COPIED
                   20786: #      ALREADY AND THE ADDRESS OF ITS COPY IS THE RIGHT PATTERN.
                   20787: #      THIS AUTOMATICALLY PERFORMS THE CORRECT REPLACEMENTS.
                   20788: #
                   20789: pconc: #prc                    # entry point
                   20790:        clrl    -(sp)           # make room for one entry at bottom
                   20791:        movl    sp,r8           # store pointer to start of list
                   20792:        movl    $ndnth,-(sp)    # stack nothen node as old node
                   20793:        movl    r10,-(sp)       # store right arg as copy of nothen
                   20794:        movl    sp,r10          # initialize pointer to stack entries
                   20795:        jsb     pcopy           # copy first node of left arg
                   20796:        movl    r6,4*2(r10)     # store as result under list
                   20797:        #page   
                   20798: #
                   20799: #      PCONC (CONTINUED)
                   20800: #
                   20801: #      THE FOLLOWING LOOP SCANS ENTRIES IN THE LIST AND MAKES
                   20802: #      SURE THAT THEIR SUCCESSORS HAVE BEEN COPIED.
                   20803: #
                   20804: pcnc1: cmpl    r10,sp          # jump if all entries processed
                   20805:        beqlu   pcnc2
                   20806:        movl    -(r10),r9       # else load next old address
                   20807:        movl    4*pthen(r9),r9  # load pointer to successor
                   20808:        jsb     pcopy           # copy successor node
                   20809:        movl    -(r10),r9       # load pointer to new node (copy)
                   20810:        movl    r6,4*pthen(r9)  # store ptr to new successor
                   20811: #
                   20812: #      NOW CHECK FOR SPECIAL CASE OF ALTERNATION NODE WHERE
                   20813: #      PARM1 POINTS TO A NODE AND MUST BE COPIED LIKE PTHEN.
                   20814: #
                   20815:        cmpl    (r9),$p$alt     # loop back if not
                   20816:        bnequ   pcnc1
                   20817:        movl    4*parm1(r9),r9  # else load pointer to alternative
                   20818:        jsb     pcopy           # copy it
                   20819:        movl    (r10),r9        # restore ptr to new node
                   20820:        movl    r6,4*parm1(r9)  # store ptr to copied alternative
                   20821:        jmp     pcnc1           # loop back for next entry
                   20822: #
                   20823: #      HERE AT END OF COPY PROCESS
                   20824: #
                   20825: pcnc2: movl    r8,sp           # restore stack pointer
                   20826:        movl    (sp)+,r9        # load pointer to copy
                   20827:        rsb                     # return to pconc caller
                   20828:        #enp                    # end procedure pconc
                   20829:        #page   
                   20830: #
                   20831: #      PCOPY -- COPY A PATTERN NODE
                   20832: #
                   20833: #      PCOPY IS CALLED FROM THE PCONC PROCEDURE TO COPY A SINGLE
                   20834: #      PATTERN NODE. THE COPY IS ONLY CARRIED OUT IF THE NODE
                   20835: #      HAS NOT BEEN COPIED ALREADY.
                   20836: #
                   20837: #      (XR)                  POINTER TO NODE TO BE COPIED
                   20838: #      (XT)                  PTR TO CURRENT LOC IN COPY LIST
                   20839: #      (WC)                  POINTER TO LIST OF COPIED NODES
                   20840: #      JSR  PCOPY            CALL TO COPY A NODE
                   20841: #      (WA)                  POINTER TO COPY
                   20842: #      (WB,XR)               DESTROYED
                   20843: #
                   20844:        .data   1
                   20845: pcopy_s:       .long   0
                   20846:        .text   0
                   20847: pcopy: movl    (sp)+,pcopy_s   # entry point
                   20848:        movl    r10,r7          # save xt
                   20849:        movl    r8,r10          # point to start of list
                   20850: #
                   20851: #      LOOP TO SEARCH LIST OF NODES COPIED ALREADY
                   20852: #
                   20853: pcop1: subl2   $4,r10          # point to next entry on list
                   20854:        cmpl    r9,(r10)        # jump if match
                   20855:        beqlu   pcop2
                   20856:        subl2   $4,r10          # else skip over copied address
                   20857:        cmpl    r10,sp          # loop back if more to test
                   20858:        bnequ   pcop1
                   20859: #
                   20860: #      HERE IF NOT IN LIST, PERFORM COPY
                   20861: #
                   20862:        movl    (r9),r6         # load first word of block
                   20863:        jsb     blkln           # get length of block
                   20864:        movl    r9,r10          # save pointer to old node
                   20865:        jsb     alloc           # allocate space for copy
                   20866:        movl    r10,-(sp)       # store old address on list
                   20867:        movl    r9,-(sp)        # store new address on list
                   20868:        jsb     sbchk           # check for stack overflow
                   20869:        jsb     sbmvw           # move words from old block to copy
                   20870:        movl    (sp),r6         # load pointer to copy
                   20871:        jmp     pcop3           # jump to exit
                   20872: #
                   20873: #      HERE IF WE FIND ENTRY IN LIST
                   20874: #
                   20875: pcop2: movl    -(r10),r6       # load address of copy from list
                   20876: #
                   20877: #      COMMON EXIT POINT
                   20878: #
                   20879: pcop3: movl    r7,r10          # restore xt
                   20880:        jmp     *pcopy_s        # return to pcopy caller
                   20881:        #enp                    # end procedure pcopy
                   20882:        #page   
                   20883: #
                   20884: #      PRFLR -- PRINT PROFILE
                   20885: #      PRFLR IS CALLED TO PRINT THE CONTENTS OF THE PROFILE
                   20886: #      TABLE IN A FAIRLY READABLE TABULAR FORMAT.
                   20887: #
                   20888: #      JSR  PRFLR            CALL TO PRINT PROFILE
                   20889: #      (WA,IA)               DESTROYED
                   20890: #
                   20891: prflr: #prc    
                   20892:        tstl    pfdmp           # no printing if no profiling done
                   20893:        bnequ   0f
                   20894:        jmp     prfl4
                   20895: 0:             
                   20896:        movl    r9,-(sp)        # preserve entry xr
                   20897:        movl    r7,pfsvw        # and also wb
                   20898:        jsb     prtpg           # eject
                   20899:        movl    $pfms1,r9       # load msg /program profile/
                   20900:        jsb     prtst           # and print it
                   20901:        jsb     prtnl           # followed by newline
                   20902:        jsb     prtnl           # and another
                   20903:        movl    $pfms2,r9       # point to first hdr
                   20904:        jsb     prtst           # print it
                   20905:        jsb     prtnl           # new line
                   20906:        movl    $pfms3,r9       # second hdr
                   20907:        jsb     prtst           # print it
                   20908:        jsb     prtnl           # new line
                   20909:        jsb     prtnl           # and another blank line
                   20910:        clrl    r7              # initial stmt count
                   20911:        movl    pftbl,r9        # point to table origin
                   20912:        addl2   $4*num02,r9     # bias past xnblk header (sgd07)
                   20913: #
                   20914: #      LOOP HERE TO PRINT SUCCESSIVE ENTRIES
                   20915: #
                   20916: prfl1: incl    r7              # bump stmt nr
                   20917:        movl    (r9),r5         # load nr of executions
                   20918:        beql    prfl3           # no printing if zero
                   20919:        movl    $pfpd1,profs    # point where to print
                   20920:        jsb     prtin           # and print it
                   20921:        clrl    profs           # back to start of line
                   20922:        movl    r7,r5           # load stmt nr
                   20923:        jsb     prtin           # print it there
                   20924:        movl    $pfpd2,profs    # and pad past count
                   20925:        movl    4*cfp$i(r9),r5  # load total exec time
                   20926:        jsb     prtin           # print that too
                   20927:        movl    4*cfp$i(r9),r5  # reload time
                   20928:        mull2   intth,r5        # convert to microsec
                   20929:        bvs     prfl2
                   20930:        divl2   (r9),r5         # divide by executions
                   20931:        movl    $pfpd3,profs    # pad last print
                   20932:        jsb     prtin           # and print mcsec/execn
                   20933: #
                   20934: #      MERGE AFTER PRINTING TIME
                   20935: #
                   20936: prfl2: jsb     prtnl           # thats another line
                   20937: #
                   20938: #      HERE TO GO TO NEXT ENTRY
                   20939: #
                   20940: prfl3: addl2   $4*pf$i2,r9     # bump index ptr (sgd07)
                   20941:        cmpl    r7,pfnte        # loop if more stmts
                   20942:        blssu   prfl1
                   20943:        movl    (sp)+,r9        # restore callers xr
                   20944:        movl    pfsvw,r7        # and wb too
                   20945: #
                   20946: #      HERE TO EXIT
                   20947: #
                   20948: prfl4: rsb                     # return
                   20949:        #enp                    # end of prflr
                   20950:        #page   
                   20951: #
                   20952: #      PRFLU -- UPDATE AN ENTRY IN THE PROFILE TABLE
                   20953: #
                   20954: #      ON ENTRY, KVSTN CONTAINS NR OF STMT TO PROFILE
                   20955: #
                   20956: #      JSR  PRFLU            CALL TO UPDATE ENTRY
                   20957: #      (IA)                  DESTROYED
                   20958: #
                   20959: prflu: #prc    
                   20960:        tstl    pffnc           # skip if just entered function
                   20961:        beqlu   0f
                   20962:        jmp     pflu4
                   20963: 0:             
                   20964:        movl    r9,-(sp)        # preserve entry xr
                   20965:        movl    r6,pfsvw        # save wa (sgd07)
                   20966:        tstl    pftbl           # branch if table allocated
                   20967:        bnequ   pflu2
                   20968: #
                   20969: #      HERE IF SPACE FOR PROFILE TABLE NOT YET ALLOCATED.
                   20970: #      CALCULATE SIZE NEEDED, ALLOCATE A STATIC XNBLK, AND
                   20971: #      INITIALIZE IT ALL TO ZERO.
                   20972: #      THE TIME TAKEN FOR THIS WILL BE ATTRIBUTED TO THE CURRENT
                   20973: #      STATEMENT (ASSIGNMENT TO KEYWD PROFILE), BUT SINCE THE
                   20974: #      TIMING FOR THIS STATEMENT IS UP THE POLE ANYWAY, THIS
                   20975: #      DOESNT REALLY MATTER...
                   20976: #
                   20977:        subl2   $num01,pfnte    # adjust for extra count (sgd07)
                   20978:        movl    pfi2a,r5        # convrt entry size to int
                   20979:        movl    r5,pfste        # and store safely for later
                   20980:        movl    pfnte,r5        # load table length as integer
                   20981:        mull2   pfste,r5        # multiply by entry size
                   20982:        movl    r5,r6           # get back address-style
                   20983:        addl2   $num02,r6       # add on 2 word overhead
                   20984:        moval   0[r6],r6        # convert the whole lot to bytes
                   20985:        jsb     alost           # gimme the space
                   20986:        movl    r9,pftbl        # save block pointer
                   20987:        movl    $b$xnt,(r9)+    # put block type and ...
                   20988:        movl    r6,(r9)+        # ... length into header
                   20989:        movl    r5,r6           # get back nr of wds in data area
                   20990:                                # load the counter
                   20991: #
                   20992: #      LOOP HERE TO ZERO THE BLOCK DATA
                   20993: #
                   20994: pflu1: clrl    (r9)+           # blank a word
                   20995:        sobgtr  r6,pflu1        # and alllllll the rest
                   20996: #
                   20997: #      END OF ALLOCATION. MERGE BACK INTO ROUTINE
                   20998: #
                   20999: pflu2: movl    kvstn,r5        # load nr of stmt just ended
                   21000:        subl2   intv1,r5        # make into index offset
                   21001:        mull2   pfste,r5        # make offset of table entry
                   21002:        movl    r5,r6           # convert to address
                   21003:        moval   0[r6],r6        # get as baus
                   21004:        addl2   $4*num02,r6     # offset includes table header
                   21005:        movl    pftbl,r9        # get table start
                   21006:        cmpl    r6,4*num01(r9)  # if out of table, skip it
                   21007:        bgequ   pflu3
                   21008:        addl2   r6,r9           # else point to entry
                   21009:        movl    (r9),r5         # get nr of executions so far
                   21010:        addl2   intv1,r5        # nudge up one
                   21011:        movl    r5,(r9)         # and put back
                   21012:        jsb     systm           # get time now
                   21013:        movl    r5,pfetm        # stash ending time
                   21014:        subl2   pfstm,r5        # subtract start time
                   21015:        addl2   4*cfp$i(r9),r5  # add cumulative time so far
                   21016:        movl    r5,4*cfp$i(r9)  # and put back new total
                   21017:        movl    pfetm,r5        # load end time of this stmt ...
                   21018:        movl    r5,pfstm        # ... which is start time of next
                   21019: #
                   21020: #      MERGE HERE TO EXIT
                   21021: #
                   21022: pflu3: movl    (sp)+,r9        # restore callers xr
                   21023:        movl    pfsvw,r6        # restore saved reg
                   21024:        rsb                     # and return
                   21025: #
                   21026: #      HERE IF PROFILE IS SUPPRESSED BECAUSE A PROGRAM DEFINED
                   21027: #      FUNCTION IS ABOUT TO BE ENTERED, AND SO THE CURRENT STMT
                   21028: #      HAS NOT YET FINISHED
                   21029: #
                   21030: pflu4: clrl    pffnc           # reset the condition flag
                   21031:        rsb                     # and immediate return
                   21032:        #enp                    # end of procedure prflu
                   21033:        #page   
                   21034: #
                   21035: #      PRPAR - PROCESS PRINT PARAMETERS
                   21036: #
                   21037: #      (WC)                  IF NONZERO ASSOCIATE TERMINAL ONLY
                   21038: #      JSR  PRPAR            CALL TO PROCESS PRINT PARAMETERS
                   21039: #      (XL,XR,WA,WB,WC)      DESTROYED
                   21040: #
                   21041: #      SINCE MEMORY ALLOCATION IS UNDECIDED ON INITIAL CALL,
                   21042: #      TERMINAL CANNOT BE ASSOCIATED. THE ENTRY WITH WC NON-ZERO
                   21043: #      IS PROVIDED SO A LATER CALL CAN BE MADE TO COMPLETE THIS.
                   21044: #
                   21045: prpar: #prc                    # entry point
                   21046:        tstl    r8              # jump to associate terminal
                   21047:        beqlu   0f
                   21048:        jmp     prpa7
                   21049: 0:             
                   21050:        jsb     syspp           # get print parameters
                   21051:        tstl    r7              # jump if lines/page specified
                   21052:        bnequ   prpa1
                   21053:        movl    $cfp$m,r7       # else use a large value
                   21054:        ashl    $-1,r7,r7       # but not too large
                   21055: #
                   21056: #      STORE LINE COUNT/PAGE
                   21057: #
                   21058: prpa1: movl    r7,lstnp        # store number of lines/page
                   21059:        movl    r7,lstlc        # pretend page is full initially
                   21060:        clrl    lstpg           # clear page number
                   21061:        movl    prlen,r7        # get prior length if any
                   21062:        beqlu   prpa2           # skip if no length
                   21063:        cmpl    r6,r7           # skip storing if too big
                   21064:        bgtru   prpa3
                   21065: #
                   21066: #      STORE PRINT BUFFER LENGTH
                   21067: #
                   21068: prpa2: movl    r6,prlen        # store value
                   21069: #
                   21070: #      PROCESS BITS OPTIONS
                   21071: #
                   21072: prpa3: movl    bits3,r7        # bit 3 mask
                   21073:        mcoml   r8,r11          # get -nolist bit
                   21074:        bicl2   r11,r7
                   21075:        beqlu   prpa4           # skip if clear
                   21076:        clrl    cswls           # set -nolist
                   21077: #
                   21078: #      CHECK IF FAIL REPORTS GOTO INTERACTIVE CHANNEL
                   21079: #
                   21080: prpa4: movl    bits1,r7        # bit 1 mask
                   21081:        mcoml   r8,r11          # get bit
                   21082:        bicl2   r11,r7
                   21083:        movl    r7,erich        # store int. chan. error flag
                   21084:        movl    bits2,r7        # bit 2 mask
                   21085:        mcoml   r8,r11          # get bit
                   21086:        bicl2   r11,r7
                   21087:        movl    r7,prich        # flag for std printer on int. chan.
                   21088:        movl    bits4,r7        # bit 4 mask
                   21089:        mcoml   r8,r11          # get bit
                   21090:        bicl2   r11,r7
                   21091:        movl    r7,cpsts        # flag for compile stats suppressn.
                   21092:        movl    bits5,r7        # bit 5 mask
                   21093:        mcoml   r8,r11          # get bit
                   21094:        bicl2   r11,r7
                   21095:        movl    r7,exsts        # flag for exec stats suppression
                   21096:        #page   
                   21097: #
                   21098: #      PRPAR (CONTINUED)
                   21099: #
                   21100:        movl    bits6,r7        # bit 6 mask
                   21101:        mcoml   r8,r11          # get bit
                   21102:        bicl2   r11,r7
                   21103:        movl    r7,precl        # extended/compact listing flag
                   21104:        subl2   $num08,r6       # point 8 chars from line end
                   21105:        tstl    r7              # jump if not extended
                   21106:        beqlu   prpa5
                   21107:        movl    r6,lstpo        # store for listing page headings
                   21108: #
                   21109: #       CONTINUE OPTION PROCESSING
                   21110: #
                   21111: prpa5: movl    bits7,r7        # bit 7 mask
                   21112:        mcoml   r8,r11          # get bit 7
                   21113:        bicl2   r11,r7
                   21114:        movl    r7,cswex        # set -noexecute if non-zero
                   21115:        movl    bit10,r7        # bit 10 mask
                   21116:        mcoml   r8,r11          # get bit 10
                   21117:        bicl2   r11,r7
                   21118:        movl    r7,headp        # pretend printed to omit headers
                   21119:        movl    bits9,r7        # bit 9 mask
                   21120:        mcoml   r8,r11          # get bit 9
                   21121:        bicl2   r11,r7
                   21122:        movl    r7,prsto        # keep it as std listing option
                   21123:        tstl    r7              # skip if clear
                   21124:        beqlu   prpa6
                   21125:        movl    prlen,r6        # get print buffer length
                   21126:        subl2   $num08,r6       # point 8 chars from line end
                   21127:        movl    r6,lstpo        # store page offset
                   21128: #
                   21129: #      CHECK FOR TERMINAL
                   21130: #
                   21131: prpa6: mcoml   bits8,r11       # see if terminal to be activated
                   21132:        bicl2   r11,r8
                   21133:        beqlu   0f              # jump if terminal required
                   21134:        jmp     prpa7
                   21135: 0:             
                   21136:        tstl    initr           # jump if no terminal to detach
                   21137:        beqlu   prpa8
                   21138:        movl    $v$ter,r10      # ptr to /terminal/
                   21139:        jsb     gtnvr           # get vrblk pointer
                   21140:        .long   invalid$        # cant fail
                   21141:        movl    $nulls,4*vrval(r9) # clear value of terminal
                   21142:        jsb     setvr           # remove association
                   21143:        jmp     prpa8           # return
                   21144: #
                   21145: #      ASSOCIATE TERMINAL
                   21146: #
                   21147: prpa7: movl    sp,initr        # note terminal associated
                   21148:        tstl    dnamb           # cant if memory not organised
                   21149:        beqlu   prpa8
                   21150:        movl    $v$ter,r10      # point to terminal string
                   21151:        movl    $trtou,r7       # output trace type
                   21152:        jsb     inout           # attach output trblk to vrblk
                   21153:        movl    r9,-(sp)        # stack trblk ptr
                   21154:        movl    $v$ter,r10      # point to terminal string
                   21155:        movl    $trtin,r7       # input trace type
                   21156:        jsb     inout           # attach input trace blk
                   21157:        movl    (sp)+,4*vrval(r9)# add output trblk to chain
                   21158: #
                   21159: #      RETURN POINT
                   21160: #
                   21161: prpa8: rsb                     # return
                   21162:        #enp                    # end procedure prpar
                   21163:        #page   
                   21164: #
                   21165: #      PRTCH -- PRINT A CHARACTER
                   21166: #
                   21167: #      PRTCH IS USED TO PRINT A SINGLE CHARACTER
                   21168: #
                   21169: #      (WA)                  CHARACTER TO BE PRINTED
                   21170: #      JSR  PRTCH            CALL TO PRINT CHARACTER
                   21171: #
                   21172: prtch: #prc                    # entry point
                   21173:        movl    r9,-(sp)        # save xr
                   21174:        cmpl    profs,prlen     # jump if room in buffer
                   21175:        bnequ   prch1
                   21176:        jsb     prtnl           # else print this line
                   21177: #
                   21178: #      HERE AFTER MAKING SURE WE HAVE ROOM
                   21179: #
                   21180: prch1: movl    prbuf,r9        # point to print buffer
                   21181:        movl    profs,r11       # [get in scratch register]
                   21182:        movab   cfp$f(r9)[r11],r9# point to next character location
                   21183:        movb    r6,(r9)         # store new character
                   21184:        #csc    r9              # complete store characters
                   21185:        incl    profs           # bump pointer
                   21186:        movl    (sp)+,r9        # restore entry xr
                   21187:        rsb                     # return to prtch caller
                   21188:        #enp                    # end procedure prtch
                   21189:        #page   
                   21190: #
                   21191: #      PRTIC -- PRINT TO INTERACTIVE CHANNEL
                   21192: #
                   21193: #      PRTIC IS CALLED TO PRINT THE CONTENTS OF THE STANDARD
                   21194: #      PRINT BUFFER TO THE INTERACTIVE CHANNEL. IT IS ONLY
                   21195: #      CALLED AFTER PRTST HAS SET UP THE STRING FOR PRINTING.
                   21196: #      IT DOES NOT CLEAR THE BUFFER.
                   21197: #
                   21198: #      JSR  PRTIC            CALL FOR PRINT
                   21199: #      (WA,WB)               DESTROYED
                   21200: #
                   21201: prtic: #prc                    # entry point
                   21202:        movl    r9,-(sp)        # save xr
                   21203:        movl    prbuf,r9        # point to buffer
                   21204:        movl    profs,r6        # no of chars
                   21205:        jsb     syspi           # print
                   21206:        .long   prtc2           # fail return
                   21207: #
                   21208: #      RETURN
                   21209: #
                   21210: prtc1: movl    (sp)+,r9        # restore xr
                   21211:        rsb                     # return
                   21212: #
                   21213: #      ERROR OCCURED
                   21214: #
                   21215: prtc2: clrl    erich           # prevent looping
                   21216:        jmp     er_252          # error on printing to interactive channel
                   21217:        jmp     prtc1           # return
                   21218:        #enp                    # procedure prtic
                   21219:        #page   
                   21220: #
                   21221: #      PRTIS -- PRINT TO INTERACTIVE AND STANDARD PRINTER
                   21222: #
                   21223: #      PRTIS PUTS A LINE FROM THE PRINT BUFFER ONTO THE
                   21224: #      INTERACTIVE CHANNEL (IF ANY) AND THE STANDARD PRINTER.
                   21225: #      IT ALWAYS PRINTS TO THE STANDARD PRINTER BUT DOES
                   21226: #      NOT DUPLICATE LINES IF THE STANDARD PRINTER IS
                   21227: #      INTERACTIVE.  IT CLEARS DOWN THE PRINT BUFFER.
                   21228: #
                   21229: #      JSR  PRTIS            CALL FOR PRINTING
                   21230: #      (WA,WB)               DESTROYED
                   21231: #
                   21232: prtis: #prc                    # entry point
                   21233:        tstl    prich           # jump if standard printer is int.ch.
                   21234:        bnequ   prts1
                   21235:        tstl    erich           # skip if not doing int. error reps.
                   21236:        beqlu   prts1
                   21237:        jsb     prtic           # print to interactive channel
                   21238: #
                   21239: #      MERGE AND EXIT
                   21240: #
                   21241: prts1: jsb     prtnl           # print to standard printer
                   21242:        rsb                     # return
                   21243:        #enp                    # end procedure prtis
                   21244:        #page   
                   21245: #
                   21246: #      PRTIN -- PRINT AN INTEGER
                   21247: #
                   21248: #      PRTIN PRINTS THE INTEGER VALUE WHICH IS IN THE INTEGER
                   21249: #      ACCUMULATOR. BLOCKS BUILT IN DYNAMIC STORAGE
                   21250: #      DURING THIS PROCESS ARE IMMEDIATELY DELETED.
                   21251: #
                   21252: #      (IA)                  INTEGER VALUE TO BE PRINTED
                   21253: #      JSR  PRTIN            CALL TO PRINT INTEGER
                   21254: #      (IA,RA)               DESTROYED
                   21255: #
                   21256: prtin: #prc                    # entry point
                   21257:        movl    r9,-(sp)        # save xr
                   21258:        jsb     icbld           # build integer block
                   21259:        cmpl    r9,dnamb        # jump if icblk below dynamic
                   21260:        blequ   prti1
                   21261:        cmpl    r9,dnamp        # jump if above dynamic
                   21262:        bgequ   prti1
                   21263:        movl    r9,dnamp        # immediately delete it
                   21264: #
                   21265: #      DELETE ICBLK FROM DYNAMIC STORE
                   21266: #
                   21267: prti1: movl    r9,-(sp)        # stack ptr for gtstg
                   21268:        jsb     gtstg           # convert to string
                   21269:        .long   invalid$        # convert error is impossible
                   21270:        movl    r9,dnamp        # reset pointer to delete scblk
                   21271:        jsb     prtst           # print integer string
                   21272:        movl    (sp)+,r9        # restore entry xr
                   21273:        rsb                     # return to prtin caller
                   21274:        #enp                    # end procedure prtin
                   21275:        #page   
                   21276: #
                   21277: #      PRTMI -- PRINT MESSAGE AND INTEGER
                   21278: #
                   21279: #      PRTMI IS USED TO PRINT MESSAGES TOGETHER WITH AN INTEGER
                   21280: #      VALUE STARTING IN COLUMN 15 (USED BY THE ROUTINES AT
                   21281: #      THE END OF COMPILATION).
                   21282: #
                   21283: #      JSR  PRTMI            CALL TO PRINT MESSAGE AND INTEGER
                   21284: #
                   21285: prtmi: #prc                    # entry point
                   21286:        jsb     prtst           # print string message
                   21287:        movl    $prtmf,profs    # set offset to col 15
                   21288:        jsb     prtin           # print integer
                   21289:        jsb     prtnl           # print line
                   21290:        rsb                     # return to prtmi caller
                   21291:        #enp                    # end procedure prtmi
                   21292:        #page   
                   21293: #
                   21294: #      PRTMX  -- AS PRTMI WITH EXTRA COPY TO INTERACTIVE CHAN.
                   21295: #
                   21296: #      JSR  PRTMX            CALL FOR PRINTING
                   21297: #      (WA,WB)               DESTROYED
                   21298: #
                   21299: prtmx: #prc                    # entry point
                   21300:        jsb     prtst           # print string message
                   21301:        movl    $prtmf,profs    # set ptr to column 15
                   21302:        jsb     prtin           # print integer
                   21303:        jsb     prtis           # print line
                   21304:        rsb                     # return
                   21305:        #enp                    # end procedure prtmx
                   21306:        #page   
                   21307: #
                   21308: #      PRTNL -- PRINT NEW LINE (END PRINT LINE)
                   21309: #
                   21310: #      PRTNL PRINTS THE CONTENTS OF THE PRINT BUFFER, RESETS
                   21311: #      THE BUFFER TO ALL BLANKS AND RESETS THE PRINT POINTER.
                   21312: #
                   21313: #      JSR  PRTNL            CALL TO PRINT LINE
                   21314: #
                   21315: prtnl: #prc                    # entry point
                   21316:        tstl    headp           # were headers printed
                   21317:        bnequ   prnl0
                   21318:        jsb     prtps           # no - print them
                   21319: #
                   21320: #      CALL SYSPR
                   21321: #
                   21322: prnl0: movl    r9,-(sp)        # save entry xr
                   21323:        movl    r6,prtsa        # save wa
                   21324:        movl    r7,prtsb        # save wb
                   21325:        movl    prbuf,r9        # load pointer to buffer
                   21326:        movl    profs,r6        # load number of chars in buffer
                   21327:        jsb     syspr           # call system print routine
                   21328:        .long   prnl2           # jump if failed
                   21329:        movl    prlnw,r6        # load length of buffer in words
                   21330:        addl2   $4*schar,r9     # point to chars of buffer
                   21331:        movl    nullw,r7        # get word of blanks
                   21332: #
                   21333: #      LOOP TO BLANK BUFFER
                   21334: #
                   21335: prnl1: movl    r7,(r9)+        # store word of blanks, bump ptr
                   21336:        sobgtr  r6,prnl1        # loop till all blanked
                   21337: #
                   21338: #      EXIT POINT
                   21339: #
                   21340:        movl    prtsb,r7        # restore wb
                   21341:        movl    prtsa,r6        # restore wa
                   21342:        movl    (sp)+,r9        # restore entry xr
                   21343:        clrl    profs           # reset print buffer pointer
                   21344:        rsb                     # return to prtnl caller
                   21345: #
                   21346: #      FILE FULL OR NO OUTPUT FILE FOR LOAD MODULE
                   21347: #
                   21348: prnl2: tstl    prtef           # jump if not first time
                   21349:        bnequ   prnl3
                   21350:        movl    sp,prtef        # mark first occurrence
                   21351:        jmp     er_253          # print limit exceeded on standard output channel
                   21352: #
                   21353: #      STOP AT ONCE
                   21354: #
                   21355: prnl3: movl    $nini8,r7       # ending code
                   21356:        movl    kvstn,r6        # statement number
                   21357:        jsb     sysej           # stop
                   21358:        #enp                    # end procedure prtnl
                   21359:        #page   
                   21360: #
                   21361: #      PRTNM -- PRINT VARIABLE NAME
                   21362: #
                   21363: #      PRTNM IS USED TO PRINT A CHARACTER REPRESENTATION OF THE
                   21364: #      NAME OF A VARIABLE (NOT A VALUE OF DATATYPE NAME)
                   21365: #      NAMES OF PSEUDO-VARIABLES MAY NOT BE PASSED TO PRTNM.
                   21366: #
                   21367: #      (XL)                  NAME BASE
                   21368: #      (WA)                  NAME OFFSET
                   21369: #      JSR  PRTNM            CALL TO PRINT NAME
                   21370: #      (WB,WC,RA)            DESTROYED
                   21371: #
                   21372: prtnm: #prc                    # entry point (recursive, see prtvl)
                   21373:        movl    r6,-(sp)        # save wa (offset is collectable)
                   21374:        movl    r9,-(sp)        # save entry xr
                   21375:        movl    r10,-(sp)       # save name base
                   21376:        cmpl    r10,state       # jump if not natural variable
                   21377:        bgequ   prn02
                   21378: #
                   21379: #      HERE FOR NATURAL VARIABLE NAME, RECOGNIZED BY THE FACT
                   21380: #      THAT THE NAME BASE POINTS INTO THE STATIC AREA.
                   21381: #
                   21382:        movl    r10,r9          # point to vrblk
                   21383:        jsb     prtvn           # print name of variable
                   21384: #
                   21385: #      COMMON EXIT POINT
                   21386: #
                   21387: prn01: movl    (sp)+,r10       # restore name base
                   21388:        movl    (sp)+,r9        # restore entry value of xr
                   21389:        movl    (sp)+,r6        # restore wa
                   21390:        rsb                     # return to prtnm caller
                   21391: #
                   21392: #      HERE FOR CASE OF NON-NATURAL VARIABLE
                   21393: #
                   21394: prn02: movl    r6,r7           # copy name offset
                   21395:        cmpl    (r10),$b$pdt    # jump if array or table
                   21396:        bnequ   prn03
                   21397: #
                   21398: #      FOR PROGRAM DEFINED DATATYPE, PRT FLD NAME, LEFT PAREN
                   21399: #
                   21400:        movl    4*pddfp(r10),r9 # load pointer to dfblk
                   21401:        addl2   r6,r9           # add name offset
                   21402:        movl    4*pdfof(r9),r9  # load vrblk pointer for field
                   21403:        jsb     prtvn           # print field name
                   21404:        movl    $ch$pp,r6       # load left paren
                   21405:        jsb     prtch           # print character
                   21406:        #page   
                   21407: #
                   21408: #      PRTNM (CONTINUED)
                   21409: #
                   21410: #      NOW WE PRINT AN IDENTIFYING NAME FOR THE OBJECT IF ONE
                   21411: #      CAN BE FOUND. THE FOLLOWING CODE SEARCHES FOR A NATURAL
                   21412: #      VARIABLE WHICH CONTAINS THIS OBJECT AS VALUE. IF SUCH A
                   21413: #      VARIABLE IS FOUND, ITS NAME IS PRINTED, ELSE THE VALUE
                   21414: #      OF THE OBJECT (AS PRINTED BY PRTVL) IS USED INSTEAD.
                   21415: #
                   21416: #      FIRST WE POINT TO THE PARENT TBBLK IF THIS IS THE CASE OF
                   21417: #      A TABLE ELEMENT. TO DO THIS, CHASE DOWN THE TRNXT CHAIN.
                   21418: #
                   21419: prn03: cmpl    (r10),$b$tet    # jump if we got there (or not te)
                   21420:        bnequ   prn04
                   21421:        movl    4*tenxt(r10),r10# else move out on chain
                   21422:        jmp     prn03           # and loop back
                   21423: #
                   21424: #      NOW WE ARE READY FOR THE SEARCH. TO SPEED THINGS UP IN
                   21425: #      THE CASE OF CALLS FROM DUMP WHERE THE SAME NAME BASE
                   21426: #      WILL OCCUR REPEATEDLY WHILE DUMPING AN ARRAY OR TABLE,
                   21427: #      WE REMEMBER THE LAST VRBLK POINTER FOUND IN PRNMV. SO
                   21428: #      FIRST CHECK TO SEE IF WE HAVE THIS ONE AGAIN.
                   21429: #
                   21430: prn04: movl    prnmv,r9        # point to vrblk we found last time
                   21431:        movl    hshtb,r6        # point to hash table in case not
                   21432:        jmp     prn07           # jump into search for special check
                   21433: #
                   21434: #      LOOP THROUGH HASH SLOTS
                   21435: #
                   21436: prn05: movl    r6,r9           # copy slot pointer
                   21437:        addl2   $4,r6           # bump slot pointer
                   21438:        subl2   $4*vrnxt,r9     # introduce standard vrblk offset
                   21439: #
                   21440: #      LOOP THROUGH VRBLKS ON ONE HASH CHAIN
                   21441: #
                   21442: prn06: movl    4*vrnxt(r9),r9  # point to next vrblk on hash chain
                   21443: #
                   21444: #      MERGE HERE FIRST TIME TO CHECK BLOCK WE FOUND LAST TIME
                   21445: #
                   21446: prn07: movl    r9,r8           # copy vrblk pointer
                   21447:        beqlu   prn09           # jump if chain end (or prnmv zero)
                   21448:        #page   
                   21449: #
                   21450: #      PRTNM (CONTINUED)
                   21451: #
                   21452: #      LOOP TO FIND VALUE (CHASE DOWN POSSIBLE TRBLK CHAIN)
                   21453: #
                   21454: prn08: movl    4*vrval(r9),r9  # load value
                   21455:        cmpl    (r9),$b$trt     # loop if that was a trblk
                   21456:        beqlu   prn08
                   21457: #
                   21458: #      NOW WE HAVE THE VALUE, IS THIS THE BLOCK WE WANT
                   21459: #
                   21460:        cmpl    r9,r10          # jump if this matches the name base
                   21461:        beqlu   prn10
                   21462:        movl    r8,r9           # else point back to that vrblk
                   21463:        jmp     prn06           # and loop back
                   21464: #
                   21465: #      HERE TO MOVE TO NEXT HASH SLOT
                   21466: #
                   21467: prn09: cmpl    r6,hshte        # loop back if more to go
                   21468:        blssu   prn05
                   21469:        movl    r10,r9          # else not found, copy value pointer
                   21470:        jsb     prtvl           # print value
                   21471:        jmp     prn11           # and merge ahead
                   21472: #
                   21473: #      HERE WHEN WE FIND A MATCHING ENTRY
                   21474: #
                   21475: prn10: movl    r8,r9           # copy vrblk pointer
                   21476:        movl    r9,prnmv        # save for next time in
                   21477:        jsb     prtvn           # print variable name
                   21478: #
                   21479: #      MERGE HERE IF NO ENTRY FOUND
                   21480: #
                   21481: prn11: movl    (r10),r8        # load first word of name base
                   21482:        cmpl    r8,$b$pdt       # jump if not program defined
                   21483:        bnequ   prn13
                   21484: #
                   21485: #      FOR PROGRAM DEFINED DATATYPE, ADD RIGHT PAREN AND EXIT
                   21486: #
                   21487:        movl    $ch$rp,r6       # load right paren, merge
                   21488: #
                   21489: #      MERGE HERE TO PRINT FINAL RIGHT PAREN OR BRACKET
                   21490: #
                   21491: prn12: jsb     prtch           # print final character
                   21492:        movl    r7,r6           # restore name offset
                   21493:        jmp     prn01           # merge back to exit
                   21494:        #page   
                   21495: #
                   21496: #      PRTNM (CONTINUED)
                   21497: #
                   21498: #      HERE FOR ARRAY OR TABLE
                   21499: #
                   21500: prn13: movl    $ch$bb,r6       # load left bracket
                   21501:        jsb     prtch           # and print it
                   21502:        movl    (sp),r10        # restore block pointer
                   21503:        movl    (r10),r8        # load type word again
                   21504:        cmpl    r8,$b$tet       # jump if not table
                   21505:        bnequ   prn15
                   21506: #
                   21507: #      HERE FOR TABLE, PRINT SUBSCRIPT VALUE
                   21508: #
                   21509:        movl    4*tesub(r10),r9 # load subscript value
                   21510:        movl    r7,r10          # save name offset
                   21511:        jsb     prtvl           # print subscript value
                   21512:        movl    r10,r7          # restore name offset
                   21513: #
                   21514: #      MERGE HERE FROM ARRAY CASE TO PRINT RIGHT BRACKET
                   21515: #
                   21516: prn14: movl    $ch$rb,r6       # load right bracket
                   21517:        jmp     prn12           # merge back to print it
                   21518: #
                   21519: #      HERE FOR ARRAY OR VECTOR, TO PRINT SUBSCRIPT(S)
                   21520: #
                   21521: prn15: movl    r7,r6           # copy name offset
                   21522:        ashl    $-2,r6,r6       # convert to words
                   21523:        cmpl    r8,$b$art       # jump if arblk
                   21524:        beqlu   prn16
                   21525: #
                   21526: #      HERE FOR VECTOR
                   21527: #
                   21528:        subl2   $vcvlb,r6       # adjust for standard fields
                   21529:        movl    r6,r5           # move to integer accum
                   21530:        jsb     prtin           # print linear subscript
                   21531:        jmp     prn14           # merge back for right bracket
                   21532:        #page   
                   21533: #
                   21534: #      PRTNM (CONTINUED)
                   21535: #
                   21536: #      HERE FOR ARRAY. FIRST CALCULATE ABSOLUTE SUBSCRIPT
                   21537: #      OFFSETS BY SUCCESSIVE DIVISIONS BY THE DIMENSION VALUES.
                   21538: #      THIS MUST BE DONE RIGHT TO LEFT SINCE THE ELEMENTS ARE
                   21539: #      STORED ROW-WISE. THE SUBSCRIPTS ARE STACKED AS INTEGERS.
                   21540: #
                   21541: prn16: movl    4*arofs(r10),r8 # load length of bounds info
                   21542:        addl2   $4,r8           # adjust for arpro field
                   21543:        ashl    $-2,r8,r8       # convert to words
                   21544:        subl2   r8,r6           # get linear zero-origin subscript
                   21545:        movl    r6,r5           # get integer value
                   21546:        movl    4*arndm(r10),r6 # set num of dimensions as loop count
                   21547:        addl2   4*arofs(r10),r10# point past bounds information
                   21548:        subl2   $4*arlbd,r10    # set ok offset for proper ptr later
                   21549: #
                   21550: #      LOOP TO STACK SUBSCRIPT OFFSETS
                   21551: #
                   21552: prn17: subl2   $4*ardms,r10    # point to next set of bounds
                   21553:        movl    r5,prnsi        # save current offset
                   21554:        ashq    $-32,r4,r4      # get remainder on dividing by dimens
                   21555:        ediv    4*ardim(r10),r4,r11,r5
                   21556:        movl    r5,-(sp)        # store on stack (one word)
                   21557:        movl    prnsi,r5        # reload argument
                   21558:        divl2   4*ardim(r10),r5 # divide to get quotient
                   21559:        sobgtr  r6,prn17        # loop till all stacked
                   21560:        clrl    r9              # set offset to first set of bounds
                   21561:        movl    4*arndm(r10),r7 # load count of dims to control loop
                   21562:        jmp     prn19           # jump into print loop
                   21563: #
                   21564: #      LOOP TO PRINT SUBSCRIPTS FROM STACK ADJUSTING BY ADDING
                   21565: #      THE APPROPRIATE LOW BOUND VALUE FROM THE ARBLK
                   21566: #
                   21567: prn18: movl    $ch$cm,r6       # load a comma
                   21568:        jsb     prtch           # print it
                   21569: #
                   21570: #      MERGE HERE FIRST TIME IN (NO COMMA REQUIRED)
                   21571: #
                   21572: prn19: movl    (sp)+,r5        # load subscript offset as integer
                   21573:        addl2   r9,r10          # point to current lbd
                   21574:        addl2   4*arlbd(r10),r5 # add lbd to get signed subscript
                   21575:        subl2   r9,r10          # point back to start of arblk
                   21576:        jsb     prtin           # print subscript
                   21577:        addl2   $4*ardms,r9     # bump offset to next bounds
                   21578:        sobgtr  r7,prn18        # loop back till all printed
                   21579:        jmp     prn14           # merge back to print right bracket
                   21580:        #enp                    # end procedure prtnm
                   21581:        #page   
                   21582: #
                   21583: #      PRTNV -- PRINT NAME VALUE
                   21584: #
                   21585: #      PRTNV IS USED BY THE TRACE AND DUMP ROUTINES TO PRINT
                   21586: #      A LINE OF THE FORM
                   21587: #
                   21588: #      NAME = VALUE
                   21589: #
                   21590: #      NOTE THAT THE NAME INVOLVED CAN NEVER BE A PSEUDO-VAR
                   21591: #
                   21592: #      (XL)                  NAME BASE
                   21593: #      (WA)                  NAME OFFSET
                   21594: #      JSR  PRTNV            CALL TO PRINT NAME = VALUE
                   21595: #      (WB,WC,RA)            DESTROYED
                   21596: #
                   21597: prtnv: #prc                    # entry point
                   21598:        jsb     prtnm           # print argument name
                   21599:        movl    r9,-(sp)        # save entry xr
                   21600:        movl    r6,-(sp)        # save name offset (collectable)
                   21601:        movl    $tmbeb,r9       # point to blank equal blank
                   21602:        jsb     prtst           # print it
                   21603:        movl    r10,r9          # copy name base
                   21604:        addl2   r6,r9           # point to value
                   21605:        movl    (r9),r9         # load value pointer
                   21606:        jsb     prtvl           # print value
                   21607:        jsb     prtnl           # terminate line
                   21608:        movl    (sp)+,r6        # restore name offset
                   21609:        movl    (sp)+,r9        # restore entry xr
                   21610:        rsb                     # return to caller
                   21611:        #enp                    # end procedure prtnv
                   21612:        #page   
                   21613: #
                   21614: #      PRTPG  -- PRINT A PAGE THROW
                   21615: #
                   21616: #      PRINTS A PAGE THROW OR A FEW BLANK LINES ON THE STANDARD
                   21617: #      LISTING CHANNEL DEPENDING ON THE LISTING OPTIONS CHOSEN.
                   21618: #
                   21619: #      JSR  PRTPG            CALL FOR PAGE EJECT
                   21620: #
                   21621: prtpg: #prc                    # entry point
                   21622:        cmpl    stage,$stgxt    # jump if execution time
                   21623:        beqlu   prp01
                   21624:        tstl    lstlc           # return if top of page already
                   21625:        bnequ   0f
                   21626:        jmp     prp06
                   21627: 0:             
                   21628:        clrl    lstlc           # clear line count
                   21629: #
                   21630: #      CHECK TYPE OF LISTING
                   21631: #
                   21632: prp01: movl    r9,-(sp)        # preserve xr
                   21633:        tstl    prstd           # eject if flag set
                   21634:        bnequ   prp02
                   21635:        tstl    prich           # jump if interactive listing channel
                   21636:        bnequ   prp03
                   21637:        tstl    precl           # jump if compact listing
                   21638:        beqlu   prp03
                   21639: #
                   21640: #      PERFORM AN EJECT
                   21641: #
                   21642: prp02: jsb     sysep           # eject
                   21643:        jmp     prp04           # merge
                   21644: #
                   21645: #      COMPACT OR INTERACTIVE CHANNEL LISTING. CANT PRINT
                   21646: #      BLANKS UNTIL CHECK MADE FOR HEADERS PRINTED AND FLAG SET.
                   21647: #
                   21648: #
                   21649: prp03: movl    headp,r9        # remember headp
                   21650:        movl    sp,headp        # set to avoid repeated prtpg calls
                   21651:        jsb     prtnl           # print blank line
                   21652:        jsb     prtnl           # print blank line
                   21653:        jsb     prtnl           # print blank line
                   21654:        movl    $num03,lstlc    # count blank lines
                   21655:        movl    r9,headp        # restore header flag
                   21656:        #page   
                   21657: #
                   21658: #      PRPTG (CONTINUED)
                   21659: #
                   21660: #      PRINT THE HEADING
                   21661: #
                   21662: prp04: tstl    headp           # jump if header listed
                   21663:        bnequ   prp05
                   21664:        movl    sp,headp        # mark headers printed
                   21665:        movl    r10,-(sp)       # keep xl
                   21666:        movl    $headr,r9       # point to listing header
                   21667:        jsb     prtst           # place it
                   21668:        jsb     sysid           # get system identification
                   21669:        jsb     prtst           # append extra chars
                   21670:        jsb     prtnl           # print it
                   21671:        movl    r10,r9          # extra header line
                   21672:        jsb     prtst           # place it
                   21673:        jsb     prtnl           # print it
                   21674:        jsb     prtnl           # print a blank
                   21675:        jsb     prtnl           # and another
                   21676:        addl2   $num04,lstlc    # four header lines printed
                   21677:        movl    (sp)+,r10       # restore xl
                   21678: #
                   21679: #      MERGE IF HEADER NOT PRINTED
                   21680: #
                   21681: prp05: movl    (sp)+,r9        # restore xr
                   21682: #
                   21683: #      RETURN
                   21684: #
                   21685: prp06: rsb                     # return
                   21686:        #enp                    # end procedure prtpg
                   21687:        #page   
                   21688: #
                   21689: #      PRTPS - PRINT PAGE WITH TEST FOR STANDARD LISTING OPTION
                   21690: #
                   21691: #      IF THE STANDARD LISTING OPTION IS SELECTED, INSIST THAT
                   21692: #      AN EJECT BE DONE
                   21693: #
                   21694: #      JSR  PRTPS            CALL FOR EJECT
                   21695: #
                   21696: prtps: #prc                    # entry point
                   21697:        movl    prsto,prstd     # copy option flag
                   21698:        jsb     prtpg           # print page
                   21699:        clrl    prstd           # clear flag
                   21700:        rsb                     # return
                   21701:        #enp                    # end procedure prtps
                   21702:        #page   
                   21703: #
                   21704: #      PRTSN -- PRINT STATEMENT NUMBER
                   21705: #
                   21706: #      PRTSN IS USED TO INITIATE A PRINT TRACE LINE BY PRINTING
                   21707: #      ASTERISKS AND THE CURRENT STATEMENT NUMBER. THE ACTUAL
                   21708: #      FORMAT OF THE OUTPUT GENERATED IS.
                   21709: #
                   21710: #      ***NNNNN**** III.....IIII
                   21711: #
                   21712: #      NNNNN IS THE STATEMENT NUMBER WITH LEADING ZEROS REPLACED
                   21713: #      BY ASTERISKS (E.G. *******9****)
                   21714: #
                   21715: #      III...III REPRESENTS A VARIABLE LENGTH OUTPUT CONSISTING
                   21716: #      OF A NUMBER OF LETTER I CHARACTERS EQUAL TO FNCLEVEL.
                   21717: #
                   21718: #      JSR  PRTSN            CALL TO PRINT STATEMENT NUMBER
                   21719: #      (WC)                  DESTROYED
                   21720: #
                   21721: prtsn: #prc                    # entry point
                   21722:        movl    r9,-(sp)        # save entry xr
                   21723:        movl    r6,prsna        # save entry wa
                   21724:        movl    $tmasb,r9       # point to asterisks
                   21725:        jsb     prtst           # print asterisks
                   21726:        movl    $num04,profs    # point into middle of asterisks
                   21727:        movl    kvstn,r5        # load statement number as integer
                   21728:        jsb     prtin           # print integer statement number
                   21729:        movl    $prsnf,profs    # point past asterisks plus blank
                   21730:        movl    kvfnc,r9        # get fnclevel
                   21731:        movl    $ch$li,r6       # set letter i
                   21732: #
                   21733: #      LOOP TO GENERATE LETTER I FNCLEVEL TIMES
                   21734: #
                   21735: prsn1: tstl    r9              # jump if all set
                   21736:        beqlu   prsn2
                   21737:        jsb     prtch           # else print an i
                   21738:        decl    r9              # decrement counter
                   21739:        jmp     prsn1           # loop back
                   21740: #
                   21741: #      MERRE WITH ALL LETTER I CHARACTERS GENERATED
                   21742: #
                   21743: prsn2: movl    $ch$bl,r6       # get blank
                   21744:        jsb     prtch           # print blank
                   21745:        movl    prsna,r6        # restore entry wa
                   21746:        movl    (sp)+,r9        # restore entry xr
                   21747:        rsb                     # return to prtsn caller
                   21748:        #enp                    # end procedure prtsn
                   21749:        #page   
                   21750: #
                   21751: #      PRTST -- PRINT STRING
                   21752: #
                   21753: #      PRTST PLACES A STRING OF CHARACTERS IN THE PRINT BUFFER
                   21754: #
                   21755: #      SEE PRTNL FOR GLOBAL LOCATIONS USED
                   21756: #
                   21757: #      NOTE THAT THE FIRST WORD OF THE BLOCK (NORMALLY B$SCL)
                   21758: #      IS NOT USED AND NEED NOT BE SET CORRECTLY (SEE PRTVN)
                   21759: #
                   21760: #      (XR)                  STRING TO BE PRINTED
                   21761: #      JSR  PRTST            CALL TO PRINT STRING
                   21762: #      (PROFS)               UPDATED PAST CHARS PLACED
                   21763: #
                   21764: prtst: #prc                    # entry point
                   21765:        tstl    headp           # were headers printed
                   21766:        bnequ   prst0
                   21767:        jsb     prtps           # no - print them
                   21768: #
                   21769: #      CALL SYSPR
                   21770: #
                   21771: prst0: movl    r6,prsva        # save wa
                   21772:        movl    r7,prsvb        # save wb
                   21773:        clrl    r7              # set chars printed count to zero
                   21774: #
                   21775: #      LOOP TO PRINT SUCCESSIVE LINES FOR LONG STRING
                   21776: #
                   21777: prst1: movl    4*sclen(r9),r6  # load string length
                   21778:        subl2   r7,r6           # subtract count of chars already out
                   21779:        bnequ   0f              # jump to exit if none left
                   21780:        jmp     prst4
                   21781: 0:             
                   21782:        movl    r10,-(sp)       # else stack entry xl
                   21783:        movl    r9,-(sp)        # save argument
                   21784:        movl    r9,r10          # copy for eventual move
                   21785:        movl    prlen,r9        # load print buffer length
                   21786:        subl2   profs,r9        # get chars left in print buffer
                   21787:        bnequ   prst2           # skip if room left on this line
                   21788:        jsb     prtnl           # else print this line
                   21789:        movl    prlen,r9        # and set full width available
                   21790:        #page   
                   21791: #
                   21792: #      PRTST (CONTINUED)
                   21793: #
                   21794: #      HERE WITH CHARS TO PRINT AND SOME ROOM IN BUFFER
                   21795: #
                   21796: prst2: cmpl    r6,r9           # jump if room for rest of string
                   21797:        blequ   prst3
                   21798:        movl    r9,r6           # else set to fill line
                   21799: #
                   21800: #      MERGE HERE WITH CHARACTER COUNT IN WA
                   21801: #
                   21802: prst3: movl    prbuf,r9        # point to print buffer
                   21803:        movab   cfp$f(r10)[r7],r10 # point to location in string
                   21804:        movl    profs,r11       # [get in scratch register]
                   21805:        movab   cfp$f(r9)[r11],r9# point to location in buffer
                   21806:        addl2   r6,r7           # bump string chars count
                   21807:        addl2   r6,profs        # bump buffer pointer
                   21808:        movl    r7,prsvc        # preserve char counter
                   21809:        jsb     sbmvc           # move characters to buffer
                   21810:        movl    prsvc,r7        # recover char counter
                   21811:        movl    (sp)+,r9        # restore argument pointer
                   21812:        movl    (sp)+,r10       # restore entry xl
                   21813:        jmp     prst1           # loop back to test for more
                   21814: #
                   21815: #      HERE TO EXIT AFTER PRINTING STRING
                   21816: #
                   21817: prst4: movl    prsvb,r7        # restore entry wb
                   21818:        movl    prsva,r6        # restore entry wa
                   21819:        rsb                     # return to prtst caller
                   21820:        #enp                    # end procedure prtst
                   21821:        #page   
                   21822: #
                   21823: #      PRTTR -- PRINT TO TERMINAL
                   21824: #
                   21825: #      CALLED TO PRINT CONTENTS OF STANDARD PRINT BUFFER TO
                   21826: #      ONLINE TERMINAL. CLEARS BUFFER DOWN AND RESETS PROFS.
                   21827: #
                   21828: #      JSR  PRTTR            CALL FOR PRINT
                   21829: #      (WA,WB)               DESTROYED
                   21830: #
                   21831: prttr: #prc                    # entry point
                   21832:        movl    r9,-(sp)        # save xr
                   21833:        jsb     prtic           # print buffer contents
                   21834:        movl    prbuf,r9        # point to print bfr to clear it
                   21835:        movl    prlnw,r6        # get buffer length
                   21836:        addl2   $4*schar,r9     # point past scblk header
                   21837:        movl    nullw,r7        # get blanks
                   21838: #
                   21839: #      LOOP TO CLEAR BUFFER
                   21840: #
                   21841: prtt1: movl    r7,(r9)+        # clear a word
                   21842:        sobgtr  r6,prtt1        # loop
                   21843:        clrl    profs           # reset profs
                   21844:        movl    (sp)+,r9        # restore xr
                   21845:        rsb                     # return
                   21846:        #enp                    # end procedure prttr
                   21847:        #page   
                   21848: #
                   21849: #      PRTVL -- PRINT A VALUE
                   21850: #
                   21851: #      PRTVL PLACES AN APPROPRIATE CHARACTER REPRESENTATION OF
                   21852: #      A DATA VALUE IN THE PRINT BUFFER FOR DUMP/TRACE USE.
                   21853: #
                   21854: #      (XR)                  VALUE TO BE PRINTED
                   21855: #      JSR  PRTVL            CALL TO PRINT VALUE
                   21856: #      (WA,WB,WC,RA)         DESTROYED
                   21857: #
                   21858: prtvl: #prc                    # entry point, recursive
                   21859:        movl    r10,-(sp)       # save entry xl
                   21860:        movl    r9,-(sp)        # save argument
                   21861:        jsb     sbchk           # check for stack overflow
                   21862: #
                   21863: #      LOOP BACK HERE AFTER FINDING A TRAP BLOCK (TRBLK)
                   21864: #
                   21865: prv01: movl    4*idval(r9),prvsi# copy idval (if any)
                   21866:        movl    (r9),r10        # load first word of block
                   21867:        movzwl  -2(r10),r10     # load entry point id
                   21868:        casel   r10,$0,$bl$$t   # switch on block type
                   21869: 5:             
                   21870:        .word   prv05-5b        # arblk
                   21871:        .word   prv15-5b        # bcblk
                   21872:        .word   prv02-5b
                   21873:        .word   prv02-5b
                   21874:        .word   prv08-5b        # icblk
                   21875:        .word   prv09-5b        # nmblk
                   21876:        .word   prv02-5b
                   21877:        .word   prv02-5b
                   21878:        .word   prv02-5b
                   21879:        .word   prv08-5b        # rcblk
                   21880:        .word   prv11-5b        # scblk
                   21881:        .word   prv12-5b        # seblk
                   21882:        .word   prv13-5b        # tbblk
                   21883:        .word   prv13-5b        # vcblk
                   21884:        .word   prv02-5b
                   21885:        .word   prv02-5b
                   21886:        .word   prv10-5b        # pdblk
                   21887:        .word   prv04-5b        # trblk
                   21888:        #esw                    # end of switch on block type
                   21889: #
                   21890: #      HERE FOR BLOCKS FOR WHICH WE JUST PRINT DATATYPE NAME
                   21891: #
                   21892: prv02: jsb     dtype           # get datatype name
                   21893:        jsb     prtst           # print datatype name
                   21894: #
                   21895: #      COMMON EXIT POINT
                   21896: #
                   21897: prv03: movl    (sp)+,r9        # reload argument
                   21898:        movl    (sp)+,r10       # restore xl
                   21899:        rsb                     # return to prtvl caller
                   21900: #
                   21901: #      HERE FOR TRBLK
                   21902: #
                   21903: prv04: movl    4*trval(r9),r9  # load real value
                   21904:        jmp     prv01           # and loop back
                   21905:        #page   
                   21906: #
                   21907: #      PRTVL (CONTINUED)
                   21908: #
                   21909: #      HERE FOR ARRAY (ARBLK)
                   21910: #
                   21911: #      PRINT ARRAY ( PROTOTYPE ) BLANK NUMBER IDVAL
                   21912: #
                   21913: prv05: movl    r9,r10          # preserve argument
                   21914:        movl    $scarr,r9       # point to datatype name (array)
                   21915:        jsb     prtst           # print it
                   21916:        movl    $ch$pp,r6       # load left paren
                   21917:        jsb     prtch           # print left paren
                   21918:        addl2   4*arofs(r10),r10# point to prototype
                   21919:        movl    (r10),r9        # load prototype
                   21920:        jsb     prtst           # print prototype
                   21921: #
                   21922: #      VCBLK, TBBLK, BCBLK MERGE HERE FOR ) BLANK NUMBER IDVAL
                   21923: #
                   21924: prv06: movl    $ch$rp,r6       # load right paren
                   21925:        jsb     prtch           # print right paren
                   21926: #
                   21927: #      PDBLK MERGES HERE TO PRINT BLANK NUMBER IDVAL
                   21928: #
                   21929: prv07: movl    $ch$bl,r6       # load blank
                   21930:        jsb     prtch           # print it
                   21931:        movl    $ch$nm,r6       # load number sign
                   21932:        jsb     prtch           # print it
                   21933:        movl    prvsi,r5        # get idval
                   21934:        jsb     prtin           # print id number
                   21935:        jmp     prv03           # back to exit
                   21936: #
                   21937: #      HERE FOR INTEGER (ICBLK), REAL (RCBLK)
                   21938: #
                   21939: #      PRINT CHARACTER REPRESENTATION OF VALUE
                   21940: #
                   21941: prv08: movl    r9,-(sp)        # stack argument for gtstg
                   21942:        jsb     gtstg           # convert to string
                   21943:        .long   invalid$        # error return is impossible
                   21944:        jsb     prtst           # print the string
                   21945:        movl    r9,dnamp        # delete garbage string from storage
                   21946:        jmp     prv03           # back to exit
                   21947:        #page   
                   21948: #
                   21949: #      PRTVL (CONTINUED)
                   21950: #
                   21951: #      NAME (NMBLK)
                   21952: #
                   21953: #      FOR PSEUDO-VARIABLE, JUST PRINT DATATYPE NAME (NAME)
                   21954: #      FOR ALL OTHER NAMES, PRINT DOT FOLLOWED BY NAME REP
                   21955: #
                   21956: prv09: movl    4*nmbas(r9),r10 # load name base
                   21957:        movl    (r10),r6        # load first word of block
                   21958:        cmpl    r6,$b$kvt       # just print name if keyword
                   21959:        bnequ   0f
                   21960:        jmp     prv02
                   21961: 0:             
                   21962:        cmpl    r6,$b$evt       # just print name if expression var
                   21963:        bnequ   0f
                   21964:        jmp     prv02
                   21965: 0:             
                   21966:        movl    $ch$dt,r6       # else get dot
                   21967:        jsb     prtch           # and print it
                   21968:        movl    4*nmofs(r9),r6  # load name offset
                   21969:        jsb     prtnm           # print name
                   21970:        jmp     prv03           # back to exit
                   21971: #
                   21972: #      PROGRAM DATATYPE (PDBLK)
                   21973: #
                   21974: #      PRINT DATATYPE NAME CH$BL CH$NM IDVAL
                   21975: #
                   21976: prv10: jsb     dtype           # get datatype name
                   21977:        jsb     prtst           # print datatype name
                   21978:        jmp     prv07           # merge back to print id
                   21979: #
                   21980: #      HERE FOR STRING (SCBLK)
                   21981: #
                   21982: #      PRINT QUOTE STRING-CHARACTERS QUOTE
                   21983: #
                   21984: prv11: movl    $ch$sq,r6       # load single quote
                   21985:        jsb     prtch           # print quote
                   21986:        jsb     prtst           # print string value
                   21987:        jsb     prtch           # print another quote
                   21988:        jmp     prv03           # back to exit
                   21989:        #page   
                   21990: #
                   21991: #      PRTVL (CONTINUED)
                   21992: #
                   21993: #      HERE FOR SIMPLE EXPRESSION (SEBLK)
                   21994: #
                   21995: #      PRINT ASTERISK VARIABLE-NAME
                   21996: #
                   21997: prv12: movl    $ch$as,r6       # load asterisk
                   21998:        jsb     prtch           # print asterisk
                   21999:        movl    4*sevar(r9),r9  # load variable pointer
                   22000:        jsb     prtvn           # print variable name
                   22001:        jmp     prv03           # jump back to exit
                   22002: #
                   22003: #      HERE FOR TABLE (TBBLK) AND ARRAY (VCBLK)
                   22004: #
                   22005: #      PRINT DATATYPE ( PROTOTYPE ) BLANK NUMBER IDVAL
                   22006: #
                   22007: prv13: movl    r9,r10          # preserve argument
                   22008:        jsb     dtype           # get datatype name
                   22009:        jsb     prtst           # print datatype name
                   22010:        movl    $ch$pp,r6       # load left paren
                   22011:        jsb     prtch           # print left paren
                   22012:        movl    4*tblen(r10),r6 # load length of block (=vclen)
                   22013:        ashl    $-2,r6,r6       # convert to word count
                   22014:        subl2   $tbsi$,r6       # allow for standard fields
                   22015:        cmpl    (r10),$b$tbt    # jump if table
                   22016:        beqlu   prv14
                   22017:        addl2   $vctbd,r6       # for vcblk, adjust size
                   22018: #
                   22019: #      PRINT PROTOTYPE
                   22020: #
                   22021: prv14: movl    r6,r5           # move as integer
                   22022:        jsb     prtin           # print integer prototype
                   22023:        jmp     prv06           # merge back for rest
                   22024:        #page   
                   22025: #
                   22026: #      PRTVL (CONTINUED)
                   22027: #
                   22028: #      HERE FOR BUFFER (BCBLK)
                   22029: #
                   22030: prv15: movl    r9,r10          # preserve argument
                   22031:        movl    $scbuf,r9       # point to datatype name (buffer)
                   22032:        jsb     prtst           # print it
                   22033:        movl    $ch$pp,r6       # load left paren
                   22034:        jsb     prtch           # print left paren
                   22035:        movl    4*bcbuf(r10),r9 # point to bfblk
                   22036:        movl    4*bfalc(r9),r5  # load allocation size
                   22037:        jsb     prtin           # print it
                   22038:        movl    $ch$cm,r6       # load comma
                   22039:        jsb     prtch           # print it
                   22040:        movl    4*bclen(r10),r5 # load defined length
                   22041:        jsb     prtin           # print it
                   22042:        jmp     prv06           # merge to finish up
                   22043:        #enp                    # end procedure prtvl
                   22044:        #page   
                   22045: #
                   22046: #      PRTVN -- PRINT NATURAL VARIABLE NAME
                   22047: #
                   22048: #      PRTVN PRINTS THE NAME OF A NATURAL VARIABLE
                   22049: #
                   22050: #      (XR)                  POINTER TO VRBLK
                   22051: #      JSR  PRTVN            CALL TO PRINT VARIABLE NAME
                   22052: #
                   22053: prtvn: #prc                    # entry point
                   22054:        movl    r9,-(sp)        # stack vrblk pointer
                   22055:        addl2   $4*vrsof,r9     # point to possible string name
                   22056:        tstl    4*sclen(r9)     # jump if not system variable
                   22057:        bnequ   prvn1
                   22058:        movl    4*vrsvo(r9),r9  # point to svblk with name
                   22059: #
                   22060: #      MERGE HERE WITH DUMMY SCBLK POINTER IN XR
                   22061: #
                   22062: prvn1: jsb     prtst           # print string name of variable
                   22063:        movl    (sp)+,r9        # restore vrblk pointer
                   22064:        rsb                     # return to prtvn caller
                   22065:        #enp                    # end procedure prtvn
                   22066:        #page   
                   22067: #
                   22068: #      RCBLD -- BUILD A REAL BLOCK
                   22069: #
                   22070: #      (RA)                  REAL VALUE FOR RCBLK
                   22071: #      JSR  RCBLD            CALL TO BUILD REAL BLOCK
                   22072: #      (XR)                  POINTER TO RESULT RCBLK
                   22073: #      (WA)                  DESTROYED
                   22074: #
                   22075: rcbld: #prc                    # entry point
                   22076:        movl    dnamp,r9        # load pointer to next available loc
                   22077:        addl2   $4*rcsi$,r9     # point past new rcblk
                   22078:        cmpl    r9,dname        # jump if there is room
                   22079:        blequ   rcbl1
                   22080:        movl    $4*rcsi$,r6     # else load rcblk length
                   22081:        jsb     alloc           # use standard allocator to get block
                   22082:        addl2   r6,r9           # point past block to merge
                   22083: #
                   22084: #      MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED
                   22085: #
                   22086: rcbl1: movl    r9,dnamp        # set new pointer
                   22087:        subl2   $4*rcsi$,r9     # point back to start of block
                   22088:        movl    $b$rcl,(r9)     # store type word
                   22089:        movf    r2,4*rcval(r9)  # store real value in rcblk
                   22090:        rsb                     # return to rcbld caller
                   22091:        #enp                    # end procedure rcbld
                   22092:        #page   
                   22093: #
                   22094: #      READR -- READ NEXT SOURCE IMAGE AT COMPILE TIME
                   22095: #
                   22096: #      READR IS USED TO READ THE NEXT SOURCE IMAGE. TO PROCESS
                   22097: #      CONTINUATION CARDS PROPERLY, THE COMPILER MUST READ ONE
                   22098: #      LINE AHEAD. THUS READR DOES NOT DESTROY THE CURRENT IMAGE
                   22099: #      SEE ALSO THE NEXTS ROUTINE WHICH ACTUALLY GETS THE IMAGE.
                   22100: #
                   22101: #      JSR  READR            CALL TO READ NEXT IMAGE
                   22102: #      (XR)                  PTR TO NEXT IMAGE (0 IF NONE)
                   22103: #      (R$CNI)               COPY OF POINTER
                   22104: #      (WA,WB,WC,XL)         DESTROYED
                   22105: #
                   22106: readr: #prc                    # entry point
                   22107:        movl    r$cni,r9        # get ptr to next image
                   22108:        bnequ   read3           # exit if already read
                   22109:        cmpl    stage,$stgic    # exit if not initial compile
                   22110:        bnequ   read3
                   22111:        movl    cswin,r6        # max read length
                   22112:        jsb     alocs           # allocate buffer
                   22113:        jsb     sysrd           # read input image
                   22114:        .long   read4           # jump if end of file
                   22115:        movl    sp,r7           # set trimr to perform trim
                   22116:        cmpl    4*sclen(r9),cswin# use smaller of string lnth ..
                   22117:        blequ   read1
                   22118:        movl    cswin,4*sclen(r9)# ... and xxx of -inxxx
                   22119: #
                   22120: #      PERFORM THE TRIM
                   22121: #
                   22122: read1: jsb     trimr           # trim trailing blanks
                   22123: #
                   22124: #      MERGE HERE AFTER READ
                   22125: #
                   22126: read2: movl    r9,r$cni        # store copy of pointer
                   22127: #
                   22128: #      MERGE HERE IF NO READ ATTEMPTED
                   22129: #
                   22130: read3: rsb                     # return to readr caller
                   22131: #
                   22132: #      HERE ON END OF FILE
                   22133: #
                   22134: read4: movl    r9,dnamp        # pop unused scblk
                   22135:        clrl    r9              # zero ptr as result
                   22136:        jmp     read2           # merge
                   22137:        #enp                    # end procedure readr
                   22138:        #page   
                   22139: #
                   22140: #      SBSTR -- BUILD A SUBSTRING
                   22141: #
                   22142: #      (XL)                  PTR TO SCBLK/BFBLK WITH CHARS
                   22143: #      (WA)                  NUMBER OF CHARS IN SUBSTRING
                   22144: #      (WB)                  OFFSET TO FIRST CHAR IN SCBLK
                   22145: #      JSR  SBSTR            CALL TO BUILD SUBSTRING
                   22146: #      (XR)                  PTR TO NEW SCBLK WITH SUBSTRING
                   22147: #      (XL)                  ZERO
                   22148: #      (WA,WB,WC,XL,IA)      DESTROYED
                   22149: #
                   22150: #      NOTE THAT SBSTR IS CALLED WITH A DUMMY STRING POINTER
                   22151: #      (POINTING INTO A VRBLK OR SVBLK) TO COPY THE NAME OF A
                   22152: #      VARIABLE AS A STANDARD STRING VALUE.
                   22153: #
                   22154: sbstr: #prc                    # entry point
                   22155:        tstl    r6              # jump if null substring
                   22156:        beqlu   sbst2
                   22157:        jsb     alocs           # else allocate scblk
                   22158:        movl    r8,r6           # move number of characters
                   22159:        movl    r9,r8           # save ptr to new scblk
                   22160:        movab   cfp$f(r10)[r7],r10 # prepare to load chars from old blk
                   22161:        movab   cfp$f(r9),r9    # prepare to store chars in new blk
                   22162:        jsb     sbmvc           # move characters to new string
                   22163:        movl    r8,r9           # then restore scblk pointer
                   22164: #
                   22165: #      RETURN POINT
                   22166: #
                   22167: sbst1: clrl    r10             # clear garbage pointer in xl
                   22168:        rsb                     # return to sbstr caller
                   22169: #
                   22170: #      HERE FOR NULL SUBSTRING
                   22171: #
                   22172: sbst2: movl    $nulls,r9       # set null string as result
                   22173:        jmp     sbst1           # return
                   22174:        #enp                    # end procedure sbstr
                   22175:        #page   
                   22176: #
                   22177: #      SCANE -- SCAN AN ELEMENT
                   22178: #
                   22179: #      SCANE IS CALLED AT COMPILE TIME (BY EXPAN ,CMPIL,CNCRD)
                   22180: #      TO SCAN ONE ELEMENT FROM THE INPUT IMAGE.
                   22181: #
                   22182: #      (SCNCC)               NON-ZERO IF CALLED FROM CNCRD
                   22183: #      JSR  SCANE            CALL TO SCAN ELEMENT
                   22184: #      (XR)                  RESULT POINTER (SEE BELOW)
                   22185: #      (XL)                  SYNTAX TYPE CODE (T$XXX)
                   22186: #
                   22187: #      THE FOLLOWING GLOBAL LOCATIONS ARE USED.
                   22188: #
                   22189: #      R$CIM                 POINTER TO STRING BLOCK (SCBLK)
                   22190: #                            FOR CURRENT INPUT IMAGE.
                   22191: #
                   22192: #      R$CNI                 POINTER TO NEXT INPUT IMAGE STRING
                   22193: #                            POINTER (ZERO IF NONE).
                   22194: #
                   22195: #      R$SCP                 SAVE POINTER (EXIT XR) FROM LAST
                   22196: #                            CALL IN CASE RESCAN IS SET.
                   22197: #
                   22198: #      SCNBL                 THIS LOCATION IS SET NON-ZERO ON
                   22199: #                            EXIT IF SCANE SCANNED PAST BLANKS
                   22200: #                            BEFORE LOCATING THE CURRENT ELEMENT
                   22201: #                            THE END OF A LINE COUNTS AS BLANKS.
                   22202: #
                   22203: #      SCNCC                 CNCRD SETS THIS NON-ZERO TO SCAN
                   22204: #                            CONTROL CARD NAMES AND CLEARS IT
                   22205: #                            ON RETURN
                   22206: #
                   22207: #      SCNIL                 LENGTH OF CURRENT INPUT IMAGE
                   22208: #
                   22209: #      SCNGO                 IF SET NON-ZERO ON ENTRY, F AND S
                   22210: #                            ARE RETURNED AS SEPARATE SYNTAX
                   22211: #                            TYPES (NOT LETTERS) (GOTO PRO-
                   22212: #                            CESSING). SCNGO IS RESET ON EXIT.
                   22213: #
                   22214: #      SCNPT                 OFFSET TO CURRENT LOC IN R$CIM
                   22215: #
                   22216: #      SCNRS                 IF SET NON-ZERO ON ENTRY, SCANE
                   22217: #                            RETURNS THE SAME RESULT AS ON THE
                   22218: #                            LAST CALL (RESCAN). SCNRS IS RESET
                   22219: #                            ON EXIT FROM ANY CALL TO SCANE.
                   22220: #
                   22221: #      SCNTP                 SAVE SYNTAX TYPE FROM LAST
                   22222: #                            CALL (IN CASE RESCAN IS SET).
                   22223:        #page   
                   22224: #
                   22225: #      SCANE (CONTINUED)
                   22226: #
                   22227: #
                   22228: #
                   22229: #      ELEMENT SCANNED       XL        XR
                   22230: #      ---------------       --        --
                   22231: #
                   22232: #      CONTROL CARD NAME     0         POINTER TO SCBLK FOR NAME
                   22233: #
                   22234: #      UNARY OPERATOR        T$UOP     PTR TO OPERATOR DVBLK
                   22235: #
                   22236: #      LEFT PAREN            T$LPR     T$LPR
                   22237: #
                   22238: #      LEFT BRACKET          T$LBR     T$LBR
                   22239: #
                   22240: #      COMMA                 T$CMA     T$CMA
                   22241: #
                   22242: #      FUNCTION CALL         T$FNC     PTR TO FUNCTION VRBLK
                   22243: #
                   22244: #      VARIABLE              T$VAR     PTR TO VRBLK
                   22245: #
                   22246: #      STRING CONSTANT       T$CON     PTR TO SCBLK
                   22247: #
                   22248: #      INTEGER CONSTANT      T$CON     PTR TO ICBLK
                   22249: #
                   22250: #      REAL CONSTANT         T$CON     PTR TO RCBLK
                   22251: #
                   22252: #      BINARY OPERATOR       T$BOP     PTR TO OPERATOR DVBLK
                   22253: #
                   22254: #      RIGHT PAREN           T$RPR     T$RPR
                   22255: #
                   22256: #      RIGHT BRACKET         T$RBR     T$RBR
                   22257: #
                   22258: #      COLON                 T$COL     T$COL
                   22259: #
                   22260: #      SEMI-COLON            T$SMC     T$SMC
                   22261: #
                   22262: #      F (SCNGO NE 0)        T$FGO     T$FGO
                   22263: #
                   22264: #      S (SCNGO NE 0)        T$SGO     T$SGO
                   22265:        #page   
                   22266: #
                   22267: #      SCANE (CONTINUED)
                   22268: #
                   22269: #      ENTRY POINT
                   22270: #
                   22271: scane: #prc                    # entry point
                   22272:        clrl    scnbl           # reset blanks flag
                   22273:        movl    r6,scnsa        # save wa
                   22274:        movl    r7,scnsb        # save wb
                   22275:        movl    r8,scnsc        # save wc
                   22276:        tstl    scnrs           # jump if no rescan
                   22277:        beqlu   scn03
                   22278: #
                   22279: #      HERE FOR RESCAN REQUEST
                   22280: #
                   22281:        movl    scntp,r10       # set previous returned scan type
                   22282:        movl    r$scp,r9        # set previous returned pointer
                   22283:        clrl    scnrs           # reset rescan switch
                   22284:        jmp     scn13           # jump to exit
                   22285: #
                   22286: #      COME HERE TO READ NEW IMAGE TO TEST FOR CONTINUATION
                   22287: #
                   22288: scn01: jsb     readr           # read next image
                   22289:        movl    $4*dvubs,r7     # set wb for not reading name
                   22290:        tstl    r9              # treat as semi-colon if none
                   22291:        bnequ   0f
                   22292:        jmp     scn30
                   22293: 0:             
                   22294:        movab   cfp$f(r9),r9    # else point to first character
                   22295:        movzbl  (r9),r8         # load first character
                   22296:        cmpl    r8,$ch$dt       # jump if dot for continuation
                   22297:        beqlu   scn02
                   22298:        cmpl    r8,$ch$pl       # else treat as semicolon unless plus
                   22299:        beqlu   0f
                   22300:        jmp     scn30
                   22301: 0:             
                   22302: #
                   22303: #      HERE FOR CONTINUATION LINE
                   22304: #
                   22305: scn02: jsb     nexts           # acquire next source image
                   22306:        movl    $num01,scnpt    # set scan pointer past continuation
                   22307:        movl    sp,scnbl        # set blanks flag
                   22308:        #page   
                   22309: #
                   22310: #      SCANE (CONTINUED)
                   22311: #
                   22312: #      MERGE HERE TO SCAN NEXT ELEMENT ON CURRENT LINE
                   22313: #
                   22314: scn03: movl    scnpt,r6        # load current offset
                   22315:        cmpl    r6,scnil        # check continuation if end
                   22316:        bnequ   0f
                   22317:        jmp     scn01
                   22318: 0:             
                   22319:        movl    r$cim,r10       # point to current line
                   22320:        movab   cfp$f(r10)[r6],r10 # point to current character
                   22321:        movl    r6,scnse        # set start of element location
                   22322:        movl    $opdvs,r8       # point to operator dv list
                   22323:        movl    $4*dvubs,r7     # set constant for operator circuit
                   22324:        jmp     scn06           # start scanning
                   22325: #
                   22326: #      LOOP HERE TO IGNORE LEADING BLANKS AND TABS
                   22327: #
                   22328: scn05: tstl    r7              # jump if trailing
                   22329:        bnequ   0f
                   22330:        jmp     scn10
                   22331: 0:             
                   22332:        incl    scnse           # increment start of element
                   22333:        cmpl    r6,scnil        # jump if end of image
                   22334:        bnequ   0f
                   22335:        jmp     scn01
                   22336: 0:             
                   22337:        movl    sp,scnbl        # note blanks seen
                   22338: #
                   22339: #      THE FOLLOWING JUMP IS USED REPEATEDLY FOR SCANNING OUT
                   22340: #      THE CHARACTERS OF A NUMERIC CONSTANT OR VARIABLE NAME.
                   22341: #      THE REGISTERS ARE USED AS FOLLOWS.
                   22342: #
                   22343: #      (XR)                  SCRATCH
                   22344: #      (XL)                  PTR TO NEXT CHARACTER
                   22345: #      (WA)                  CURRENT SCAN OFFSET
                   22346: #      (WB)                  *DVUBS (0 IF SCANNING NAME,CONST)
                   22347: #      (WC)                  =OPDVS (0 IF SCANNING CONSTANT)
                   22348: #
                   22349: scn06: movzbl  (r10)+,r9       # get next character
                   22350:        incl    r6              # bump scan offset
                   22351:        movl    r6,scnpt        # store offset past char scanned
                   22352:        cmpl    $cfp$u,r9       # quick check for other char
                   22353:        bgtru   0f
                   22354:        jmp     scn07
                   22355: 0:             
                   22356:        casel   r9,$0,$cfp$u    # switch on scanned character
                   22357: 5:             
                   22358: #
                   22359: #      SWITCH TABLE FOR SWITCH ON CHARACTER
                   22360: #
                   22361:        #page   
                   22362: #
                   22363: #      SCANE (CONTINUED)
                   22364: #
                   22365:        #page   
                   22366: #
                   22367: #      SCANE (CONTINUED)
                   22368: #
                   22369:        .word   scn07-5b
                   22370:        .word   scn07-5b
                   22371:        .word   scn07-5b
                   22372:        .word   scn07-5b
                   22373:        .word   scn07-5b
                   22374:        .word   scn07-5b
                   22375:        .word   scn07-5b
                   22376:        .word   scn07-5b
                   22377:        .word   scn07-5b
                   22378:        .word   scn05-5b        # horizontal tab
                   22379:        .word   scn07-5b
                   22380:        .word   scn07-5b
                   22381:        .word   scn07-5b
                   22382:        .word   scn07-5b
                   22383:        .word   scn07-5b
                   22384:        .word   scn07-5b
                   22385:        .word   scn07-5b
                   22386:        .word   scn07-5b
                   22387:        .word   scn07-5b
                   22388:        .word   scn07-5b
                   22389:        .word   scn07-5b
                   22390:        .word   scn07-5b
                   22391:        .word   scn07-5b
                   22392:        .word   scn07-5b
                   22393:        .word   scn07-5b
                   22394:        .word   scn07-5b
                   22395:        .word   scn07-5b
                   22396:        .word   scn07-5b
                   22397:        .word   scn07-5b
                   22398:        .word   scn07-5b
                   22399:        .word   scn07-5b
                   22400:        .word   scn07-5b
                   22401:        .word   scn05-5b        # blank
                   22402:        .word   scn37-5b        # exclamation mark
                   22403:        .word   scn17-5b        # double quote
                   22404:        .word   scn41-5b        # number sign
                   22405:        .word   scn36-5b        # dollar
                   22406:        .word   scn38-5b        # percent
                   22407:        .word   scn44-5b        # ampersand
                   22408:        .word   scn16-5b        # single quote
                   22409:        .word   scn25-5b        # left paren
                   22410:        .word   scn26-5b        # right paren
                   22411:        .word   scn49-5b        # asterisk
                   22412:        .word   scn33-5b        # plus
                   22413:        .word   scn31-5b        # comma
                   22414:        .word   scn34-5b        # minus
                   22415:        .word   scn32-5b        # dot
                   22416:        .word   scn40-5b        # slash
                   22417:        .word   scn08-5b        # digit 0
                   22418:        .word   scn08-5b        # digit 1
                   22419:        .word   scn08-5b        # digit 2
                   22420:        .word   scn08-5b        # digit 3
                   22421:        .word   scn08-5b        # digit 4
                   22422:        .word   scn08-5b        # digit 5
                   22423:        .word   scn08-5b        # digit 6
                   22424:        .word   scn08-5b        # digit 7
                   22425:        .word   scn08-5b        # digit 8
                   22426:        .word   scn08-5b        # digit 9
                   22427:        .word   scn29-5b        # colon
                   22428:        .word   scn30-5b        # semi-colon
                   22429:        .word   scn28-5b        # left bracket
                   22430:        .word   scn46-5b        # equal
                   22431:        .word   scn27-5b        # right bracket
                   22432:        .word   scn45-5b        # question mark
                   22433:        .word   scn42-5b        # at
                   22434:        .word   scn09-5b        # letter a
                   22435:        .word   scn09-5b        # letter b
                   22436:        .word   scn09-5b        # letter c
                   22437:        .word   scn09-5b        # letter d
                   22438:        .word   scn09-5b        # letter e
                   22439:        .word   scn20-5b        # letter f
                   22440:        .word   scn09-5b        # letter g
                   22441:        .word   scn09-5b        # letter h
                   22442:        .word   scn09-5b        # letter i
                   22443:        .word   scn09-5b        # letter j
                   22444:        .word   scn09-5b        # letter k
                   22445:        .word   scn09-5b        # letter l
                   22446:        .word   scn09-5b        # letter m
                   22447:        .word   scn09-5b        # letter n
                   22448:        .word   scn09-5b        # letter o
                   22449:        .word   scn09-5b        # letter p
                   22450:        .word   scn09-5b        # letter q
                   22451:        .word   scn09-5b        # letter r
                   22452:        .word   scn21-5b        # letter s
                   22453:        .word   scn09-5b        # letter t
                   22454:        .word   scn09-5b        # letter u
                   22455:        .word   scn09-5b        # letter v
                   22456:        .word   scn09-5b        # letter w
                   22457:        .word   scn09-5b        # letter x
                   22458:        .word   scn09-5b        # letter y
                   22459:        .word   scn09-5b        # letter z
                   22460:        .word   scn28-5b        # left bracket
                   22461:        .word   scn07-5b
                   22462:        .word   scn27-5b        # right bracket
                   22463:        .word   scn07-5b
                   22464:        .word   scn24-5b        # underline
                   22465:        .word   scn07-5b
                   22466:        .word   scn09-5b        # shifted a
                   22467:        .word   scn09-5b        # shifted b
                   22468:        .word   scn09-5b        # shifted c
                   22469:        .word   scn09-5b        # shifted d
                   22470:        .word   scn09-5b        # shifted e
                   22471:        .word   scn20-5b        # shifted f
                   22472:        .word   scn09-5b        # shifted g
                   22473:        .word   scn09-5b        # shifted h
                   22474:        .word   scn09-5b        # shifted i
                   22475:        .word   scn09-5b        # shifted j
                   22476:        .word   scn09-5b        # shifted k
                   22477:        .word   scn09-5b        # shifted l
                   22478:        .word   scn09-5b        # shifted m
                   22479:        .word   scn09-5b        # shifted n
                   22480:        .word   scn09-5b        # shifted o
                   22481:        .word   scn09-5b        # shifted p
                   22482:        .word   scn09-5b        # shifted q
                   22483:        .word   scn09-5b        # shifted r
                   22484:        .word   scn21-5b        # shifted s
                   22485:        .word   scn09-5b        # shifted t
                   22486:        .word   scn09-5b        # shifted u
                   22487:        .word   scn09-5b        # shifted v
                   22488:        .word   scn09-5b        # shifted w
                   22489:        .word   scn09-5b        # shifted x
                   22490:        .word   scn09-5b        # shifted y
                   22491:        .word   scn09-5b        # shifted z
                   22492:        .word   scn07-5b
                   22493:        .word   scn43-5b        # vertical bar
                   22494:        .word   scn07-5b
                   22495:        .word   scn35-5b        # not
                   22496:        .word   scn07-5b
                   22497:        #esw                    # end switch on character
                   22498: #
                   22499: #      HERE FOR ILLEGAL CHARACTER (UNDERLINE MERGES)
                   22500: #
                   22501: scn07: tstl    r7              # jump if scanning name or constant
                   22502:        bnequ   0f
                   22503:        jmp     scn10
                   22504: 0:             
                   22505:        jmp     er_230          # syntax error. illegal character
                   22506:        #page   
                   22507: #
                   22508: #      SCANE (CONTINUED)
                   22509: #
                   22510: #      HERE FOR DIGITS 0-9
                   22511: #
                   22512: scn08: tstl    r7              # keep scanning if name/constant
                   22513:        bnequ   0f
                   22514:        jmp     scn09
                   22515: 0:             
                   22516:        clrl    r8              # else set flag for scanning constant
                   22517: #
                   22518: #      HERE FOR LETTER. LOOP HERE WHEN SCANNING NAME/CONSTANT
                   22519: #
                   22520: scn09: cmpl    r6,scnil        # jump if end of image
                   22521:        beqlu   scn11
                   22522:        clrl    r7              # set flag for scanning name/const
                   22523:        jmp     scn06           # merge back to continue scan
                   22524: #
                   22525: #      COME HERE FOR DELIMITER ENDING NAME OR CONSTANT
                   22526: #
                   22527: scn10: decl    r6              # reset offset to point to delimiter
                   22528: #
                   22529: #      COME HERE AFTER FINISHING SCAN OF NAME OR CONSTANT
                   22530: #
                   22531: scn11: movl    r6,scnpt        # store updated scan offset
                   22532:        movl    scnse,r7        # point to start of element
                   22533:        subl2   r7,r6           # get number of characters
                   22534:        movl    r$cim,r10       # point to line image
                   22535:        tstl    r8              # jump if name
                   22536:        bnequ   scn15
                   22537: #
                   22538: #      HERE AFTER SCANNING OUT NUMERIC CONSTANT
                   22539: #
                   22540:        jsb     sbstr           # get string for constant
                   22541:        movl    r9,dnamp        # delete from storage (not needed)
                   22542:        jsb     gtnum           # convert to numeric
                   22543:        .long   scn14           # jump if conversion failure
                   22544: #
                   22545: #      MERGE HERE TO EXIT WITH CONSTANT
                   22546: #
                   22547: scn12: movl    $t$con,r10      # set result type of constant
                   22548:        #page   
                   22549: #
                   22550: #      SCANE (CONTINUED)
                   22551: #
                   22552: #      COMMON EXIT POINT (XR,XL) SET
                   22553: #
                   22554: scn13: movl    scnsa,r6        # restore wa
                   22555:        movl    scnsb,r7        # restore wb
                   22556:        movl    scnsc,r8        # restore wc
                   22557:        movl    r9,r$scp        # save xr in case rescan
                   22558:        movl    r10,scntp       # save xl in case rescan
                   22559:        clrl    scngo           # reset possible goto flag
                   22560:        rsb                     # return to scane caller
                   22561: #
                   22562: #      HERE IF CONVERSION ERROR ON NUMERIC ITEM
                   22563: #
                   22564: scn14: jmp     er_231          # syntax error. invalid numeric item
                   22565: #
                   22566: #      HERE AFTER SCANNING OUT VARIABLE NAME
                   22567: #
                   22568: scn15: jsb     sbstr           # build string name of variable
                   22569:        tstl    scncc           # return if cncrd call
                   22570:        beqlu   0f
                   22571:        jmp     scn13
                   22572: 0:             
                   22573:        jsb     gtnvr           # locate/build vrblk
                   22574:        .long   invalid$        # dummy (unused) error return
                   22575:        movl    $t$var,r10      # set type as variable
                   22576:        jmp     scn13           # back to exit
                   22577: #
                   22578: #      HERE FOR SINGLE QUOTE (START OF STRING CONSTANT)
                   22579: #
                   22580: scn16: tstl    r7              # terminator if scanning name or cnst
                   22581:        bnequ   0f
                   22582:        jmp     scn10
                   22583: 0:             
                   22584:        movl    $ch$sq,r7       # set terminator as single quote
                   22585:        jmp     scn18           # merge
                   22586: #
                   22587: #      HERE FOR DOUBLE QUOTE (START OF STRING CONSTANT)
                   22588: #
                   22589: scn17: tstl    r7              # terminator if scanning name or cnst
                   22590:        bnequ   0f
                   22591:        jmp     scn10
                   22592: 0:             
                   22593:        movl    $ch$dq,r7       # set double quote terminator, merge
                   22594: #
                   22595: #      LOOP TO SCAN OUT STRING CONSTANT
                   22596: #
                   22597: scn18: cmpl    r6,scnil        # error if end of image
                   22598:        beqlu   scn19
                   22599:        movzbl  (r10)+,r8       # else load next character
                   22600:        incl    r6              # bump offset
                   22601:        cmpl    r8,r7           # loop back if not terminator
                   22602:        bnequ   scn18
                   22603:        #page   
                   22604: #
                   22605: #      SCANE (CONTINUED)
                   22606: #
                   22607: #      HERE AFTER SCANNING OUT STRING CONSTANT
                   22608: #
                   22609:        movl    scnpt,r7        # point to first character
                   22610:        movl    r6,scnpt        # save offset past final quote
                   22611:        decl    r6              # point back past last character
                   22612:        subl2   r7,r6           # get number of characters
                   22613:        movl    r$cim,r10       # point to input image
                   22614:        jsb     sbstr           # build substring value
                   22615:        jmp     scn12           # back to exit with constant result
                   22616: #
                   22617: #      HERE IF NO MATCHING QUOTE FOUND
                   22618: #
                   22619: scn19: movl    r6,scnpt        # set updated scan pointer
                   22620:        jmp     er_232          # syntax error. unmatched string quote
                   22621: #
                   22622: #      HERE FOR F (POSSIBLE FAILURE GOTO)
                   22623: #
                   22624: scn20: movl    $t$fgo,r9       # set return code for fail goto
                   22625:        jmp     scn22           # jump to merge
                   22626: #
                   22627: #      HERE FOR S (POSSIBLE SUCCESS GOTO)
                   22628: #
                   22629: scn21: movl    $t$sgo,r9       # set success goto as return code
                   22630: #
                   22631: #      SPECIAL GOTO CASES MERGE HERE
                   22632: #
                   22633: scn22: tstl    scngo           # treat as normal letter if not goto
                   22634:        bnequ   0f
                   22635:        jmp     scn09
                   22636: 0:             
                   22637: #
                   22638: #      MERGE HERE FOR SPECIAL CHARACTER EXIT
                   22639: #
                   22640: scn23: tstl    r7              # jump if end of name/constant
                   22641:        bnequ   0f
                   22642:        jmp     scn10
                   22643: 0:             
                   22644:        movl    r9,r10          # else copy code
                   22645:        jmp     scn13           # and jump to exit
                   22646: #
                   22647: #      HERE FOR UNDERLINE
                   22648: #
                   22649: scn24: tstl    r7              # part of name if scanning name
                   22650:        bnequ   0f
                   22651:        jmp     scn09
                   22652: 0:             
                   22653:        jmp     scn07           # else illegal
                   22654:        #page   
                   22655: #
                   22656: #      SCANE (CONTINUED)
                   22657: #
                   22658: #      HERE FOR LEFT PAREN
                   22659: #
                   22660: scn25: movl    $t$lpr,r9       # set left paren return code
                   22661:        tstl    r7              # return left paren unless name
                   22662:        bnequ   scn23
                   22663:        tstl    r8              # delimiter if scanning constant
                   22664:        bnequ   0f
                   22665:        jmp     scn10
                   22666: 0:             
                   22667: #
                   22668: #      HERE FOR LEFT PAREN AFTER NAME (FUNCTION CALL)
                   22669: #
                   22670:        movl    scnse,r7        # point to start of name
                   22671:        movl    r6,scnpt        # set pointer past left paren
                   22672:        decl    r6              # point back past last char of name
                   22673:        subl2   r7,r6           # get name length
                   22674:        movl    r$cim,r10       # point to input image
                   22675:        jsb     sbstr           # get string name for function
                   22676:        jsb     gtnvr           # locate/build vrblk
                   22677:        .long   invalid$        # dummy (unused) error return
                   22678:        movl    $t$fnc,r10      # set code for function call
                   22679:        jmp     scn13           # back to exit
                   22680: #
                   22681: #      PROCESSING FOR SPECIAL CHARACTERS
                   22682: #
                   22683: scn26: movl    $t$rpr,r9       # right paren, set code
                   22684:        jmp     scn23           # take special character exit
                   22685: #
                   22686: scn27: movl    $t$rbr,r9       # right bracket, set code
                   22687:        jmp     scn23           # take special character exit
                   22688: #
                   22689: scn28: movl    $t$lbr,r9       # left bracket, set code
                   22690:        jmp     scn23           # take special character exit
                   22691: #
                   22692: scn29: movl    $t$col,r9       # colon, set code
                   22693:        jmp     scn23           # take special character exit
                   22694: #
                   22695: scn30: movl    $t$smc,r9       # semi-colon, set code
                   22696:        jmp     scn23           # take special character exit
                   22697: #
                   22698: scn31: movl    $t$cma,r9       # comma, set code
                   22699:        jmp     scn23           # take special character exit
                   22700:        #page   
                   22701: #
                   22702: #      SCANE (CONTINUED)
                   22703: #
                   22704: #      HERE FOR OPERATORS. ON ENTRY, WC POINTS TO THE TABLE OF
                   22705: #      OPERATOR DOPE VECTORS AND WB IS THE INCREMENT TO STEP
                   22706: #      TO THE NEXT PAIR (BINARY/UNARY) OF DOPE VECTORS IN THE
                   22707: #      LIST. ON REACHING SCN46, THE POINTER HAS BEEN ADJUSTED TO
                   22708: #      POINT TO THE APPROPRIATE PAIR OF DOPE VECTORS.
                   22709: #      THE FIRST THREE ENTRIES ARE SPECIAL SINCE THEY CAN OCCUR
                   22710: #      AS PART OF A VARIABLE NAME (.) OR CONSTANT (.+-).
                   22711: #
                   22712: scn32: tstl    r7              # dot can be part of name or constant
                   22713:        bnequ   0f
                   22714:        jmp     scn09
                   22715: 0:             
                   22716:        addl2   r7,r8           # else bump pointer
                   22717: #
                   22718: scn33: tstl    r8              # plus can be part of constant
                   22719:        bnequ   0f
                   22720:        jmp     scn09
                   22721: 0:             
                   22722:        tstl    r7              # plus cannot be part of name
                   22723:        bnequ   0f
                   22724:        jmp     scn48
                   22725: 0:             
                   22726:        addl2   r7,r8           # else bump pointer
                   22727: #
                   22728: scn34: tstl    r8              # minus can be part of constant
                   22729:        bnequ   0f
                   22730:        jmp     scn09
                   22731: 0:             
                   22732:        tstl    r7              # minus cannot be part of name
                   22733:        bnequ   0f
                   22734:        jmp     scn48
                   22735: 0:             
                   22736:        addl2   r7,r8           # else bump pointer
                   22737: #
                   22738: scn35: addl2   r7,r8           # not
                   22739: scn36: addl2   r7,r8           # dollar
                   22740: scn37: addl2   r7,r8           # exclamation
                   22741: scn38: addl2   r7,r8           # percent
                   22742: scn39: addl2   r7,r8           # asterisk
                   22743: scn40: addl2   r7,r8           # slash
                   22744: scn41: addl2   r7,r8           # number sign
                   22745: scn42: addl2   r7,r8           # at sign
                   22746: scn43: addl2   r7,r8           # vertical bar
                   22747: scn44: addl2   r7,r8           # ampersand
                   22748: scn45: addl2   r7,r8           # question mark
                   22749: #
                   22750: #      ALL OPERATORS COME HERE (EQUAL MERGES DIRECTLY)
                   22751: #      (WC) POINTS TO THE BINARY/UNARY PAIR OF OPERATOR DVBLKS.
                   22752: #
                   22753: scn46: tstl    r7              # operator terminates name/constant
                   22754:        bnequ   0f
                   22755:        jmp     scn10
                   22756: 0:             
                   22757:        movl    r8,r9           # else copy dv pointer
                   22758:        movzbl  (r10),r8        # load next character
                   22759:        movl    $t$bop,r10      # set binary op in case
                   22760:        cmpl    r6,scnil        # should be binary if image end
                   22761:        beqlu   scn47
                   22762:        cmpl    r8,$ch$bl       # should be binary if followed by blk
                   22763:        beqlu   scn47
                   22764:        cmpl    r8,$ch$ht       # jump if horizontal tab
                   22765:        beqlu   scn47
                   22766:        cmpl    r8,$ch$sm       # semicolon can immediately follow =
                   22767:        beqlu   scn47
                   22768: #
                   22769: #      HERE FOR UNARY OPERATOR
                   22770: #
                   22771:        addl2   $4*dvbs$,r9     # point to dv for unary op
                   22772:        movl    $t$uop,r10      # set type for unary operator
                   22773:        cmpl    scntp,$t$uok    # ok unary if ok preceding element
                   22774:        bgtru   0f
                   22775:        jmp     scn13
                   22776: 0:             
                   22777:        #page   
                   22778: #
                   22779: #      SCANE (CONTINUED)
                   22780: #
                   22781: #      MERGE HERE TO REQUIRE PRECEDING BLANKS
                   22782: #
                   22783: scn47: tstl    scnbl           # all ok if preceding blanks, exit
                   22784:        beqlu   0f
                   22785:        jmp     scn13
                   22786: 0:             
                   22787: #
                   22788: #      FAIL OPERATOR IN THIS POSITION
                   22789: #
                   22790: scn48: jmp     er_233          # syntax error. invalid use of operator
                   22791: #
                   22792: #      HERE FOR ASTERISK, COULD BE ** SUBSTITUTE FOR EXCLAMATION
                   22793: #
                   22794: scn49: tstl    r7              # end of name if scanning name
                   22795:        bnequ   0f
                   22796:        jmp     scn10
                   22797: 0:             
                   22798:        cmpl    r6,scnil        # not ** if * at image end
                   22799:        beqlu   scn39
                   22800:        movl    r6,r9           # else save offset past first *
                   22801:        movl    r6,scnof        # save another copy
                   22802:        movzbl  (r10)+,r6       # load next character
                   22803:        cmpl    r6,$ch$as       # not ** if next char not *
                   22804:        bnequ   scn50
                   22805:        incl    r9              # else step offset past second *
                   22806:        cmpl    r9,scnil        # ok exclam if end of image
                   22807:        beqlu   scn51
                   22808:        movzbl  (r10),r6        # else load next character
                   22809:        cmpl    r6,$ch$bl       # exclamation if blank
                   22810:        beqlu   scn51
                   22811:        cmpl    r6,$ch$ht       # exclamation if horizontal tab
                   22812:        beqlu   scn51
                   22813: #
                   22814: #      UNARY *
                   22815: #
                   22816: scn50: movl    scnof,r6        # recover stored offset
                   22817:        movl    r$cim,r10       # point to line again
                   22818:        movab   cfp$f(r10)[r6],r10 # point to current char
                   22819:        jmp     scn39           # merge with unary *
                   22820: #
                   22821: #      HERE FOR ** AS SUBSTITUTE FOR EXCLAMATION
                   22822: #
                   22823: scn51: movl    r9,scnpt        # save scan pointer past 2nd *
                   22824:        movl    r9,r6           # copy scan pointer
                   22825:        jmp     scn37           # merge with exclamation
                   22826:        #enp                    # end procedure scane
                   22827:        #page   
                   22828: #
                   22829: #      SCNGF -- SCAN GOTO FIELD
                   22830: #
                   22831: #      SCNGF IS CALLED FROM CMPIL TO SCAN AND ANALYZE A GOTO
                   22832: #      FIELD INCLUDING THE SURROUNDING BRACKETS OR PARENTHESES.
                   22833: #      FOR A NORMAL GOTO, THE RESULT RETURNED IS EITHER A VRBLK
                   22834: #      POINTER FOR A SIMPLE LABEL OPERAND, OR A POINTER TO AN
                   22835: #      EXPRESSION TREE WITH A SPECIAL OUTER UNARY OPERATOR
                   22836: #      (O$GOC). FOR A DIRECT GOTO, THE RESULT RETURNED IS A
                   22837: #      POINTER TO AN EXPRESSION TREE WITH THE SPECIAL OUTER
                   22838: #      UNARY OPERATOR O$GOD.
                   22839: #
                   22840: #      JSR  SCNGF            CALL TO SCAN GOTO FIELD
                   22841: #      (XR)                  RESULT (SEE ABOVE)
                   22842: #      (XL,WA,WB,WC)         DESTROYED
                   22843: #
                   22844: scngf: #prc                    # entry point
                   22845:        jsb     scane           # scan initial element
                   22846:        cmpl    r10,$t$lpr      # skip if left paren (normal goto)
                   22847:        beqlu   scng1
                   22848:        cmpl    r10,$t$lbr      # skip if left bracket (direct goto)
                   22849:        beqlu   scng2
                   22850:        jmp     er_234          # syntax error. goto field incorrect
                   22851: #
                   22852: #      HERE FOR LEFT PAREN (NORMAL GOTO)
                   22853: #
                   22854: scng1: movl    $num01,r7       # set expan flag for normal goto
                   22855:        jsb     expan           # analyze goto field
                   22856:        movl    $opdvn,r6       # point to opdv for complex goto
                   22857:        cmpl    r9,statb        # jump if not in static (sgd15)
                   22858:        blequ   scng3
                   22859:        cmpl    r9,state        # jump to exit if simple label name
                   22860:        blequ   scng4
                   22861:        jmp     scng3           # complex goto - merge
                   22862: #
                   22863: #      HERE FOR LEFT BRACKET (DIRECT GOTO)
                   22864: #
                   22865: scng2: movl    $num02,r7       # set expan flag for direct goto
                   22866:        jsb     expan           # scan goto field
                   22867:        movl    $opdvd,r6       # set opdv pointer for direct goto
                   22868:        #page   
                   22869: #
                   22870: #      SCNGF (CONTINUED)
                   22871: #
                   22872: #      MERGE HERE TO BUILD OUTER UNARY OPERATOR BLOCK
                   22873: #
                   22874: scng3: movl    r6,-(sp)        # stack operator dv pointer
                   22875:        movl    r9,-(sp)        # stack pointer to expression tree
                   22876:        jsb     expop           # pop operator off
                   22877:        movl    (sp)+,r9        # reload new expression tree pointer
                   22878: #
                   22879: #      COMMON EXIT POINT
                   22880: #
                   22881: scng4: rsb                     # return to caller
                   22882:        #enp                    # end procedure scngf
                   22883:        #page   
                   22884: #
                   22885: #      SETVR -- SET VRGET,VRSTO FIELDS OF VRBLK
                   22886: #
                   22887: #      SETVR SETS THE PROPER VALUES IN THE VRGET AND VRSTO
                   22888: #      FIELDS OF A VRBLK. IT IS CALLED WHENEVER TRBLKS ARE
                   22889: #      ADDED OR SUBTRACTED (TRACE,STOPTR,INPUT,OUTPUT,DETACH)
                   22890: #
                   22891: #      (XR)                  POINTER TO VRBLK
                   22892: #      JSR  SETVR            CALL TO SET FIELDS
                   22893: #      (XL,WA)               DESTROYED
                   22894: #
                   22895: #      NOTE THAT SETVR IGNORES THE CALL IF XR DOES NOT POINT
                   22896: #      INTO THE STATIC REGION (I.E. IS SOME OTHER NAME BASE)
                   22897: #
                   22898: setvr: #prc                    # entry point
                   22899:        cmpl    r9,state        # exit if not natural variable
                   22900:        bgequ   setv1
                   22901: #
                   22902: #      HERE IF WE HAVE A VRBLK
                   22903: #
                   22904:        movl    r9,r10          # copy vrblk pointer
                   22905:        movl    $b$vrl,4*vrget(r9) # store normal get value
                   22906:        cmpl    4*vrsto(r9),$b$vre # skip if protected variable
                   22907:        beqlu   setv1
                   22908:        movl    $b$vrs,4*vrsto(r9) # store normal store value
                   22909:        movl    4*vrval(r10),r10# point to next entry on chain
                   22910:        cmpl    (r10),$b$trt    # jump if end of trblk chain
                   22911:        bnequ   setv1
                   22912:        movl    $b$vra,4*vrget(r9) # store trapped routine address
                   22913:        movl    $b$vrv,4*vrsto(r9) # set trapped routine address
                   22914: #
                   22915: #      MERGE HERE TO EXIT TO CALLER
                   22916: #
                   22917: setv1: rsb                     # return to setvr caller
                   22918:        #enp                    # end procedure setvr
                   22919:        #page   
                   22920: #
                   22921: #      SORTA -- SORT ARRAY
                   22922: #
                   22923: #      ROUTINE TO SORT AN ARRAY OR TABLE ON SAME BASIS AS IN
                   22924: #      SITBOL. A TABLE IS CONVERTED TO AN ARRAY, LEAVING TWO
                   22925: #      DIMENSIONAL ARRAYS AND VECTORS AS CASES TO BE CONSIDERED.
                   22926: #      WHOLE ROWS OF ARRAYS ARE PERMUTED ACCORDING TO THE
                   22927: #      ORDERING OF THE KEYS THEY CONTAIN, AND THE STRIDE
                   22928: #      REFERRED TO, IS THE THE LENGTH OF A ROW. IT IS ONE
                   22929: #      FOR A VECTOR.
                   22930: #      THE SORT USED IS HEAPSORT, FUNDAMENTALS OF DATA STRUCTURE
                   22931: #      HOROWITZ AND SAHNI, PITMAN 1977, PAGE 347.
                   22932: #      IT IS AN ORDER N*LOG(N) ALGORITHM. IN ORDER
                   22933: #      TO MAKE IT STABLE, COMPARANDS MAY NOT COMPARE EQUAL. THIS
                   22934: #      IS ACHIEVED BY SORTING A COPY ARRAY (REFERRED TO AS THE
                   22935: #      SORT ARRAY) CONTAINING AT ITS HIGH ADDRESS END, BYTE
                   22936: #      OFFSETS TO THE ROWS TO BE SORTED HELD IN THE ORIGINAL
                   22937: #      ARRAY (REFERRED TO AS THE KEY ARRAY). SORTC, THE
                   22938: #      COMPARISON ROUTINE, ACCESSES THE KEYS THROUGH THESE
                   22939: #      OFFSETS AND IN THE CASE OF EQUALITY, RESOLVES IT BY
                   22940: #      COMPARING THE OFFSETS THEMSELVES. THE SORT PERMUTES THE
                   22941: #      OFFSETS WHICH ARE THEN USED IN A FINAL OPERATION TO COPY
                   22942: #      THE ACTUAL ITEMS INTO THE NEW ARRAY IN SORTED ORDER.
                   22943: #      REFERENCES TO ZEROTH ITEM ARE TO NOTIONAL ITEM
                   22944: #      PRECEDING FIRST ACTUAL ITEM.
                   22945: #      REVERSE SORTING FOR RSORT IS DONE BY HAVING THE LESS THAN
                   22946: #      TEST FOR KEYS EFFECTIVELY BE REPLACED BY A
                   22947: #      GREATER THAN TEST.
                   22948: #
                   22949: #      1(XS)                 FIRST ARG - ARRAY OR TABLE
                   22950: #      0(XS)                 2ND ARG - INDEX OR PDTYPE NAME
                   22951: #      (WA)                  0 , NON-ZERO FOR SORT , RSORT
                   22952: #      JSR  SORTA            CALL TO SORT ARRAY
                   22953: #      (XR)                  SORTED ARRAY
                   22954: #      (XL,WA,WB,WC)         DESTROYED
                   22955:        #page   
                   22956: #
                   22957: #      SORTA (CONTINUED)
                   22958: #
                   22959:        .data   1
                   22960: sorta_s:       .long   0
                   22961:        .text   0
                   22962: sorta: movl    (sp)+,sorta_s   # entry point
                   22963:        movl    r6,srtsr        # sort/rsort indicator
                   22964:        movl    $4*num01,srtst  # default stride of 1
                   22965:        clrl    srtof           # default zero offset to sort key
                   22966:        movl    $nulls,srtdf    # clear datatype field name
                   22967:        movl    (sp)+,r$sxr     # unstack argument 2
                   22968:        movl    (sp)+,r9        # get first argument
                   22969:        jsb     gtarr           # convert to array
                   22970:        .long   srt16           # fail
                   22971:        movl    r9,-(sp)        # stack ptr to resulting key array
                   22972:        movl    r9,-(sp)        # another copy for copyb
                   22973:        jsb     copyb           # get copy array for sorting into
                   22974:        .long   invalid$        # cant fail
                   22975:        movl    r9,-(sp)        # stack pointer to sort array
                   22976:        movl    r$sxr,r9        # get second arg
                   22977:        movl    4*1(sp),r10     # get ptr to key array
                   22978:        cmpl    (r10),$b$vct    # jump if arblk
                   22979:        bnequ   srt02
                   22980:        cmpl    r9,$nulls       # jump if null second arg
                   22981:        beqlu   srt01
                   22982:        jsb     gtnvr           # get vrblk ptr for it
                   22983:        .long   er_257          # erroneous 2nd arg in sort/rsort of vector
                   22984:        movl    r9,srtdf        # store datatype field name vrblk
                   22985: #
                   22986: #      COMPUTE N AND OFFSET TO ITEM A(0) IN VECTOR CASE
                   22987: #
                   22988: srt01: movl    $4*vclen,r8     # offset to a(0)
                   22989:        movl    $4*vcvls,r7     # offset to first item
                   22990:        movl    4*vclen(r10),r6 # get block length
                   22991:        subl2   $4*vcsi$,r6     # get no. of entries, n (in bytes)
                   22992:        jmp     srt04           # merge
                   22993: #
                   22994: #      HERE FOR ARRAY
                   22995: #
                   22996: srt02: movl    4*ardim(r10),r5 # get possible dimension
                   22997:        movl    r5,r6           # convert to short integer
                   22998:        moval   0[r6],r6        # further convert to baus
                   22999:        movl    $4*arvls,r7     # offset to first value if one
                   23000:        movl    $4*arpro,r8     # offset before values if one dim.
                   23001:        cmpl    4*arndm(r10),$num01 # jump in fact if one dim.
                   23002:        bnequ   0f
                   23003:        jmp     srt04
                   23004: 0:             
                   23005:        cmpl    4*arndm(r10),$num02 # fail unless two dimens
                   23006:        beqlu   0f
                   23007:        jmp     srt16
                   23008: 0:             
                   23009:        movl    4*arlb2(r10),r5 # get lower bound 2 as default
                   23010:        cmpl    r9,$nulls       # jump if default second arg
                   23011:        beqlu   srt03
                   23012:        jsb     gtint           # convert to integer
                   23013:        .long   srt17           # fail
                   23014:        movl    4*icval(r9),r5  # get actual integer value
                   23015:        #page   
                   23016: #
                   23017: #      SORTA (CONTINUED)
                   23018: #
                   23019: #      HERE WITH SORT COLUMN INDEX IN IA IN ARRAY CASE
                   23020: #
                   23021: srt03: subl2   4*arlb2(r10),r5 # subtract low bound
                   23022:        bvc     0f
                   23023:        jmp     srt17
                   23024: 0:             
                   23025:        tstl    r5              # fail if below low bound
                   23026:        bgeq    0f
                   23027:        jmp     srt17
                   23028: 0:             
                   23029:        subl2   4*ardm2(r10),r5 # check against dimension
                   23030:        blss    0f              # fail if too large
                   23031:        jmp     srt17
                   23032: 0:             
                   23033:        addl2   4*ardm2(r10),r5 # restore value
                   23034:        movl    r5,r6           # get as small integer
                   23035:        moval   0[r6],r6        # offset within row to key
                   23036:        movl    r6,srtof        # keep offset
                   23037:        movl    4*ardm2(r10),r5 # second dimension is row length
                   23038:        movl    r5,r6           # convert to short integer
                   23039:        movl    r6,r9           # copy row length
                   23040:        moval   0[r6],r6        # convert to bytes
                   23041:        movl    r6,srtst        # store as stride
                   23042:        movl    4*ardim(r10),r5 # get number of rows
                   23043:        movl    r5,r6           # as a short integer
                   23044:        moval   0[r6],r6        # convert n to baus
                   23045:        movl    4*arlen(r10),r8 # offset past array end
                   23046:        subl2   r6,r8           # adjust, giving space for n offsets
                   23047:        subl2   $4,r8           # point to a(0)
                   23048:        movl    4*arofs(r10),r7 # offset to word before first item
                   23049:        addl2   $4,r7           # offset to first item
                   23050: #
                   23051: #      SEPARATE PRE-PROCESSING FOR ARRAYS AND VECTORS DONE.
                   23052: #      TO SIMPLIFY LATER KEY COMPARISONS, REMOVAL OF ANY TRBLK
                   23053: #      TRAP BLOCKS FROM ENTRIES IN KEY ARRAY IS EFFECTED.
                   23054: #
                   23055: #      (XL) = 1(XS) = POINTER TO KEY ARRAY
                   23056: #      (XS) = POINTER TO SORT ARRAY
                   23057: #      WA = NUMBER OF ITEMS, N (CONVERTED TO BYTES).
                   23058: #      WB = OFFSET TO FIRST ITEM OF ARRAYS.
                   23059: #      WC = OFFSET TO A(0)
                   23060: #
                   23061: srt04: cmpl    r6,$4*num01     # return if only a single item
                   23062:        bgtru   0f
                   23063:        jmp     srt15
                   23064: 0:             
                   23065:        movl    r6,srtsn        # store number of items (in baus)
                   23066:        movl    r8,srtso        # store offset to a(0)
                   23067:        movl    4*arlen(r10),r8 # length of array or vec (=vclen)
                   23068:        addl2   r10,r8          # point past end of array or vector
                   23069:        movl    r7,srtsf        # store offset to first row
                   23070:        addl2   r7,r10          # point to first item in key array
                   23071: #
                   23072: #      LOOP THROUGH ARRAY
                   23073: #
                   23074: srt05: movl    (r10),r9        # get an entry
                   23075: #
                   23076: #      HUNT ALONG TRBLK CHAIN
                   23077: #
                   23078: srt06: cmpl    (r9),$b$trt     # jump out if not trblk
                   23079:        bnequ   srt07
                   23080:        movl    4*trval(r9),r9  # get value field
                   23081:        jmp     srt06           # loop
                   23082:        #page   
                   23083: #
                   23084: #      SORTA (CONTINUED)
                   23085: #
                   23086: #      XR IS VALUE FROM END OF CHAIN
                   23087: #
                   23088: srt07: movl    r9,(r10)+       # store as array entry
                   23089:        cmpl    r10,r8          # loop if not done
                   23090:        blssu   srt05
                   23091:        movl    (sp),r10        # get adrs of sort array
                   23092:        movl    srtsf,r9        # initial offset to first key
                   23093:        movl    srtst,r7        # get stride
                   23094:        addl2   srtso,r10       # offset to a(0)
                   23095:        addl2   $4,r10          # point to a(1)
                   23096:        movl    srtsn,r8        # get n
                   23097:        ashl    $-2,r8,r8       # convert from bytes
                   23098:        movl    r8,srtnr        # store as row count
                   23099:                                # loop counter
                   23100: #
                   23101: #      STORE KEY OFFSETS AT TOP OF SORT ARRAY
                   23102: #
                   23103: srt08: movl    r9,(r10)+       # store an offset
                   23104:        addl2   r7,r9           # bump offset by stride
                   23105:        sobgtr  r8,srt08        # loop through rows
                   23106: #
                   23107: #      PERFORM THE SORT ON OFFSETS IN SORT ARRAY.
                   23108: #
                   23109: #      (SRTSN)               NUMBER OF ITEMS TO SORT, N (BYTES)
                   23110: #      (SRTSO)               OFFSET TO A(0)
                   23111: #
                   23112: srt09: movl    srtsn,r6        # get n
                   23113:        movl    srtnr,r8        # get number of rows
                   23114:        ashl    $-1,r8,r8       # i = n / 2 (wc=i, index into array)
                   23115:        moval   0[r8],r8        # convert back to bytes
                   23116: #
                   23117: #      LOOP TO FORM INITIAL HEAP
                   23118: #
                   23119: srt10: jsb     sorth           # sorth(i,n)
                   23120:        subl2   $4,r8           # i = i - 1
                   23121:        bnequ   srt10           # loop if i gt 0
                   23122:        movl    r6,r8           # i = n
                   23123: #
                   23124: #      SORTING LOOP. AT THIS POINT, A(1) IS THE LARGEST
                   23125: #      ITEM, SINCE ALGORITHM INITIALISES IT AS, AND THEN MAINTAI
                   23126: #      IT AS, ROOT OF TREE.
                   23127: #
                   23128: srt11: subl2   $4,r8           # i = i - 1 (n - 1 initially)
                   23129:        beqlu   srt12           # jump if done
                   23130:        movl    (sp),r9         # get sort array address
                   23131:        addl2   srtso,r9        # point to a(0)
                   23132:        movl    r9,r10          # a(0) address
                   23133:        addl2   r8,r10          # a(i) address
                   23134:        movl    4*1(r10),r7     # copy a(i+1)
                   23135:        movl    4*1(r9),4*1(r10)# move a(1) to a(i+1)
                   23136:        movl    r7,4*1(r9)      # complete exchange of a(1), a(i+1)
                   23137:        movl    r8,r6           # n = i for sorth
                   23138:        movl    $4*num01,r8     # i = 1 for sorth
                   23139:        jsb     sorth           # sorth(1,n)
                   23140:        movl    r6,r8           # restore wc
                   23141:        jmp     srt11           # loop
                   23142:        #page   
                   23143: #
                   23144: #      SORTA (CONTINUED)
                   23145: #
                   23146: #      OFFSETS HAVE BEEN PERMUTED INTO REQUIRED ORDER BY SORT.
                   23147: #      COPY ARRAY ELEMENTS OVER THEM.
                   23148: #
                   23149: srt12: movl    (sp),r10        # base adrs of key array
                   23150:        movl    r10,r8          # copy it
                   23151:        addl2   srtso,r8        # offset of a(0)
                   23152:        addl2   srtsf,r10       # adrs of first row of sort array
                   23153:        movl    srtst,r7        # get stride
                   23154:        ashl    $-2,r7,r7       # convert to words
                   23155: #
                   23156: #      COPYING LOOP FOR SUCCESSIVE ITEMS. SORTED OFFSETS ARE
                   23157: #      HELD AT END OF SORT ARRAY.
                   23158: #
                   23159: srt13: addl2   $4,r8           # adrs of next of sorted offsets
                   23160:        movl    r8,r9           # copy it for access
                   23161:        movl    (r9),r9         # get offset
                   23162:        addl2   4*1(sp),r9      # add key array base adrs
                   23163:        movl    r7,r6           # get count of words in row
                   23164: #
                   23165: #      COPY A COMPLETE ROW
                   23166: #
                   23167: srt14: movl    (r9)+,(r10)+    # move a word
                   23168:        sobgtr  r6,srt14        # loop
                   23169:        decl    srtnr           # decrement row count
                   23170:        bnequ   srt13           # repeat till all rows done
                   23171: #
                   23172: #      RETURN POINT
                   23173: #
                   23174: srt15: movl    (sp)+,r9        # pop result array ptr
                   23175:        addl2   $4,sp           # pop key array ptr
                   23176:        clrl    r$sxl           # clear junk
                   23177:        clrl    r$sxr           # clear junk
                   23178:        jmp     *sorta_s        # return
                   23179: #
                   23180: #      ERROR POINT
                   23181: #
                   23182: srt16: jmp     er_256          # sort/rsort 1st arg not suitable array or table
                   23183: srt17: jmp     er_258          # sort/rsort 2nd arg out of range or non-integer
                   23184:        #enp                    # end procudure sorta
                   23185:        #page   
                   23186: #
                   23187: #      SORTC --  COMPARE SORT KEYS
                   23188: #
                   23189: #      COMPARE TWO SORT KEYS GIVEN THEIR OFFSETS. IF
                   23190: #      EQUAL, COMPARE KEY OFFSETS TO GIVE STABLE SORT.
                   23191: #      NOTE THAT IF SRTSR IS NON-ZERO (REQUEST FOR REVERSE
                   23192: #      SORT), THE QUOTED RETURNS ARE INVERTED.
                   23193: #      FOR OBJECTS OF DIFFERING DATATYPES, THE ENTRY POINT
                   23194: #      IDENTIFICATIONS ARE COMPARED.
                   23195: #
                   23196: #      (XL)                  BASE ADRS FOR KEYS
                   23197: #      (WA)                  OFFSET TO KEY 1 ITEM
                   23198: #      (WB)                  OFFSET TO KEY 2 ITEM
                   23199: #      (SRTSR)               ZERO/NON-ZERO FOR SORT/RSORT
                   23200: #      (SRTOF)               OFFSET WITHIN ROW TO COMPARANDS
                   23201: #      JSR  SORTC            CALL TO COMPARE KEYS
                   23202: #      PPM  LOC              KEY1 LESS THAN KEY2
                   23203: #                            NORMAL RETURN, KEY1 GT THAN KEY2
                   23204: #      (XL,XR,WA,WB)         DESTROYED
                   23205: #
                   23206: sortc: #prc                    # entry point
                   23207:        movl    r6,srts1        # save offset 1
                   23208:        movl    r7,srts2        # save offset 2
                   23209:        movl    r8,srtsc        # save wc
                   23210:        addl2   srtof,r10       # add offset to comparand field
                   23211:        movl    r10,r9          # copy base + offset
                   23212:        addl2   r6,r10          # add key1 offset
                   23213:        addl2   r7,r9           # add key2 offset
                   23214:        movl    (r10),r10       # get key1
                   23215:        movl    (r9),r9         # get key2
                   23216:        cmpl    srtdf,$nulls    # jump if datatype field name used
                   23217:        beqlu   0f
                   23218:        jmp     src11
                   23219: 0:             
                   23220:        #page   
                   23221: #
                   23222: #      SORTC (CONTINUED)
                   23223: #
                   23224: #      MERGE AFTER DEALING WITH FIELD NAME. TRY FOR STRINGS.
                   23225: #
                   23226: src01: movl    (r10),r8        # get type code
                   23227:        cmpl    r8,(r9)         # skip if not same datatype
                   23228:        bnequ   src02
                   23229:        cmpl    r8,$b$scl       # jump if both strings
                   23230:        beqlu   src09
                   23231: #
                   23232: #      NOW TRY FOR NUMERIC
                   23233: #
                   23234: src02: movl    r10,r$sxl       # keep arg1
                   23235:        movl    r9,r$sxr        # keep arg2
                   23236:        movl    r10,-(sp)       # stack
                   23237:        movl    r9,-(sp)        # args
                   23238:        jsb     acomp           # compare objects
                   23239:        .long   src10           # not numeric
                   23240:        .long   src10           # not numeric
                   23241:        .long   src03           # key1 less
                   23242:        .long   src08           # keys equal
                   23243:        .long   src05           # key1 greater
                   23244: #
                   23245: #      RETURN IF KEY1 SMALLER (SORT), GREATER (RSORT)
                   23246: #
                   23247: src03: tstl    srtsr           # jump if rsort
                   23248:        bnequ   src06
                   23249: #
                   23250: src04: movl    srtsc,r8        # restore wc
                   23251:        movl    (sp)+,r11       # return
                   23252:        jmp     *(r11)+
                   23253: #
                   23254: #      RETURN IF KEY1 GREATER (SORT), SMALLER (RSORT)
                   23255: #
                   23256: src05: tstl    srtsr           # jump if rsort
                   23257:        bnequ   src04
                   23258: #
                   23259: src06: movl    srtsc,r8        # restore wc
                   23260:        addl2   $4*1,(sp)       # return
                   23261:        rsb     
                   23262: #
                   23263: #      KEYS ARE OF SAME DATATYPE
                   23264: #
                   23265: src07: cmpl    r10,r9          # item first created is less
                   23266:        blssu   src03
                   23267:        cmpl    r10,r9          # addresses rise in order of creation
                   23268:        bgtru   src05
                   23269: #
                   23270: #      DROP THROUGH OR MERGE FOR IDENTICAL OR EQUAL OBJECTS
                   23271: #
                   23272: src08: cmpl    srts1,srts2     # test offsets or key addrss instead
                   23273:        blssu   src04
                   23274:        jmp     src06           # offset 1 greater
                   23275:        #page   
                   23276: #
                   23277: #      SORTC (CONTINUED)
                   23278: #
                   23279: #      STRINGS
                   23280: #
                   23281: src09: movl    r10,-(sp)       # stack
                   23282:        movl    r9,-(sp)        # args
                   23283:        jsb     lcomp           # compare objects
                   23284:        .long   invalid$        # cant
                   23285:        .long   invalid$        # fail
                   23286:        .long   src03           # key1 less
                   23287:        .long   src08           # keys equal
                   23288:        .long   src05           # key1 greater
                   23289: #
                   23290: #      ARITHMETIC COMPARISON FAILED - RECOVER ARGS
                   23291: #
                   23292: src10: movl    r$sxl,r10       # get arg1
                   23293:        movl    r$sxr,r9        # get arg2
                   23294:        movl    (r10),r8        # get type of key1
                   23295:        cmpl    r8,(r9)         # jump if keys of same type
                   23296:        beqlu   src07
                   23297:        movl    r8,r10          # get block type word
                   23298:        movl    (r9),r9         # get block type word
                   23299:        movzwl  -2(r10),r10     # entry point id for key1
                   23300:        movzwl  -2(r9),r9       # entry point id for key2
                   23301:        cmpl    r10,r9          # jump if key1 gt key2
                   23302:        bgtru   src05
                   23303:        jmp     src03           # key1 lt key2
                   23304: #
                   23305: #      DATATYPE FIELD NAME USED
                   23306: #
                   23307: src11: jsb     sortf           # call routine to find field 1
                   23308:        movl    r10,-(sp)       # stack item pointer
                   23309:        movl    r9,r10          # get key2
                   23310:        jsb     sortf           # find field 2
                   23311:        movl    r10,r9          # place as key2
                   23312:        movl    (sp)+,r10       # recover key1
                   23313:        jmp     src01           # merge
                   23314:        #enp                    # procedure sortc
                   23315:        #page   
                   23316: #
                   23317: #      SORTF -- FIND FIELD FOR SORTC
                   23318: #
                   23319: #      ROUTINE USED BY SORTC TO OBTAIN ITEM CORRESPONDING
                   23320: #      TO A GIVEN FIELD NAME, IF THIS EXISTS, IN A PROGRAMMER
                   23321: #      DEFINED OBJECT PASSED AS ARGUMENT.
                   23322: #      IF SUCH A MATCH OCCURS, RECORD IS KEPT OF DATATYPE
                   23323: #      NAME, FIELD NAME AND OFFSET TO FIELD IN ORDER TO
                   23324: #      SHORT-CIRCUIT LATER SEARCHES ON SAME TYPE. NOTE THAT
                   23325: #      DFBLKS ARE STORED IN STATIC AND HENCE CANNOT BE MOVED.
                   23326: #
                   23327: #      (SRTDF)               VRBLK POINTER OF FIELD NAME
                   23328: #      (XL)                  POSSIBLE PDBLK POINTER
                   23329: #      JSR  SORTF            CALL TO SEARCH FOR FIELD NAME
                   23330: #      (XL)                  ITEM FOUND OR ORIGINAL PDBLK PTR
                   23331: #      (WC)                  DESTROYED
                   23332: #
                   23333: sortf: #prc                    # entry point
                   23334:        cmpl    (r10),$b$pdt    # return if not pdblk
                   23335:        bnequ   srtf3
                   23336:        movl    r9,-(sp)        # keep xr
                   23337:        movl    srtfd,r9        # get possible former dfblk ptr
                   23338:        beqlu   srtf4           # jump if not
                   23339:        cmpl    r9,4*pddfp(r10) # jump if not right datatype
                   23340:        bnequ   srtf4
                   23341:        cmpl    srtdf,srtff     # jump if not right field name
                   23342:        bnequ   srtf4
                   23343:        addl2   srtfo,r10       # add offset to required field
                   23344: #
                   23345: #      HERE WITH XL POINTING TO FOUND FIELD
                   23346: #
                   23347: srtf1: movl    (r10),r10       # get item from field
                   23348: #
                   23349: #      RETURN POINT
                   23350: #
                   23351: srtf2: movl    (sp)+,r9        # restore xr
                   23352: #
                   23353: srtf3: rsb                     # return
                   23354:        #page   
                   23355: #
                   23356: #      SORTF (CONTINUED)
                   23357: #
                   23358: #      CONDUCT A SEARCH
                   23359: #
                   23360: srtf4: movl    r10,r9          # copy original pointer
                   23361:        movl    4*pddfp(r9),r9  # point to dfblk
                   23362:        movl    r9,srtfd        # keep a copy
                   23363:        movl    4*fargs(r9),r8  # get number of fields
                   23364:        moval   0[r8],r8        # convert to bytes
                   23365:        addl2   4*dflen(r9),r9  # point past last field
                   23366: #
                   23367: #      LOOP TO FIND NAME IN PDFBLK
                   23368: #
                   23369: srtf5: subl2   $4,r8           # count down
                   23370:        subl2   $4,r9           # point in front
                   23371:        cmpl    (r9),srtdf      # skip out if found
                   23372:        beqlu   srtf6
                   23373:        tstl    r8              # loop
                   23374:        bnequ   srtf5
                   23375:        jmp     srtf2           # return - not found
                   23376: #
                   23377: #      FOUND
                   23378: #
                   23379: srtf6: movl    (r9),srtff      # keep field name ptr
                   23380:        addl2   $4*pdfld,r8     # add offset to first field
                   23381:        movl    r8,srtfo        # store as field offset
                   23382:        addl2   r8,r10          # point to field
                   23383:        jmp     srtf1           # return
                   23384:        #enp                    # procedure sortf
                   23385:        #page   
                   23386: #
                   23387: #      SORTH -- HEAP ROUTINE FOR SORTA
                   23388: #
                   23389: #      THIS ROUTINE CONSTRUCTS A HEAP FROM ELEMENTS OF ARRAY, A.
                   23390: #      IN THIS APPLICATION, THE ELEMENTS ARE OFFSETS TO KEYS IN
                   23391: #      A KEY ARRAY.
                   23392: #
                   23393: #      (XS)                  POINTER TO SORT ARRAY BASE
                   23394: #      1(XS)                 POINTER TO KEY ARRAY BASE
                   23395: #      (WA)                  MAX ARRAY INDEX, N (IN BYTES)
                   23396: #      (WC)                  OFFSET J IN A TO ROOT (IN *1 TO *N)
                   23397: #      JSR  SORTH            CALL SORTH(J,N) TO MAKE HEAP
                   23398: #      (XL,XR,WB)            DESTROYED
                   23399: #
                   23400:        .data   1
                   23401: sorth_s:       .long   0
                   23402:        .text   0
                   23403: sorth: movl    (sp)+,sorth_s   # entry point
                   23404:        movl    r6,srtsn        # save n
                   23405:        movl    r8,srtwc        # keep wc
                   23406:        movl    (sp),r10        # sort array base adrs
                   23407:        addl2   srtso,r10       # add offset to a(0)
                   23408:        addl2   r8,r10          # point to a(j)
                   23409:        movl    (r10),srtrt     # get offset to root
                   23410:        addl2   r8,r8           # double j - cant exceed n
                   23411: #
                   23412: #      LOOP TO MOVE DOWN TREE USING DOUBLED INDEX J
                   23413: #
                   23414: srh01: cmpl    r8,srtsn        # done if j gt n
                   23415:        bgtru   srh03
                   23416:        cmpl    r8,srtsn        # skip if j equals n
                   23417:        beqlu   srh02
                   23418:        movl    (sp),r9         # sort array base adrs
                   23419:        movl    4*1(sp),r10     # key array base adrs
                   23420:        addl2   srtso,r9        # point to a(0)
                   23421:        addl2   r8,r9           # adrs of a(j)
                   23422:        movl    4*1(r9),r6      # get a(j+1)
                   23423:        movl    (r9),r7         # get a(j)
                   23424: #
                   23425: #      COMPARE SONS. (WA) RIGHT SON, (WB) LEFT SON
                   23426: #
                   23427:        jsb     sortc           # compare keys - lt(a(j+1),a(j))
                   23428:        .long   srh02           # a(j+1) lt a(j)
                   23429:        addl2   $4,r8           # point to greater son, a(j+1)
                   23430:        #page   
                   23431: #
                   23432: #      SORTH (CONTINUED)
                   23433: #
                   23434: #      COMPARE ROOT WITH GREATER SON
                   23435: #
                   23436: srh02: movl    4*1(sp),r10     # key array base adrs
                   23437:        movl    (sp),r9         # get sort array address
                   23438:        addl2   srtso,r9        # adrs of a(0)
                   23439:        movl    r9,r7           # copy this adrs
                   23440:        addl2   r8,r9           # adrs of greater son, a(j)
                   23441:        movl    (r9),r6         # get a(j)
                   23442:        movl    r7,r9           # point back to a(0)
                   23443:        movl    srtrt,r7        # get root
                   23444:        jsb     sortc           # compare them - lt(a(j),root)
                   23445:        .long   srh03           # father exceeds sons - done
                   23446:        movl    (sp),r9         # get sort array adrs
                   23447:        addl2   srtso,r9        # point to a(0)
                   23448:        movl    r9,r10          # copy it
                   23449:        movl    r8,r6           # copy j
                   23450:        ashl    $-2,r8,r8       # convert to words
                   23451:        ashl    $-1,r8,r8       # get j/2
                   23452:        moval   0[r8],r8        # convert back to bytes
                   23453:        addl2   r6,r10          # point to a(j)
                   23454:        addl2   r8,r9           # adrs of a(j/2)
                   23455:        movl    (r10),(r9)      # a(j/2) = a(j)
                   23456:        movl    r6,r8           # recover j
                   23457:        addl2   r8,r8           # j = j*2. done if too big
                   23458:        bvc     0f
                   23459:        jmp     srh03
                   23460: 0:             
                   23461:        jmp     srh01           # loop
                   23462: #
                   23463: #      FINISH BY COPYING ROOT OFFSET BACK INTO ARRAY
                   23464: #
                   23465: srh03: ashl    $-2,r8,r8       # convert to words
                   23466:        ashl    $-1,r8,r8       # j = j/2
                   23467:        moval   0[r8],r8        # convert back to bytes
                   23468:        movl    (sp),r9         # sort array adrs
                   23469:        addl2   srtso,r9        # adrs of a(0)
                   23470:        addl2   r8,r9           # adrs of a(j/2)
                   23471:        movl    srtrt,(r9)      # a(j/2) = root
                   23472:        movl    srtsn,r6        # restore wa
                   23473:        movl    srtwc,r8        # restore wc
                   23474:        jmp     *sorth_s        # return
                   23475:        #enp                    # end procedure sorth
                   23476:        #page   
                   23477:        #page   
                   23478: #
                   23479: #      TFIND -- LOCATE TABLE ELEMENT
                   23480: #
                   23481: #      (XR)                  SUBSCRIPT VALUE FOR ELEMENT
                   23482: #      (XL)                  POINTER TO TABLE
                   23483: #      (WB)                  ZERO BY VALUE, NON-ZERO BY NAME
                   23484: #      JSR  TFIND            CALL TO LOCATE ELEMENT
                   23485: #      PPM  LOC              TRANSFER LOCATION IF ACCESS FAILS
                   23486: #      (XR)                  ELEMENT VALUE (IF BY VALUE)
                   23487: #      (XR)                  DESTROYED (IF BY NAME)
                   23488: #      (XL,WA)               TEBLK NAME (IF BY NAME)
                   23489: #      (XL,WA)               DESTROYED (IF BY VALUE)
                   23490: #      (WC,RA)               DESTROYED
                   23491: #
                   23492: #      NOTE THAT IF A CALL BY VALUE SPECIFIES A NON-EXISTENT
                   23493: #      SUBSCRIPT, NULL IS RETURNED WITHOUT BUILDING A NEW TEBLK.
                   23494: #
                   23495: tfind: #prc                    # entry point
                   23496:        movl    r7,-(sp)        # save name/value indicator
                   23497:        movl    r9,-(sp)        # save subscript value
                   23498:        movl    r10,-(sp)       # save table pointer
                   23499:        movl    4*tblen(r10),r6 # load length of tbblk
                   23500:        ashl    $-2,r6,r6       # convert to word count
                   23501:        subl2   $tbbuk,r6       # get number of buckets
                   23502:        movl    r6,r5           # convert to integer value
                   23503:        movl    r5,tfnsi        # save for later
                   23504:        movl    (r9),r10        # load first word of subscript
                   23505:        movzwl  -2(r10),r10     # load block entry id (bl$xx)
                   23506:        casel   r10,$0,$bl$$d   # switch on block type
                   23507: 5:             
                   23508:        .word   tfn00-5b
                   23509:        .word   tfn00-5b
                   23510:        .word   tfn00-5b
                   23511:        .word   tfn00-5b
                   23512:        .word   tfn02-5b        # jump if integer
                   23513:        .word   tfn04-5b        # jump if name
                   23514:        .word   tfn03-5b        # jump if pattern
                   23515:        .word   tfn03-5b        # jump if pattern
                   23516:        .word   tfn03-5b        # jump if pattern
                   23517:        .word   tfn02-5b        # real
                   23518:        .word   tfn05-5b        # jump if string
                   23519:        .word   tfn00-5b
                   23520:        .word   tfn00-5b
                   23521:        .word   tfn00-5b
                   23522:        .word   tfn00-5b
                   23523:        .word   tfn00-5b
                   23524:        .word   tfn00-5b
                   23525:        #esw                    # end switch on block type
                   23526: #
                   23527: #      HERE FOR BLOCKS FOR WHICH WE USE THE SECOND WORD OF THE
                   23528: #      BLOCK AS THE HASH SOURCE (SEE BLOCK FORMATS FOR DETAILS).
                   23529: #
                   23530: tfn00: movl    4*1(r9),r6      # load second word
                   23531: #
                   23532: #      MERGE HERE WITH ONE WORD HASH SOURCE IN WA
                   23533: #
                   23534: tfn01: movl    r6,r5           # convert to integer
                   23535:        jmp     tfn06           # jump to merge
                   23536:        #page   
                   23537: #
                   23538: #      TFIND (CONTINUED)
                   23539: #
                   23540: #      HERE FOR INTEGER OR REAL
                   23541: #
                   23542: tfn02: movl    4*1(r9),r5      # load value as hash source
                   23543:        bgeq    tfn06           # ok if positive or zero
                   23544:        mnegl   r5,r5           # make positive
                   23545:        bvs     tfn06
                   23546:        jmp     tfn06           # merge
                   23547: #
                   23548: #      FOR PATTERN, USE FIRST WORD (PCODE) AS SOURCE
                   23549: #
                   23550: tfn03: movl    (r9),r6         # load first word as hash source
                   23551:        jmp     tfn01           # merge back
                   23552: #
                   23553: #      FOR NAME, USE OFFSET AS HASH SOURCE
                   23554: #
                   23555: tfn04: movl    4*nmofs(r9),r6  # load offset as hash source
                   23556:        jmp     tfn01           # merge back
                   23557: #
                   23558: #      HERE FOR STRING
                   23559: #
                   23560: tfn05: jsb     hashs           # call routine to compute hash
                   23561: #
                   23562: #      MERGE HERE WITH HASH SOURCE IN (IA)
                   23563: #
                   23564: tfn06: ashq    $-32,r4,r4      # compute hash index by remaindering
                   23565:        ediv    tfnsi,r4,r11,r5
                   23566:        movl    r5,r8           # get as one word integer
                   23567:        moval   0[r8],r8        # convert to byte offset
                   23568:        movl    (sp),r10        # get table ptr again
                   23569:        addl2   r8,r10          # point to proper bucket
                   23570:        movl    4*tbbuk(r10),r9 # load first teblk pointer
                   23571:        cmpl    r9,(sp)         # jump if no teblks on chain
                   23572:        beqlu   tfn10
                   23573: #
                   23574: #      LOOP THROUGH TEBLKS ON HASH CHAIN
                   23575: #
                   23576: tfn07: movl    r9,r7           # save teblk pointer
                   23577:        movl    4*tesub(r9),r9  # load subscript value
                   23578:        movl    4*1(sp),r10     # load input argument subscript val
                   23579:        jsb     ident           # compare them
                   23580:        .long   tfn08           # jump if equal (ident)
                   23581: #
                   23582: #      HERE IF NO MATCH WITH THAT TEBLK
                   23583: #
                   23584:        movl    r7,r10          # restore teblk pointer
                   23585:        movl    4*tenxt(r10),r9 # point to next teblk on chain
                   23586:        cmpl    r9,(sp)         # jump if there is one
                   23587:        bnequ   tfn07
                   23588: #
                   23589: #      HERE IF NO MATCH WITH ANY TEBLK ON CHAIN
                   23590: #
                   23591:        movl    $4*tenxt,r8     # set offset to link field (xl base)
                   23592:        jmp     tfn11           # jump to merge
                   23593:        #page   
                   23594: #
                   23595: #      TFIND (CONTINUED)
                   23596: #
                   23597: #      HERE WE HAVE FOUND A MATCHING ELEMENT
                   23598: #
                   23599: tfn08: movl    r7,r10          # restore teblk pointer
                   23600:        movl    $4*teval,r6     # set teblk name offset
                   23601:        movl    4*2(sp),r7      # restore name/value indicator
                   23602:        bnequ   tfn09           # jump if called by name
                   23603:        jsb     acess           # else get value
                   23604:        .long   tfn12           # jump if reference fails
                   23605:        clrl    r7              # restore name/value indicator
                   23606: #
                   23607: #      COMMON EXIT FOR ENTRY FOUND
                   23608: #
                   23609: tfn09: addl2   $4*num03,sp     # pop stack entries
                   23610:        addl2   $4*1,(sp)       # return to tfind caller
                   23611:        rsb     
                   23612: #
                   23613: #      HERE IF NO TEBLKS ON THE HASH CHAIN
                   23614: #
                   23615: tfn10: addl2   $4*tbbuk,r8     # get offset to bucket ptr
                   23616:        movl    (sp),r10        # set tbblk ptr as base
                   23617: #
                   23618: #      MERGE HERE WITH (XL,WC) BASE,OFFSET OF FINAL LINK
                   23619: #
                   23620: tfn11: movl    (sp),r9         # tbblk pointer
                   23621:        movl    4*tbinv(r9),r9  # load default value in case
                   23622:        movl    4*2(sp),r7      # load name/value indicator
                   23623:        beqlu   tfn09           # exit with default if value call
                   23624: #
                   23625: #      HERE WE MUST BUILD A NEW TEBLK
                   23626: #
                   23627:        movl    $4*tesi$,r6     # set size of teblk
                   23628:        jsb     alloc           # allocate teblk
                   23629:        addl2   r8,r10          # point to hash link
                   23630:        movl    r9,(r10)        # link new teblk at end of chain
                   23631:        movl    $b$tet,(r9)     # store type word
                   23632:        movl    $nulls,4*teval(r9) # set null as initial value
                   23633:        movl    (sp)+,4*tenxt(r9)# set tbblk ptr to mark end of chain
                   23634:        movl    (sp)+,4*tesub(r9)# store subscript value
                   23635:        addl2   $4,sp           # pop past name/value indicator
                   23636:        movl    r9,r10          # copy teblk pointer (name base)
                   23637:        movl    $4*teval,r6     # set offset
                   23638:        addl2   $4*1,(sp)       # return to caller with new teblk
                   23639:        rsb     
                   23640: #
                   23641: #      ACESS FAIL RETURN
                   23642: #
                   23643: tfn12: movl    (sp)+,r11       # alternative return
                   23644:        jmp     *(r11)+
                   23645:        #enp                    # end procedure tfind
                   23646:        #page   
                   23647: #
                   23648: #      TRACE -- SET/RESET A TRACE ASSOCIATION
                   23649: #
                   23650: #      THIS PROCEDURE IS SHARED BY TRACE AND STOPTR TO
                   23651: #      EITHER INITIATE OR STOP A TRACE RESPECTIVELY.
                   23652: #
                   23653: #      (XL)                  TRBLK PTR (TRACE) OR ZERO (STOPTR)
                   23654: #      1(XS)                 FIRST ARGUMENT (NAME)
                   23655: #      0(XS)                 SECOND ARGUMENT (TRACE TYPE)
                   23656: #      JSR  TRACE            CALL TO SET/RESET TRACE
                   23657: #      PPM  LOC              TRANSFER LOC IF 1ST ARG IS BAD NAME
                   23658: #      PPM  LOC              TRANSFER LOC IF 2ND ARG IS BAD TYPE
                   23659: #      (XS)                  POPPED
                   23660: #      (XL,XR,WA,WB,WC,IA)   DESTROYED
                   23661: #
                   23662:        .data   1
                   23663: trace_s:       .long   0
                   23664:        .text   0
                   23665: trace: movl    (sp)+,trace_s   # entry point
                   23666:        jsb     gtstg           # get trace type string
                   23667:        .long   trc15           # jump if not string
                   23668:        movab   cfp$f(r9),r9    # else point to string
                   23669:        movzbl  (r9),r6         # load first character
                   23670:        bicl2   $ch$bl,r6       # fold to upper case
                   23671:        movl    (sp),r9         # load name argument
                   23672:        movl    r10,(sp)        # stack trblk ptr or zero
                   23673:        movl    $trtac,r8       # set trtyp for access trace
                   23674:        cmpl    r6,$ch$la       # jump if a (access)
                   23675:        bnequ   0f
                   23676:        jmp     trc10
                   23677: 0:             
                   23678:        movl    $trtvl,r8       # set trtyp for value trace
                   23679:        cmpl    r6,$ch$lv       # jump if v (value)
                   23680:        bnequ   0f
                   23681:        jmp     trc10
                   23682: 0:             
                   23683:        tstl    r6              # jump if blank (value)
                   23684:        bnequ   0f
                   23685:        jmp     trc10
                   23686: 0:             
                   23687: #
                   23688: #      HERE FOR L,K,F,C,R
                   23689: #
                   23690:        cmpl    r6,$ch$lf       # jump if f (function)
                   23691:        beqlu   trc01
                   23692:        cmpl    r6,$ch$lr       # jump if r (return)
                   23693:        beqlu   trc01
                   23694:        cmpl    r6,$ch$ll       # jump if l (label)
                   23695:        beqlu   trc03
                   23696:        cmpl    r6,$ch$lk       # jump if k (keyword)
                   23697:        bnequ   0f
                   23698:        jmp     trc06
                   23699: 0:             
                   23700:        cmpl    r6,$ch$lc       # else error if not c (call)
                   23701:        beqlu   0f
                   23702:        jmp     trc15
                   23703: 0:             
                   23704: #
                   23705: #      HERE FOR F,C,R
                   23706: #
                   23707: trc01: jsb     gtnvr           # point to vrblk for name
                   23708:        .long   trc16           # jump if bad name
                   23709:        addl2   $4,sp           # pop stack
                   23710:        movl    4*vrfnc(r9),r9  # point to function block
                   23711:        cmpl    (r9),$b$pfc     # error if not program function
                   23712:        beqlu   0f
                   23713:        jmp     trc17
                   23714: 0:             
                   23715:        cmpl    r6,$ch$lr       # jump if r (return)
                   23716:        beqlu   trc02
                   23717:        #page   
                   23718: #
                   23719: #      TRACE (CONTINUED)
                   23720: #
                   23721: #      HERE FOR F,C TO SET/RESET CALL TRACE
                   23722: #
                   23723:        movl    r10,4*pfctr(r9) # set/reset call trace
                   23724:        cmpl    r6,$ch$lc       # exit with null if c (call)
                   23725:        bnequ   0f
                   23726:        jmp     exnul
                   23727: 0:             
                   23728: #
                   23729: #      HERE FOR F,R TO SET/RESET RETURN TRACE
                   23730: #
                   23731: trc02: movl    r10,4*pfrtr(r9) # set/reset return trace
                   23732:        addl3   $4*2,trace_s,r11        # return
                   23733:        jmp     (r11)
                   23734: #
                   23735: #      HERE FOR L TO SET/RESET LABEL TRACE
                   23736: #
                   23737: trc03: jsb     gtnvr           # point to vrblk
                   23738:        .long   trc16           # jump if bad name
                   23739:        movl    4*vrlbl(r9),r10 # load label pointer
                   23740:        cmpl    (r10),$b$trt    # jump if no old trace
                   23741:        bnequ   trc04
                   23742:        movl    4*trlbl(r10),r10# else delete old trace association
                   23743: #
                   23744: #      HERE WITH OLD LABEL TRACE ASSOCIATION DELETED
                   23745: #
                   23746: trc04: cmpl    r10,$stndl      # error if undefined label
                   23747:        bnequ   0f
                   23748:        jmp     trc16
                   23749: 0:             
                   23750:        movl    (sp)+,r7        # get trblk ptr again
                   23751:        beqlu   trc05           # jump if stoptr case
                   23752:        movl    r7,4*vrlbl(r9)  # else set new trblk pointer
                   23753:        movl    $b$vrt,4*vrtra(r9) # set label trace routine address
                   23754:        movl    r7,r9           # copy trblk pointer
                   23755:        movl    r10,4*trlbl(r9) # store real label in trblk
                   23756:        addl3   $4*2,trace_s,r11        # return
                   23757:        jmp     (r11)
                   23758: #
                   23759: #      HERE FOR STOPTR CASE FOR LABEL
                   23760: #
                   23761: trc05: movl    r10,4*vrlbl(r9) # store label ptr back in vrblk
                   23762:        movl    $b$vrg,4*vrtra(r9) # store normal transfer address
                   23763:        addl3   $4*2,trace_s,r11        # return
                   23764:        jmp     (r11)
                   23765:        #page   
                   23766: #
                   23767: #      TRACE (CONTINUED)
                   23768: #
                   23769: #      HERE FOR K (KEYWORD)
                   23770: #
                   23771: trc06: jsb     gtnvr           # point to vrblk
                   23772:        .long   trc16           # error if not natural var
                   23773:        tstl    4*vrlen(r9)     # error if not system var
                   23774:        beqlu   0f
                   23775:        jmp     trc16
                   23776: 0:             
                   23777:        addl2   $4,sp           # pop stack
                   23778:        tstl    r10             # jump if stoptr case
                   23779:        beqlu   trc07
                   23780:        movl    r9,4*trkvr(r10) # store vrblk ptr in trblk for ktrex
                   23781: #
                   23782: #      MERGE HERE WITH TRBLK SET UP IN WB (OR ZERO)
                   23783: #
                   23784: trc07: movl    4*vrsvp(r9),r9  # point to svblk
                   23785:        cmpl    r9,$v$ert       # jump if errtype
                   23786:        beqlu   trc08
                   23787:        cmpl    r9,$v$stc       # jump if stcount
                   23788:        beqlu   trc09
                   23789:        cmpl    r9,$v$fnc       # else error if not fnclevel
                   23790:        beqlu   0f
                   23791:        jmp     trc17
                   23792: 0:             
                   23793: #
                   23794: #      FNCLEVEL
                   23795: #
                   23796:        movl    r10,r$fnc       # set/reset fnclevel trace
                   23797:        addl3   $4*2,trace_s,r11        # return
                   23798:        jmp     (r11)
                   23799: #
                   23800: #      ERRTYPE
                   23801: #
                   23802: trc08: movl    r10,r$ert       # set/reset errtype trace
                   23803:        addl3   $4*2,trace_s,r11        # return
                   23804:        jmp     (r11)
                   23805: #
                   23806: #      STCOUNT
                   23807: #
                   23808: trc09: movl    r10,r$stc       # set/reset stcount trace
                   23809:        addl3   $4*2,trace_s,r11        # return
                   23810:        jmp     (r11)
                   23811:        #page   
                   23812: #
                   23813: #      TRACE (CONTINUED)
                   23814: #
                   23815: #      A,V MERGE HERE WITH TRTYP VALUE IN WC
                   23816: #
                   23817: trc10: jsb     gtvar           # locate variable
                   23818:        .long   trc16           # error if not appropriate name
                   23819:        movl    (sp)+,r7        # get new trblk ptr again
                   23820:        addl2   r10,r6          # point to variable location
                   23821:        movl    r6,r9           # copy variable pointer
                   23822: #
                   23823: #      LOOP TO SEARCH TRBLK CHAIN
                   23824: #
                   23825: trc11: movl    (r9),r10        # point to next entry
                   23826:        cmpl    (r10),$b$trt    # jump if not trblk
                   23827:        bnequ   trc13
                   23828:        cmpl    r8,4*trtyp(r10) # jump if too far out on chain
                   23829:        blssu   trc13
                   23830:        cmpl    r8,4*trtyp(r10) # jump if this matches our type
                   23831:        beqlu   trc12
                   23832:        addl2   $4*trnxt,r10    # else point to link field
                   23833:        movl    r10,r9          # copy pointer
                   23834:        jmp     trc11           # and loop back
                   23835: #
                   23836: #      HERE TO DELETE AN OLD TRBLK OF THE TYPE WE WERE GIVEN
                   23837: #
                   23838: trc12: movl    4*trnxt(r10),r10# get ptr to next block or value
                   23839:        movl    r10,(r9)        # store to delete this trblk
                   23840: #
                   23841: #      HERE AFTER DELETING ANY OLD ASSOCIATION OF THIS TYPE
                   23842: #
                   23843: trc13: tstl    r7              # jump if stoptr case
                   23844:        beqlu   trc14
                   23845:        movl    r7,(r9)         # else link new trblk in
                   23846:        movl    r7,r9           # copy trblk pointer
                   23847:        movl    r10,4*trnxt(r9) # store forward pointer
                   23848:        movl    r8,4*trtyp(r9)  # store appropriate trap type code
                   23849: #
                   23850: #      HERE TO MAKE SURE VRGET,VRSTO ARE SET PROPERLY
                   23851: #
                   23852: trc14: movl    r6,r9           # recall possible vrblk pointer
                   23853:        subl2   $4*vrval,r9     # point back to vrblk
                   23854:        jsb     setvr           # set fields if vrblk
                   23855:        addl3   $4*2,trace_s,r11        # return
                   23856:        jmp     (r11)
                   23857: #
                   23858: #      HERE FOR BAD TRACE TYPE
                   23859: #
                   23860: trc15: addl3   $4*1,trace_s,r11        # take bad trace type error exit
                   23861:        jmp     *(r11)+
                   23862: #
                   23863: #      POP STACK BEFORE FAILING
                   23864: #
                   23865: trc16: addl2   $4,sp           # pop stack
                   23866: #
                   23867: #      HERE FOR BAD NAME ARGUMENT
                   23868: #
                   23869: trc17: movl    trace_s,r11     # take bad name error exit
                   23870:        jmp     *(r11)+
                   23871:        #enp                    # end procedure trace
                   23872:        #page   
                   23873: #
                   23874: #      TRBLD -- BUILD TRBLK
                   23875: #
                   23876: #      TRBLK IS USED BY THE INPUT, OUTPUT AND TRACE FUNCTIONS
                   23877: #      TO CONSTRUCT A TRBLK (TRAP BLOCK)
                   23878: #
                   23879: #      (XR)                  TRTAG OR TRTER
                   23880: #      (XL)                  TRFNC OR TRFPT
                   23881: #      (WB)                  TRTYP
                   23882: #      JSR  TRBLD            CALL TO BUILD TRBLK
                   23883: #      (XR)                  POINTER TO TRBLK
                   23884: #      (WA)                  DESTROYED
                   23885: #
                   23886: trbld: #prc                    # entry point
                   23887:        movl    r9,-(sp)        # stack trtag (or trfnm)
                   23888:        movl    $4*trsi$,r6     # set size of trblk
                   23889:        jsb     alloc           # allocate trblk
                   23890:        movl    $b$trt,(r9)     # store first word
                   23891:        movl    r10,4*trfnc(r9) # store trfnc (or trfpt)
                   23892:        movl    (sp)+,4*trtag(r9)# store trtag (or trfnm)
                   23893:        movl    r7,4*trtyp(r9)  # store type
                   23894:        movl    $nulls,4*trval(r9) # for now, a null value
                   23895:        rsb                     # return to caller
                   23896:        #enp                    # end procedure trbld
                   23897:        #page   
                   23898: #
                   23899: #      TRIMR -- TRIM TRAILING BLANKS
                   23900: #
                   23901: #      TRIMR IS PASSED A POINTER TO AN SCBLK WHICH MUST BE THE
                   23902: #      LAST BLOCK IN DYNAMIC STORAGE. TRAILING BLANKS ARE
                   23903: #      TRIMMED OFF AND THE DYNAMIC STORAGE POINTER RESET TO
                   23904: #      THE END OF THE (POSSIBLY) SHORTENED BLOCK.
                   23905: #
                   23906: #      (WB)                  NON-ZERO TO TRIM TRAILING BLANKS
                   23907: #      (XR)                  POINTER TO STRING TO TRIM
                   23908: #      JSR  TRIMR            CALL TO TRIM STRING
                   23909: #      (XR)                  POINTER TO TRIMMED STRING
                   23910: #      (XL,WA,WB,WC)         DESTROYED
                   23911: #
                   23912: #      THE CALL WITH WB ZERO STILL PERFORMS THE END ZERO PAD
                   23913: #      AND DNAMP READJUSTMENT. IT IS USED FROM ACESS IF KVTRM=0.
                   23914: #
                   23915: trimr: #prc                    # entry point
                   23916:        movl    r9,r10          # copy string pointer
                   23917:        movl    4*sclen(r9),r6  # load string length
                   23918:        beqlu   trim2           # jump if null input
                   23919:        movab   cfp$f(r10)[r6],r10 # else point past last character
                   23920:        tstl    r7              # jump if no trim
                   23921:        beqlu   trim3
                   23922:        movl    $ch$bl,r8       # load blank character
                   23923: #
                   23924: #      LOOP THROUGH CHARACTERS FROM RIGHT TO LEFT
                   23925: #
                   23926: trim0: movzbl  -(r10),r7       # load next character
                   23927:        cmpl    r7,$ch$ht       # jump if horizontal tab
                   23928:        beqlu   trim1
                   23929:        cmpl    r7,r8           # jump if non-blank found
                   23930:        bnequ   trim3
                   23931: trim1: decl    r6              # else decrement character count
                   23932:        bnequ   trim0           # loop back if more to check
                   23933: #
                   23934: #      HERE IF RESULT IS NULL (NULL OR ALL-BLANK INPUT)
                   23935: #
                   23936: trim2: movl    r9,dnamp        # wipe out input string block
                   23937:        movl    $nulls,r9       # load null result
                   23938:        jmp     trim5           # merge to exit
                   23939:        #page   
                   23940: #
                   23941: #      TRIMR (CONTINUED)
                   23942: #
                   23943: #      HERE WITH NON-BLANK FOUND (MERGE FOR NO TRIM)
                   23944: #
                   23945: trim3: movl    r6,4*sclen(r9)  # set new length
                   23946:        movl    r9,r10          # copy string pointer
                   23947:        movab   cfp$f(r10)[r6],r10 # ready for storing blanks
                   23948:        movab   3+(4*schar)(r6),r6 # get length of block in bytes
                   23949:        bicl2   $3,r6
                   23950:        addl2   r9,r6           # point past new block
                   23951:        movl    r6,dnamp        # set new top of storage pointer
                   23952:        movl    $cfp$c,r6       # get count of chars in word
                   23953:        clrl    r8              # set blank char
                   23954: #
                   23955: #      LOOP TO ZERO PAD LAST WORD OF CHARACTERS
                   23956: #
                   23957: trim4: movb    r8,(r10)+       # store zero character
                   23958:        sobgtr  r6,trim4        # loop back till all stored
                   23959:        #csc    r10             # complete store characters
                   23960: #
                   23961: #      COMMON EXIT POINT
                   23962: #
                   23963: trim5: clrl    r10             # clear garbage xl pointer
                   23964:        rsb                     # return to caller
                   23965:        #enp                    # end procedure trimr
                   23966:        #page   
                   23967: #
                   23968: #      TRXEQ -- EXECUTE FUNCTION TYPE TRACE
                   23969: #
                   23970: #      TRXEQ IS USED TO EXECUTE A TRACE WHEN A FOURTH ARGUMENT
                   23971: #      HAS BEEN SUPPLIED. TRACE HAS ALREADY BEEN DECREMENTED.
                   23972: #
                   23973: #      (XR)                  POINTER TO TRBLK
                   23974: #      (XL,WA)               NAME BASE,OFFSET FOR VARIABLE
                   23975: #      JSR  TRXEQ            CALL TO EXECUTE TRACE
                   23976: #      (WB,WC,RA)            DESTROYED
                   23977: #
                   23978: #      THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING
                   23979: #      CONTROL TO THE TRACE FUNCTION USING THE CFUNC ROUTINE.
                   23980: #
                   23981: #                            TRXEQ RETURN POINT WORD(S)
                   23982: #                            SAVED VALUE OF TRACE KEYWORD
                   23983: #                            TRBLK POINTER
                   23984: #                            NAME BASE
                   23985: #                            NAME OFFSET
                   23986: #                            SAVED VALUE OF R$COD
                   23987: #                            SAVED CODE PTR (-R$COD)
                   23988: #                            SAVED VALUE OF FLPTR
                   23989: #      FLPTR --------------- ZERO (DUMMY FAIL OFFSET)
                   23990: #                            NMBLK FOR VARIABLE NAME
                   23991: #      XS ------------------ TRACE TAG
                   23992: #
                   23993: #      R$COD AND THE CODE PTR ARE SET TO DUMMY VALUES WHICH
                   23994: #      CAUSE CONTROL TO RETURN TO THE TRXEQ PROCEDURE ON SUCCESS
                   23995: #      OR FAILURE (TRXEQ IGNORES A FAILURE CONDITION).
                   23996: #
                   23997: trxeq: #prc                    # entry point (recursive)
                   23998:        movl    r$cod,r8        # load code block pointer
                   23999:        movl    r3,r7           # get current code pointer
                   24000:        subl2   r8,r7           # make code pointer into offset
                   24001:        movl    kvtra,-(sp)     # stack trace keyword value
                   24002:        movl    r9,-(sp)        # stack trblk pointer
                   24003:        movl    r10,-(sp)       # stack name base
                   24004:        movl    r6,-(sp)        # stack name offset
                   24005:        movl    r8,-(sp)        # stack code block pointer
                   24006:        movl    r7,-(sp)        # stack code pointer offset
                   24007:        movl    flptr,-(sp)     # stack old failure pointer
                   24008:        clrl    -(sp)           # set dummy fail offset
                   24009:        movl    sp,flptr        # set new failure pointer
                   24010:        clrl    kvtra           # reset trace keyword to zero
                   24011:        movl    $trxdc,r8       # load new (dummy) code blk pointer
                   24012:        movl    r8,r$cod        # set as code block pointer
                   24013:        movl    r8,r3           # and new code pointer
                   24014:        #page   
                   24015: #
                   24016: #      TRXEQ (CONTINUED)
                   24017: #
                   24018: #      NOW PREPARE ARGUMENTS FOR FUNCTION
                   24019: #
                   24020:        movl    r6,r7           # save name offset
                   24021:        movl    $4*nmsi$,r6     # load nmblk size
                   24022:        jsb     alloc           # allocate space for nmblk
                   24023:        movl    $b$nml,(r9)     # set type word
                   24024:        movl    r10,4*nmbas(r9) # store name base
                   24025:        movl    r7,4*nmofs(r9)  # store name offset
                   24026:        movl    4*6(sp),r10     # reload pointer to trblk
                   24027:        movl    r9,-(sp)        # stack nmblk pointer (1st argument)
                   24028:        movl    4*trtag(r10),-(sp) # stack trace tag (2nd argument)
                   24029:        movl    4*trfnc(r10),r10# load trace function pointer
                   24030:        movl    $num02,r6       # set number of arguments to two
                   24031:        jmp     cfunc           # jump to call function
                   24032: #
                   24033: #      SEE O$TXR FOR DETAILS OF RETURN TO THIS POINT
                   24034: #
                   24035: trxq1: movl    flptr,sp        # point back to our stack entries
                   24036:        addl2   $4,sp           # pop off garbage fail offset
                   24037:        movl    (sp)+,flptr     # restore old failure pointer
                   24038:        movl    (sp)+,r7        # reload code offset
                   24039:        movl    (sp)+,r8        # load old code base pointer
                   24040:        movl    r8,r9           # copy cdblk pointer
                   24041:        movl    4*cdstm(r9),kvstn# restore stmnt no
                   24042:        movl    (sp)+,r6        # reload name offset
                   24043:        movl    (sp)+,r10       # reload name base
                   24044:        movl    (sp)+,r9        # reload trblk pointer
                   24045:        movl    (sp)+,kvtra     # restore trace keyword value
                   24046:        addl2   r8,r7           # recompute absolute code pointer
                   24047:        movl    r7,r3           # restore code pointer
                   24048:        movl    r8,r$cod        # and code block pointer
                   24049:        rsb                     # return to trxeq caller
                   24050:        #enp                    # end procedure trxeq
                   24051:        #page   
                   24052: #
                   24053: #      XSCAN -- EXECUTION FUNCTION ARGUMENT SCAN
                   24054: #
                   24055: #      XSCAN SCANS OUT ONE TOKEN IN A PROTOTYPE ARGUMENT IN
                   24056: #      ARRAY,CLEAR,DATA,DEFINE,LOAD FUNCTION CALLS. XSCAN
                   24057: #      CALLS MUST BE PRECEDED BY A CALL TO THE INITIALIZATION
                   24058: #      PROCEDURE XSCNI. THE FOLLOWING VARIABLES ARE USED.
                   24059: #
                   24060: #      R$XSC                 POINTER TO SCBLK FOR FUNCTION ARG
                   24061: #      XSOFS                 OFFSET (NUM CHARS SCANNED SO FAR)
                   24062: #
                   24063: #      (WC)                  DELIMITER ONE (CH$XX)
                   24064: #      (XL)                  DELIMITER TWO (CH$XX)
                   24065: #      JSR  XSCAN            CALL TO SCAN NEXT ITEM
                   24066: #      (XR)                  POINTER TO SCBLK FOR TOKEN SCANNED
                   24067: #      (WA)                  COMPLETION CODE (SEE BELOW)
                   24068: #      (WC,XL)               DESTROYED
                   24069: #
                   24070: #      THE SCAN STARTS FROM THE CURRENT POSITION AND CONTINUES
                   24071: #      UNTIL ONE OF THE FOLLOWING THREE CONDITIONS OCCURS.
                   24072: #
                   24073: #      1)   DELIMITER ONE IS ENCOUNTERED  (WA SET TO 1)
                   24074: #
                   24075: #      2)   DELIMITER TWO ENCOUNTERED  (WA SET TO 2)
                   24076: #
                   24077: #      3)   END OF STRING ENCOUNTERED  (WA SET TO 0)
                   24078: #
                   24079: #      THE RESULT IS A STRING CONTAINING ALL CHARACTERS SCANNED
                   24080: #      UP TO BUT NOT INCLUDING ANY DELIMITER CHARACTER.
                   24081: #      THE POINTER IS LEFT POINTING PAST THE DELIMITER.
                   24082: #
                   24083: #      IF ONLY ONE DELIMITER IS TO BE DETECTED, DELIMITER ONE
                   24084: #      AND DELIMITER TWO SHOULD BE SET TO THE SAME VALUE.
                   24085: #
                   24086: #      IN THE CASE WHERE THE END OF STRING IS ENCOUNTERED, THE
                   24087: #      STRING INCLUDES ALL THE CHARACTERS TO THE END OF THE
                   24088: #      STRING. NO FURTHER CALLS CAN BE MADE TO XSCAN UNTIL
                   24089: #      XSCNI IS CALLED TO INITIALIZE A NEW ARGUMENT SCAN
                   24090:        #page   
                   24091: #
                   24092: #      XSCAN (CONTINUED)
                   24093: #
                   24094: xscan: #prc                    # entry point
                   24095:        movl    r7,xscwb        # preserve wb
                   24096:        movl    r$xsc,r9        # point to argument string
                   24097:        movl    4*sclen(r9),r6  # load string length
                   24098:        movl    xsofs,r7        # load current offset
                   24099:        subl2   r7,r6           # get number of remaining characters
                   24100:        beqlu   xscn2           # jump if no characters left
                   24101:        movab   cfp$f(r9)[r7],r9# point to current character
                   24102: #
                   24103: #      LOOP TO SEARCH FOR DELIMITER
                   24104: #
                   24105: xscn1: movzbl  (r9)+,r7        # load next character
                   24106:        cmpl    r7,r8           # jump if delimiter one found
                   24107:        beqlu   xscn3
                   24108:        cmpl    r7,r10          # jump if delimiter two found
                   24109:        beqlu   xscn4
                   24110:        decl    r6              # decrement count of chars left
                   24111:        bnequ   xscn1           # loop back if more chars to go
                   24112: #
                   24113: #      HERE FOR RUNOUT
                   24114: #
                   24115: xscn2: movl    r$xsc,r10       # point to string block
                   24116:        movl    4*sclen(r10),r6 # get string length
                   24117:        movl    xsofs,r7        # load offset
                   24118:        subl2   r7,r6           # get substring length
                   24119:        clrl    r$xsc           # clear string ptr for collector
                   24120:        clrl    xscrt           # set zero (runout) return code
                   24121:        jmp     xscn6           # jump to exit
                   24122:        #page   
                   24123: #
                   24124: #      XSCAN (CONTINUED)
                   24125: #
                   24126: #      HERE IF DELIMITER ONE FOUND
                   24127: #
                   24128: xscn3: movl    $num01,xscrt    # set return code
                   24129:        jmp     xscn5           # jump to merge
                   24130: #
                   24131: #      HERE IF DELIMITER TWO FOUND
                   24132: #
                   24133: xscn4: movl    $num02,xscrt    # set return code
                   24134: #
                   24135: #      MERGE HERE AFTER DETECTING A DELIMITER
                   24136: #
                   24137: xscn5: movl    r$xsc,r10       # reload pointer to string
                   24138:        movl    4*sclen(r10),r8 # get original length of string
                   24139:        subl2   r6,r8           # minus chars left = chars scanned
                   24140:        movl    r8,r6           # move to reg for sbstr
                   24141:        movl    xsofs,r7        # set offset
                   24142:        subl2   r7,r6           # compute length for sbstr
                   24143:        incl    r8              # adjust new cursor past delimiter
                   24144:        movl    r8,xsofs        # store new offset
                   24145: #
                   24146: #      COMMON EXIT POINT
                   24147: #
                   24148: xscn6: clrl    r9              # clear garbage character ptr in xr
                   24149:        jsb     sbstr           # build sub-string
                   24150:        movl    xscrt,r6        # load return code
                   24151:        movl    xscwb,r7        # restore wb
                   24152:        rsb                     # return to xscan caller
                   24153:        #enp                    # end procedure xscan
                   24154:        #page   
                   24155: #
                   24156: #      XSCNI -- EXECUTION FUNCTION ARGUMENT SCAN
                   24157: #
                   24158: #      XSCNI INITIALIZES THE SCAN USED FOR PROTOTYPE ARGUMENTS
                   24159: #      IN THE CLEAR, DEFINE, LOAD, DATA, ARRAY FUNCTIONS. SEE
                   24160: #      XSCAN FOR THE PROCEDURE WHICH IS USED AFTER THIS CALL.
                   24161: #
                   24162: #      -(XS)                 ARGUMENT TO BE SCANNED (ON STACK)
                   24163: #      JSR  XSCNI            CALL TO SCAN ARGUMENT
                   24164: #      PPM  LOC              TRANSFER LOC IF ARG IS NOT STRING
                   24165: #      PPM  LOC              TRANSFER LOC IF ARGUMENT IS NULL
                   24166: #      (XS)                  POPPED
                   24167: #      (XR,R$XSC)            ARGUMENT (SCBLK PTR)
                   24168: #      (WA)                  ARGUMENT LENGTH
                   24169: #      (IA,RA)               DESTROYED
                   24170: #
                   24171:        .data   1
                   24172: xscni_s:       .long   0
                   24173:        .text   0
                   24174: xscni: movl    (sp)+,xscni_s   # entry point
                   24175:        jsb     gtstg           # fetch argument as string
                   24176:        .long   xsci1           # jump if not convertible
                   24177:        movl    r9,r$xsc        # else store scblk ptr for xscan
                   24178:        clrl    xsofs           # set offset to zero
                   24179:        tstl    r6              # jump if null string
                   24180:        beqlu   xsci2
                   24181:        addl3   $4*2,xscni_s,r11        # return to xscni caller
                   24182:        jmp     (r11)
                   24183: #
                   24184: #      HERE IF ARGUMENT IS NOT A STRING
                   24185: #
                   24186: xsci1: movl    xscni_s,r11     # take not-string error exit
                   24187:        jmp     *(r11)+
                   24188: #
                   24189: #      HERE FOR NULL STRING
                   24190: #
                   24191: xsci2: addl3   $4*1,xscni_s,r11        # take null-string error exit
                   24192:        jmp     *(r11)+
                   24193:        #enp                    # end procedure xscni
                   24194:        #title  s p i t b o l -- utility routines
                   24195: #
                   24196: #      THE FOLLOWING SECTION CONTAINS UTILITY ROUTINES USED FOR
                   24197: #      VARIOUS PURPOSES THROUGHOUT THE SYSTEM. THESE DIFFER
                   24198: #      FROM THE PROCEDURES IN THE UTILITY PROCEDURES SECTION IN
                   24199: #      THEY ARE NOT IN PROCEDURE FORM AND THEY DO NOT RETURN
                   24200: #      TO THEIR CALLERS. THEY ARE ACCESSED WITH A BRANCH TYPE
                   24201: #      INSTRUCTION AFTER SETTING THE REGISTERS TO APPROPRIATE
                   24202: #      PARAMETER VALUES.
                   24203: #
                   24204: #      THE REGISTER VALUES REQUIRED FOR EACH ROUTINE ARE
                   24205: #      DOCUMENTED AT THE START OF EACH ROUTINE. REGISTERS NOT
                   24206: #      MENTIONED MAY CONTAIN ANY VALUES EXCEPT THAT XR,XL
                   24207: #      CAN ONLY CONTAIN PROPER COLLECTABLE POINTERS.
                   24208: #
                   24209: #      SOME OF THESE ROUTINES WILL TOLERATE GARBAGE POINTERS
                   24210: #      IN XL,XR ON ENTRY. THIS IS ALWAYS DOCUMENTED AND IN
                   24211: #      EACH CASE, THE ROUTINE CLEARS THESE GARBAGE VALUES BEFORE
                   24212: #      EXITING AFTER COMPLETING ITS TASK.
                   24213: #
                   24214: #      THE ROUTINES HAVE NAMES CONSISTING OF FIVE LETTERS
                   24215: #      AND ARE ASSEMBLED IN ALPHABETICAL ORDER.
                   24216:        #page   
                   24217: #      ARREF -- ARRAY REFERENCE
                   24218: #
                   24219: #      (XL)                  MAY BE NON-COLLECTABLE
                   24220: #      (XR)                  NUMBER OF SUBSCRIPTS
                   24221: #      (WB)                  SET ZERO/NONZERO FOR VALUE/NAME
                   24222: #                            THE VALUE IN WB MUST BE COLLECTABLE
                   24223: #      STACK                 SUBSCRIPTS AND ARRAY OPERAND
                   24224: #      BRN  ARREF            JUMP TO CALL FUNCTION
                   24225: #
                   24226: #      ARREF CONTINUES BY EXECUTING THE NEXT CODE WORD WITH
                   24227: #      THE RESULT NAME OR VALUE PLACED ON TOP OF THE STACK.
                   24228: #      TO DEAL WITH THE PROBLEM OF ACCESSING SUBSCRIPTS IN THE
                   24229: #      ORDER OF STACKING, XL IS USED AS A SUBSCRIPT POINTER
                   24230: #      WORKING BELOW THE STACK POINTER.
                   24231: #
                   24232: arref: #rtn    
                   24233:        movl    r9,r6           # copy number of subscripts
                   24234:        movl    sp,r10          # point to stack front
                   24235:        moval   0[r9],r9        # convert to byte offset
                   24236:        addl2   r9,r10          # point to array operand on stack
                   24237:        addl2   $4,r10          # final value for stack popping
                   24238:        movl    r10,arfxs       # keep for later
                   24239:        movl    -(r10),r9       # load array operand pointer
                   24240:        movl    r9,r$arf        # keep array pointer
                   24241:        movl    r10,r9          # save pointer to subscripts
                   24242:        movl    r$arf,r10       # point xl to possible vcblk or tbblk
                   24243:        movl    (r10),r8        # load first word
                   24244:        cmpl    r8,$b$art       # jump if arblk
                   24245:        beqlu   arf01
                   24246:        cmpl    r8,$b$vct       # jump if vcblk
                   24247:        bnequ   0f
                   24248:        jmp     arf07
                   24249: 0:             
                   24250:        cmpl    r8,$b$tbt       # jump if tbblk
                   24251:        bnequ   0f
                   24252:        jmp     arf10
                   24253: 0:             
                   24254:        jmp     er_235          # subscripted operand is not table or array
                   24255: #
                   24256: #      HERE FOR ARRAY (ARBLK)
                   24257: #
                   24258: arf01: cmpl    r6,4*arndm(r10) # jump if wrong number of dims
                   24259:        beqlu   0f
                   24260:        jmp     arf09
                   24261: 0:             
                   24262:        movl    intv0,r5        # get initial subscript of zero
                   24263:        movl    r9,r10          # point before subscripts
                   24264:        clrl    r6              # initial offset to bounds
                   24265:        jmp     arf03           # jump into loop
                   24266: #
                   24267: #      LOOP TO COMPUTE SUBSCRIPTS BY MULTIPLICATIONS
                   24268: #
                   24269: arf02: mull2   4*ardm2(r9),r5  # multiply total by next dimension
                   24270: #
                   24271: #      MERGE HERE FIRST TIME
                   24272: #
                   24273: arf03: movl    -(r10),r9       # load next subscript
                   24274:        movl    r5,arfsi        # save current subscript
                   24275:        movl    4*icval(r9),r5  # load integer value in case
                   24276:        cmpl    (r9),$b$icl     # jump if it was an integer
                   24277:        beqlu   arf04
                   24278:        #page   
                   24279: #
                   24280: #      ARREF (CONTINUED)
                   24281: #
                   24282: #
                   24283:        jsb     gtint           # convert to integer
                   24284:        .long   arf12           # jump if not integer
                   24285:        movl    4*icval(r9),r5  # if ok, load integer value
                   24286: #
                   24287: #      HERE WITH INTEGER SUBSCRIPT IN (IA)
                   24288: #
                   24289: arf04: movl    r$arf,r9        # point to array
                   24290:        addl2   r6,r9           # offset to next bounds
                   24291:        subl2   4*arlbd(r9),r5  # subtract low bound to compare
                   24292:        bvc     0f
                   24293:        jmp     arf13
                   24294: 0:             
                   24295:        tstl    r5              # out of range fail if too small
                   24296:        bgeq    0f
                   24297:        jmp     arf13
                   24298: 0:             
                   24299:        subl2   4*ardim(r9),r5  # subtract dimension
                   24300:        blss    0f              # out of range fail if too large
                   24301:        jmp     arf13
                   24302: 0:             
                   24303:        addl2   4*ardim(r9),r5  # else restore subscript offset
                   24304:        addl2   arfsi,r5        # add to current total
                   24305:        addl2   $4*ardms,r6     # point to next bounds
                   24306:        cmpl    r10,sp          # loop back if more to go
                   24307:        bnequ   arf02
                   24308: #
                   24309: #      HERE WITH INTEGER SUBSCRIPT COMPUTED
                   24310: #
                   24311:        movl    r5,r6           # get as one word integer
                   24312:        moval   0[r6],r6        # convert to offset
                   24313:        movl    r$arf,r10       # point to arblk
                   24314:        addl2   4*arofs(r10),r6 # add offset past bounds
                   24315:        addl2   $4,r6           # adjust for arpro field
                   24316:        tstl    r7              # exit with name if name call
                   24317:        bnequ   arf08
                   24318: #
                   24319: #      MERGE HERE TO GET VALUE FOR VALUE CALL
                   24320: #
                   24321: arf05: jsb     acess           # get value
                   24322:        .long   arf13           # fail if acess fails
                   24323: #
                   24324: #      RETURN VALUE
                   24325: #
                   24326: arf06: movl    arfxs,sp        # pop stack entries
                   24327:        clrl    r$arf           # finished with array pointer
                   24328:        jmp     exixr           # exit with value in xr
                   24329:        #page   
                   24330: #
                   24331: #      ARREF (CONTINUED)
                   24332: #
                   24333: #      HERE FOR VECTOR
                   24334: #
                   24335: arf07: cmpl    r6,$num01       # error if more than 1 subscript
                   24336:        beqlu   0f
                   24337:        jmp     arf09
                   24338: 0:             
                   24339:        movl    (sp),r9         # else load subscript
                   24340:        jsb     gtint           # convert to integer
                   24341:        .long   arf12           # error if not integer
                   24342:        movl    4*icval(r9),r5  # else load integer value
                   24343:        subl2   intv1,r5        # subtract for ones offset
                   24344:        movl    r5,r6           # get subscript as one word
                   24345:        bgeq    0f
                   24346:        jmp     arf13
                   24347: 0:             
                   24348:        addl2   $vcvls,r6       # add offset for standard fields
                   24349:        moval   0[r6],r6        # convert offset to bytes
                   24350:        cmpl    r6,4*vclen(r10) # fail if out of range subscript
                   24351:        blssu   0f
                   24352:        jmp     arf13
                   24353: 0:             
                   24354:        tstl    r7              # back to get value if value call
                   24355:        beqlu   arf05
                   24356: #
                   24357: #      RETURN NAME
                   24358: #
                   24359: arf08: movl    arfxs,sp        # pop stack entries
                   24360:        clrl    r$arf           # finished with array pointer
                   24361:        jmp     exnam           # else exit with name
                   24362: #
                   24363: #      HERE IF SUBSCRIPT COUNT IS WRONG
                   24364: #
                   24365: arf09: jmp     er_236          # array referenced with wrong number of subscripts
                   24366: #
                   24367: #      TABLE
                   24368: #
                   24369: arf10: cmpl    r6,$num01       # error if more than 1 subscript
                   24370:        bnequ   arf11
                   24371:        movl    (sp),r9         # else load subscript
                   24372:        jsb     tfind           # call table search routine
                   24373:        .long   arf13           # fail if failed
                   24374:        tstl    r7              # exit with name if name call
                   24375:        bnequ   arf08
                   24376:        jmp     arf06           # else exit with value
                   24377: #
                   24378: #      HERE FOR BAD TABLE REFERENCE
                   24379: #
                   24380: arf11: jmp     er_237          # table referenced with more than one subscript
                   24381: #
                   24382: #      HERE FOR BAD SUBSCRIPT
                   24383: #
                   24384: arf12: jmp     er_238          # array subscript is not integer
                   24385: #
                   24386: #      HERE TO SIGNAL FAILURE
                   24387: #
                   24388: arf13: clrl    r$arf           # finished with array pointer
                   24389:        jmp     exfal           # fail
                   24390:        #page   
                   24391: #
                   24392: #      CFUNC -- CALL A FUNCTION
                   24393: #
                   24394: #      CFUNC IS USED TO CALL A SNOBOL LEVEL FUNCTION. IT IS
                   24395: #      USED BY THE APPLY FUNCTION (S$APP), THE FUNCTION
                   24396: #      TRACE ROUTINE (TRXEQ) AND THE MAIN FUNCTION CALL ENTRY
                   24397: #      (O$FNC, O$FNS). IN THE LATTER CASES, CFUNC IS USED ONLY
                   24398: #      IF THE NUMBER OF ARGUMENTS IS INCORRECT.
                   24399: #
                   24400: #      (XL)                  POINTER TO FUNCTION BLOCK
                   24401: #      (WA)                  ACTUAL NUMBER OF ARGUMENTS
                   24402: #      (XS)                  POINTS TO STACKED ARGUMENTS
                   24403: #      BRN  CFUNC            JUMP TO CALL FUNCTION
                   24404: #
                   24405: #      CFUNC CONTINUES BY EXECUTING THE FUNCTION
                   24406: #
                   24407: cfunc: #rtn    
                   24408:        cmpl    r6,4*fargs(r10) # jump if too few arguments
                   24409:        blssu   cfnc1
                   24410:        cmpl    r6,4*fargs(r10) # jump if correct number of args
                   24411:        beqlu   cfnc3
                   24412: #
                   24413: #      HERE IF TOO MANY ARGUMENTS SUPPLIED, POP THEM OFF
                   24414: #
                   24415:        movl    r6,r7           # copy actual number
                   24416:        subl2   4*fargs(r10),r7 # get number of extra args
                   24417:        moval   0[r7],r7        # convert to bytes
                   24418:        addl2   r7,sp           # pop off unwanted arguments
                   24419:        jmp     cfnc3           # jump to go off to function
                   24420: #
                   24421: #      HERE IF TOO FEW ARGUMENTS
                   24422: #
                   24423: cfnc1: movl    4*fargs(r10),r7 # load required number of arguments
                   24424:        cmpl    r7,$nini9       # jump if case of var num of args
                   24425:        beqlu   cfnc3
                   24426:        subl2   r6,r7           # calculate number missing
                   24427:                                # set counter to control loop
                   24428: #
                   24429: #      LOOP TO SUPPLY EXTRA NULL ARGUMENTS
                   24430: #
                   24431: cfnc2: movl    $nulls,-(sp)    # stack a null argument
                   24432:        sobgtr  r7,cfnc2        # loop till proper number stacked
                   24433: #
                   24434: #      MERGE HERE TO JUMP TO FUNCTION
                   24435: #
                   24436: cfnc3: movl    (r10),r11       # jump through fcode field
                   24437:        jmp     (r11)
                   24438:        #page   
                   24439: #
                   24440: #      EXFAL -- EXIT SIGNALLING SNOBOL FAILURE
                   24441: #
                   24442: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24443: #      BRN  EXFAL            JUMP TO FAIL
                   24444: #
                   24445: #      EXFAL CONTINUES BY EXECUTING THE APPROPRIATE FAIL GOTO
                   24446: #
                   24447: exfal: #rtn    
                   24448:        movl    flptr,sp        # pop stack
                   24449:        movl    (sp),r9         # load failure offset
                   24450:        addl2   r$cod,r9        # point to failure code location
                   24451:        movl    r9,r3           # set code pointer
                   24452:        jmp     exits           # do next code word
                   24453:        #page   
                   24454: #
                   24455: #      EXINT -- EXIT WITH INTEGER RESULT
                   24456: #
                   24457: #      (XL,XR)               MAY BE NONCOLLECTABLE
                   24458: #      (IA)                  INTEGER VALUE
                   24459: #      BRN  EXINT            JUMP TO EXIT WITH INTEGER
                   24460: #
                   24461: #      EXINT CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24462: #      WHICH IT DOES BY FALLING THROUGH TO EXIXR
                   24463: #
                   24464: exint: #rtn    
                   24465:        jsb     icbld           # build icblk
                   24466:        #page   
                   24467: #      EXIXR -- EXIT WITH RESULT IN (XR)
                   24468: #
                   24469: #      (XR)                  RESULT
                   24470: #      (XL)                  MAY BE NON-COLLECTABLE
                   24471: #      BRN  EXIXR            JUMP TO EXIT WITH RESULT IN (XR)
                   24472: #
                   24473: #      EXIXR CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24474: #      WHICH IT DOES BY FALLING THROUGH TO EXITS.
                   24475: exixr: #rtn    
                   24476: #
                   24477:        movl    r9,-(sp)        # stack result
                   24478: #
                   24479: #
                   24480: #      EXITS -- EXIT WITH RESULT IF ANY STACKED
                   24481: #
                   24482: #      (XR,XL)               MAY BE NON-COLLECTABLE
                   24483: #
                   24484: #      BRN  EXITS            ENTER EXITS ROUTINE
                   24485: #
                   24486: exits: #rtn    
                   24487:        movl    (r3)+,r9        # load next code word
                   24488:        movl    (r9),r10        # load entry address
                   24489:        movl    r10,r11         # jump to execute next code word
                   24490:        jmp     (r11)
                   24491:        #page   
                   24492: #
                   24493: #      EXNAM -- EXIT WITH NAME IN (XL,WA)
                   24494: #
                   24495: #      (XL)                  NAME BASE
                   24496: #      (WA)                  NAME OFFSET
                   24497: #      (XR)                  MAY BE NON-COLLECTABLE
                   24498: #      BRN  EXNAM            JUMP TO EXIT WITH NAME IN (XL,WA)
                   24499: #
                   24500: #      EXNAM CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24501: #
                   24502: exnam: #rtn    
                   24503:        movl    r10,-(sp)       # stack name base
                   24504:        movl    r6,-(sp)        # stack name offset
                   24505:        jmp     exits           # do next code word
                   24506:        #page   
                   24507: #
                   24508: #      EXNUL -- EXIT WITH NULL RESULT
                   24509: #
                   24510: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24511: #      BRN  EXNUL            JUMP TO EXIT WITH NULL VALUE
                   24512: #
                   24513: #      EXNUL CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24514: #
                   24515: exnul: #rtn    
                   24516:        movl    $nulls,-(sp)    # stack null value
                   24517:        jmp     exits           # do next code word
                   24518:        #page   
                   24519: #
                   24520: #      EXREA -- EXIT WITH REAL RESULT
                   24521: #
                   24522: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24523: #      (RA)                  REAL VALUE
                   24524: #      BRN  EXREA            JUMP TO EXIT WITH REAL VALUE
                   24525: #
                   24526: #      EXREA CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24527: #
                   24528: exrea: #rtn    
                   24529:        jsb     rcbld           # build rcblk
                   24530:        jmp     exixr           # jump to exit with result in xr
                   24531:        #page   
                   24532: #
                   24533: #      EXSID -- EXIT SETTING ID FIELD
                   24534: #
                   24535: #      EXSID IS USED TO EXIT AFTER BUILDING ANY OF THE FOLLOWING
                   24536: #      BLOCKS (ARBLK, TBBLK, PDBLK, VCBLK). IT SETS THE IDVAL.
                   24537: #
                   24538: #      (XR)                  PTR TO BLOCK WITH IDVAL FIELD
                   24539: #      (XL)                  MAY BE NON-COLLECTABLE
                   24540: #      BRN  EXSID            JUMP TO EXIT AFTER SETTING ID FIELD
                   24541: #
                   24542: #      EXSID CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24543: #
                   24544: exsid: #rtn    
                   24545:        movl    curid,r6        # load current id value
                   24546:        cmpl    r6,$cfp$m       # jump if no overflow
                   24547:        bnequ   exsi1
                   24548:        clrl    r6              # else reset for wraparound
                   24549: #
                   24550: #      HERE WITH OLD IDVAL IN WA
                   24551: #
                   24552: exsi1: incl    r6              # bump id value
                   24553:        movl    r6,curid        # store for next time
                   24554:        movl    r6,4*idval(r9)  # store id value
                   24555:        jmp     exixr           # exit with result in (xr)
                   24556:        #page   
                   24557: #
                   24558: #      EXVNM -- EXIT WITH NAME OF VARIABLE
                   24559: #
                   24560: #      EXVNM EXITS AFTER STACKING A VALUE WHICH IS A NMBLK
                   24561: #      REFERENCING THE NAME OF A GIVEN NATURAL VARIABLE.
                   24562: #
                   24563: #      (XR)                  VRBLK POINTER
                   24564: #      (XL)                  MAY BE NON-COLLECTABLE
                   24565: #      BRN  EXVNM            EXIT WITH VRBLK POINTER IN XR
                   24566: #
                   24567: exvnm: #rtn    
                   24568:        movl    r9,r10          # copy name base pointer
                   24569:        movl    $4*nmsi$,r6     # set size of nmblk
                   24570:        jsb     alloc           # allocate nmblk
                   24571:        movl    $b$nml,(r9)     # store type word
                   24572:        movl    r10,4*nmbas(r9) # store name base
                   24573:        movl    $4*vrval,4*nmofs(r9) # store name offset
                   24574:        jmp     exixr           # exit with result in xr
                   24575:        #page   
                   24576: #
                   24577: #      FLPOP -- FAIL AND POP IN PATTERN MATCHING
                   24578: #
                   24579: #      FLPOP POPS THE NODE AND CURSOR ON THE STACK AND THEN
                   24580: #      DROPS THROUGH INTO FAILP TO CAUSE PATTERN FAILURE
                   24581: #
                   24582: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24583: #      BRN  FLPOP            JUMP TO FAIL AND POP STACK
                   24584: #
                   24585: flpop: #rtn    
                   24586:        addl2   $4*num02,sp     # pop two entries off stack
                   24587:        #page   
                   24588: #
                   24589: #      FAILP -- FAILURE IN MATCHING PATTERN NODE
                   24590: #
                   24591: #      FAILP IS USED AFTER FAILING TO MATCH A PATTERN NODE.
                   24592: #      SEE PATTERN MATCH ROUTINES FOR DETAILS OF USE.
                   24593: #
                   24594: #      (XL,XR)               MAY BE NON-COLLECTABLE
                   24595: #      BRN  FAILP            SIGNAL FAILURE TO MATCH
                   24596: #
                   24597: #      FAILP CONTINUES BY MATCHING AN ALTERNATIVE FROM THE STACK
                   24598: #
                   24599: failp: #rtn    
                   24600:        movl    (sp)+,r9        # load alternative node pointer
                   24601:        movl    (sp)+,r7        # restore old cursor
                   24602:        movl    (r9),r10        # load pcode entry pointer
                   24603:        movl    r10,r11         # jump to execute code for node
                   24604:        jmp     (r11)
                   24605:        #page   
                   24606: #
                   24607: #      INDIR -- COMPUTE INDIRECT REFERENCE
                   24608: #
                   24609: #      (WB)                  NONZERO/ZERO FOR BY NAME/VALUE
                   24610: #      BRN  INDIR            JUMP TO GET INDIRECT REF ON STACK
                   24611: #
                   24612: #      INDIR CONTINUES BY EXECUTING THE NEXT CODE WORD
                   24613: #
                   24614: indir: #rtn    
                   24615:        movl    (sp)+,r9        # load argument
                   24616:        cmpl    (r9),$b$nml     # jump if a name
                   24617:        beqlu   indr2
                   24618:        jsb     gtnvr           # else convert to variable
                   24619:        .long   er_239          # indirection operand is not name
                   24620:        tstl    r7              # skip if by value
                   24621:        beqlu   indr1
                   24622:        movl    r9,-(sp)        # else stack vrblk ptr
                   24623:        movl    $4*vrval,-(sp)  # stack name offset
                   24624:        jmp     exits           # exit with result on stack
                   24625: #
                   24626: #      HERE TO GET VALUE OF NATURAL VARIABLE
                   24627: #
                   24628: indr1: movl    (r9),r11        # jump through vrget field of vrblk
                   24629:        jmp     (r11)
                   24630: #
                   24631: #      HERE IF OPERAND IS A NAME
                   24632: #
                   24633: indr2: movl    4*nmbas(r9),r10 # load name base
                   24634:        movl    4*nmofs(r9),r6  # load name offset
                   24635:        tstl    r7              # exit if called by name
                   24636:        beqlu   0f
                   24637:        jmp     exnam
                   24638: 0:             
                   24639:        jsb     acess           # else get value first
                   24640:        .long   exfal           # fail if access fails
                   24641:        jmp     exixr           # else return with value in xr
                   24642:        #page   
                   24643: #
                   24644: #      MATCH -- INITIATE PATTERN MATCH
                   24645: #
                   24646: #      (WB)                  MATCH TYPE CODE
                   24647: #      BRN  MATCH            JUMP TO INITIATE PATTERN MATCH
                   24648: #
                   24649: #      MATCH CONTINUES BY EXECUTING THE PATTERN MATCH. SEE
                   24650: #      PATTERN MATCH ROUTINES (P$XXX) FOR FULL DETAILS.
                   24651: #
                   24652: match: #rtn    
                   24653:        movl    (sp)+,r9        # load pattern operand
                   24654:        jsb     gtpat           # convert to pattern
                   24655:        .long   er_240          # pattern match right operand is not pattern
                   24656:        movl    r9,r10          # if ok, save pattern pointer
                   24657:        tstl    r7              # jump if not match by name
                   24658:        bnequ   mtch1
                   24659:        movl    (sp),r6         # else load name offset
                   24660:        movl    r10,-(sp)       # save pattern pointer
                   24661:        movl    4*2(sp),r10     # load name base
                   24662:        jsb     acess           # access subject value
                   24663:        .long   exfal           # fail if access fails
                   24664:        movl    (sp),r10        # restore pattern pointer
                   24665:        movl    r9,(sp)         # stack subject string val for merge
                   24666:        clrl    r7              # restore type code
                   24667: #
                   24668: #      MERGE HERE WITH SUBJECT VALUE ON STACK
                   24669: #
                   24670: mtch1: movl    (sp),r9         # load subject value
                   24671:        clrl    r$pmb           # assume not a buffer
                   24672:        cmpl    (r9),$b$bct     # branch if not
                   24673:        bnequ   mtcha
                   24674:        addl2   $4,sp           # else pop value
                   24675:        movl    r9,r$pmb        # save pointer
                   24676:        movl    4*bclen(r9),r6  # get defined length
                   24677:        movl    4*bcbuf(r9),r9  # point to bfblk
                   24678:        jmp     mtchb
                   24679: #
                   24680: #      HERE IF NOT BUFFER TO CONVERT TO STRING
                   24681: #
                   24682: mtcha: jsb     gtstg           # not buffer - convert to string
                   24683:        .long   er_241          # pattern match left operand is not string
                   24684: #
                   24685: #      MERGE WITH BUFFER OR STRING
                   24686: #
                   24687: mtchb: movl    r9,r$pms        # if ok, store subject string pointer
                   24688:        movl    r6,pmssl        # and length
                   24689:        movl    r7,-(sp)        # stack match type code
                   24690:        clrl    -(sp)           # stack initial cursor (zero)
                   24691:        clrl    r7              # set initial cursor
                   24692:        movl    sp,pmhbs        # set history stack base ptr
                   24693:        clrl    pmdfl           # reset pattern assignment flag
                   24694:        movl    r10,r9          # set initial node pointer
                   24695:        tstl    kvanc           # jump if anchored
                   24696:        bnequ   mtch2
                   24697: #
                   24698: #      HERE FOR UNANCHORED
                   24699: #
                   24700:        movl    r9,-(sp)        # stack initial node pointer
                   24701:        movl    $nduna,-(sp)    # stack pointer to anchor move node
                   24702:        movl    (r9),r11        # start match of first node
                   24703:        jmp     (r11)
                   24704: #
                   24705: #      HERE IN ANCHORED MODE
                   24706: #
                   24707: mtch2: clrl    -(sp)           # dummy cursor value
                   24708:        movl    $ndabo,-(sp)    # stack pointer to abort node
                   24709:        movl    (r9),r11        # start match of first node
                   24710:        jmp     (r11)
                   24711:        #page   
                   24712: #
                   24713: #      RETRN -- RETURN FROM FUNCTION
                   24714: #
                   24715: #      (WA)                  STRING POINTER FOR RETURN TYPE
                   24716: #      BRN  RETRN            JUMP TO RETURN FROM (SNOBOL) FUNC
                   24717: #
                   24718: #      RETRN CONTINUES BY EXECUTING THE CODE AT THE RETURN POINT
                   24719: #      THE STACK IS CLEANED OF ANY GARBAGE LEFT BY OTHER
                   24720: #      ROUTINES WHICH MAY HAVE ALTERED FLPTR SINCE FUNCTION
                   24721: #      ENTRY BY USING FLPRT, RESERVED FOR USE ONLY BY
                   24722: #      FUNCTION CALL AND RETURN.
                   24723: #
                   24724: retrn: #rtn    
                   24725:        tstl    kvfnc           # jump if not level zero
                   24726:        bnequ   rtn01
                   24727:        jmp     er_242          # function return from level zero
                   24728: #
                   24729: #      HERE IF NOT LEVEL ZERO RETURN
                   24730: #
                   24731: rtn01: movl    flprt,sp        # pop stack
                   24732:        addl2   $4,sp           # remove failure offset
                   24733:        movl    (sp)+,r9        # pop pfblk pointer
                   24734:        movl    (sp)+,flptr     # pop failure pointer
                   24735:        movl    (sp)+,flprt     # pop old flprt
                   24736:        movl    (sp)+,r7        # pop code pointer offset
                   24737:        movl    (sp)+,r8        # pop old code block pointer
                   24738:        addl2   r8,r7           # make old code pointer absolute
                   24739:        movl    r7,r3           # restore old code pointer
                   24740:        movl    r8,r$cod        # restore old code block pointer
                   24741:        decl    kvfnc           # decrement function level
                   24742:        movl    kvtra,r7        # load trace
                   24743:        addl2   kvftr,r7        # add ftrace
                   24744:        bnequ   0f              # jump if no tracing possible
                   24745:        jmp     rtn06
                   24746: 0:             
                   24747: #
                   24748: #      HERE IF THERE MAY BE A TRACE
                   24749: #
                   24750:        movl    r6,-(sp)        # save function return type
                   24751:        movl    r9,-(sp)        # save pfblk pointer
                   24752:        movl    r6,kvrtn        # set rtntype for trace function
                   24753:        movl    r$fnc,r10       # load fnclevel trblk ptr (if any)
                   24754:        jsb     ktrex           # execute possible fnclevel trace
                   24755:        movl    4*pfvbl(r9),r10 # load vrblk ptr (sgd13)
                   24756:        tstl    kvtra           # jump if trace is off
                   24757:        beqlu   rtn02
                   24758:        movl    4*pfrtr(r9),r9  # else load return trace trblk ptr
                   24759:        beqlu   rtn02           # jump if not return traced
                   24760:        decl    kvtra           # else decrement trace count
                   24761:        tstl    4*trfnc(r9)     # jump if print trace
                   24762:        beqlu   rtn03
                   24763:        movl    $4*vrval,r6     # else set name offset
                   24764:        movl    4*1(sp),kvrtn   # make sure rtntype is set right
                   24765:        jsb     trxeq           # execute full trace
                   24766:        #page   
                   24767: #
                   24768: #      RETRN (CONTINUED)
                   24769: #
                   24770: #      HERE TO TEST FOR FTRACE
                   24771: #
                   24772: rtn02: tstl    kvftr           # jump if ftrace is off
                   24773:        beqlu   rtn05
                   24774:        decl    kvftr           # else decrement ftrace
                   24775: #
                   24776: #      HERE FOR PRINT TRACE OF FUNCTION RETURN
                   24777: #
                   24778: rtn03: jsb     prtsn           # print statement number
                   24779:        movl    4*1(sp),r9      # load return type
                   24780:        jsb     prtst           # print it
                   24781:        movl    $ch$bl,r6       # load blank
                   24782:        jsb     prtch           # print it
                   24783:        movl    (sp),r10        # load pfblk ptr
                   24784:        movl    4*pfvbl(r10),r10# load function vrblk ptr
                   24785:        movl    $4*vrval,r6     # set vrblk name offset
                   24786:        cmpl    r9,$scfrt       # jump if not freturn case
                   24787:        bnequ   rtn04
                   24788: #
                   24789: #      FOR FRETURN, JUST PRINT FUNCTION NAME
                   24790: #
                   24791:        jsb     prtnm           # print name
                   24792:        jsb     prtnl           # terminate print line
                   24793:        jmp     rtn05           # merge
                   24794: #
                   24795: #      HERE FOR RETURN OR NRETURN, PRINT FUNCTION NAME = VALUE
                   24796: #
                   24797: rtn04: jsb     prtnv           # print name = value
                   24798: #
                   24799: #      HERE AFTER COMPLETING TRACE
                   24800: #
                   24801: rtn05: movl    (sp)+,r9        # pop pfblk pointer
                   24802:        movl    (sp)+,r6        # pop return type string
                   24803: #
                   24804: #      MERGE HERE IF NO TRACE REQUIRED
                   24805: #
                   24806: rtn06: movl    r6,kvrtn        # set rtntype keyword
                   24807:        movl    4*pfvbl(r9),r10 # load pointer to fn vrblk
                   24808:        #page   
                   24809: #      RETRN (CONTINUED)
                   24810: #
                   24811: #      GET VALUE OF FUNCTION
                   24812: #
                   24813: rtn07: movl    r10,rtnbp       # save block pointer
                   24814:        movl    4*vrval(r10),r10# load value
                   24815:        cmpl    (r10),$b$trt    # loop back if trapped
                   24816:        beqlu   rtn07
                   24817:        movl    r10,rtnfv       # else save function result value
                   24818:        movl    (sp)+,rtnsv     # save original function value
                   24819:        movl    (sp)+,r10       # pop saved pointer
                   24820:        beqlu   rtn7c           # no action if none
                   24821:        tstl    kvpfl           # jump if no profiling
                   24822:        beqlu   rtn7c
                   24823:        jsb     prflu           # else profile last func stmt
                   24824:        cmpl    kvpfl,$num02    # branch on value of profile keywd
                   24825:        beqlu   rtn7a
                   24826: #
                   24827: #      HERE IF &PROFILE = 1. START TIME MUST BE FRIGGED TO
                   24828: #      APPEAR EARLIER THAN IT ACTUALLY IS, BY AMOUNT USED BEFORE
                   24829: #      THE CALL.
                   24830: #
                   24831:        movl    pfstm,r5        # load current time
                   24832:        subl2   4*icval(r10),r5 # frig by subtracting saved amount
                   24833:        jmp     rtn7b           # and merge
                   24834: #
                   24835: #      HERE IF &PROFILE = 2
                   24836: #
                   24837: rtn7a: movl    4*icval(r10),r5 # load saved time
                   24838: #
                   24839: #      BOTH PROFILE TYPES MERGE HERE
                   24840: #
                   24841: rtn7b: movl    r5,pfstm        # store back correct start time
                   24842: #
                   24843: #      MERGE HERE IF NO PROFILING
                   24844: #
                   24845: rtn7c: movl    4*fargs(r9),r7  # get number of args
                   24846:        addl2   4*pfnlo(r9),r7  # add number of locals
                   24847:        beqlu   rtn10           # jump if no args/locals
                   24848:                                # else set loop counter
                   24849:        addl2   4*pflen(r9),r9  # and point to end of pfblk
                   24850: #
                   24851: #      LOOP TO RESTORE FUNCTIONS AND LOCALS
                   24852: #
                   24853: rtn08: movl    -(r9),r10       # load next vrblk pointer
                   24854: #
                   24855: #      LOOP TO FIND VALUE BLOCK
                   24856: #
                   24857: rtn09: movl    r10,r6          # save block pointer
                   24858:        movl    4*vrval(r10),r10# load pointer to next value
                   24859:        cmpl    (r10),$b$trt    # loop back if trapped
                   24860:        beqlu   rtn09
                   24861:        movl    r6,r10          # else restore last block pointer
                   24862:        movl    (sp)+,4*vrval(r10) # restore old variable value
                   24863:        sobgtr  r7,rtn08        # loop till all processed
                   24864: #
                   24865: #      NOW RESTORE FUNCTION VALUE AND EXIT
                   24866: #
                   24867: rtn10: movl    rtnbp,r10       # restore ptr to last function block
                   24868:        movl    rtnsv,4*vrval(r10) # restore old function value
                   24869:        movl    rtnfv,r9        # reload function result
                   24870:        movl    r$cod,r10       # point to new code block
                   24871:        movl    kvstn,kvlst     # set lastno from stno
                   24872:        movl    4*cdstm(r10),kvstn # reset proper stno value
                   24873:        movl    kvrtn,r6        # load return type
                   24874:        cmpl    r6,$scrtn       # exit with result in xr if return
                   24875:        bnequ   0f
                   24876:        jmp     exixr
                   24877: 0:             
                   24878:        cmpl    r6,$scfrt       # fail if freturn
                   24879:        bnequ   0f
                   24880:        jmp     exfal
                   24881: 0:             
                   24882:        #page   
                   24883: #
                   24884: #      RETRN (CONTINUED)
                   24885: #
                   24886: #      HERE FOR NRETURN
                   24887: #
                   24888:        cmpl    (r9),$b$nml     # jump if is a name
                   24889:        beqlu   rtn11
                   24890:        jsb     gtnvr           # else try convert to variable name
                   24891:        .long   er_243          # function result in nreturn is not name
                   24892:        movl    r9,r10          # if ok, copy vrblk (name base) ptr
                   24893:        movl    $4*vrval,r6     # set name offset
                   24894:        jmp     rtn12           # and merge
                   24895: #
                   24896: #      HERE IF RETURNED RESULT IS A NAME
                   24897: #
                   24898: rtn11: movl    4*nmbas(r9),r10 # load name base
                   24899:        movl    4*nmofs(r9),r6  # load name offset
                   24900: #
                   24901: #      MERGE HERE WITH RETURNED NAME IN (XL,WA)
                   24902: #
                   24903: rtn12: movl    r10,r9          # preserve xl
                   24904:        movl    (r3)+,r7        # load next word
                   24905:        movl    r9,r10          # restore xl
                   24906:        cmpl    r7,$ofne$       # exit if called by name
                   24907:        bnequ   0f
                   24908:        jmp     exnam
                   24909: 0:             
                   24910:        movl    r7,-(sp)        # else save code word
                   24911:        jsb     acess           # get value
                   24912:        .long   exfal           # fail if access fails
                   24913:        movl    r9,r10          # if ok, copy result
                   24914:        movl    (sp),r9         # reload next code word
                   24915:        movl    r10,(sp)        # store result on stack
                   24916:        movl    (r9),r10        # load routine address
                   24917:        movl    r10,r11         # jump to execute next code word
                   24918:        jmp     (r11)
                   24919:        #page   
                   24920: #
                   24921: #      STCOV -- SIGNAL STATEMENT COUNTER OVERFLOW
                   24922: #
                   24923: #      BRN  STCOV            JUMP TO SIGNAL STATEMENT COUNT OFLO
                   24924: #
                   24925: #      PERMIT UP TO 10 MORE STATEMENTS TO BE OBEYED SO THAT
                   24926: #      SETEXIT TRAP CAN REGAIN CONTROL.
                   24927: #      STCOV CONTINUES BY ISSUING THE ERROR MESSAGE
                   24928: #
                   24929: stcov: #rtn    
                   24930:        incl    errft           # fatal error
                   24931:        movl    intvt,r5        # get 10
                   24932:        addl2   kvstl,r5        # add to former limit
                   24933:        movl    r5,kvstl        # store as new stlimit
                   24934:        movl    intvt,r5        # get 10
                   24935:        movl    r5,kvstc        # set as new count
                   24936:        jmp     er_244          # statement count exceeds value of stlimit keyword
                   24937:        #page   
                   24938: #
                   24939: #      STMGO -- START EXECUTION OF NEW STATEMENT
                   24940: #
                   24941: #      (XR)                  POINTER TO CDBLK FOR NEW STATEMENT
                   24942: #      BRN  STMGO            JUMP TO EXECUTE NEW STATEMENT
                   24943: #
                   24944: #      STMGO CONTINUES BY EXECUTING THE NEXT STATEMENT
                   24945: #
                   24946: stmgo: #rtn    
                   24947:        movl    r9,r$cod        # set new code block pointer
                   24948:        tstl    kvpfl           # skip if no profiling
                   24949:        beqlu   stgo1
                   24950:        jsb     prflu           # else profile the statement
                   24951: stgo1: movl    kvstn,kvlst     # set lastno
                   24952:        movl    4*cdstm(r9),kvstn# set stno
                   24953:        addl2   $4*cdcod,r9     # point to first code word
                   24954:        movl    r9,r3           # set code pointer
                   24955:        movl    kvstc,r5        # get stmt count
                   24956:        bgeq    0f              # omit counting if negative
                   24957:        jmp     exits
                   24958: 0:             
                   24959:        tstl    r5              # fail if stlimit reached
                   24960:        beql    stcov
                   24961:        subl2   intv1,r5        # decrement
                   24962:        movl    r5,kvstc        # replace it
                   24963:        tstl    r$stc           # exit if no stcount trace
                   24964:        bnequ   0f
                   24965:        jmp     exits
                   24966: 0:             
                   24967: #
                   24968: #      HERE FOR STCOUNT TRACE
                   24969: #
                   24970:        clrl    r9              # clear garbage value in xr
                   24971:        movl    r$stc,r10       # load pointer to stcount trblk
                   24972:        jsb     ktrex           # execute keyword trace
                   24973:        jmp     exits           # and then exit for next code word
                   24974:        #page   
                   24975: #
                   24976: #      STOPR -- TERMINATE RUN
                   24977: #
                   24978: #      (XR)                  POINTS TO ENDING MESSAGE
                   24979: #      BRN STOPR             JUMP TO TERMINATE RUN
                   24980: #
                   24981: #      TERMINATE RUN AND PRINT STATISTICS.  ON ENTRY XR POINTS
                   24982: #      TO ENDING MESSAGE OR IS ZERO IF MESSAGE  PRINTED ALREADY.
                   24983: #
                   24984: stopr: #rtn    
                   24985:        tstl    r9              # skip if sysax already called (reg04)
                   24986:        beqlu   stpra
                   24987:        jsb     sysax           # call after execution proc
                   24988: stpra: addl2   rsmem,dname     # use the reserve memory
                   24989:        cmpl    r9,$endms       # skip if not normal end message
                   24990:        bnequ   stpr0
                   24991:        tstl    exsts           # skip if exec stats suppressed
                   24992:        beqlu   0f
                   24993:        jmp     stpr3
                   24994: 0:             
                   24995:        clrl    erich           # clear errors to int.ch. flag
                   24996: #
                   24997: #      LOOK TO SEE IF AN ENDING MESSAGE IS SUPPLIED
                   24998: #
                   24999: stpr0: jsb     prtpg           # eject printer
                   25000:        tstl    r9              # skip if no message
                   25001:        beqlu   stpr1
                   25002:        jsb     prtst           # print message
                   25003: #
                   25004: #      MERGE HERE IF NO MESSAGE TO PRINT
                   25005: #
                   25006: stpr1: jsb     prtis           # print blank line
                   25007:        movl    kvstn,r5        # get statement number
                   25008:        movl    $stpm1,r9       # point to message /in statement xxx/
                   25009:        jsb     prtmx           # print it
                   25010:        jsb     systm           # get current time
                   25011:        subl2   timsx,r5        # minus start time = elapsed exec tim
                   25012:        movl    r5,stpti        # save for later
                   25013:        movl    $stpm3,r9       # point to msg /execution time msec /
                   25014:        jsb     prtmx           # print it
                   25015:        movl    kvstl,r5        # get statement limit
                   25016:        blss    stpr2           # skip if negative
                   25017:        subl2   kvstc,r5        # minus counter = count
                   25018:        movl    r5,stpsi        # save
                   25019:        movl    $stpm2,r9       # point to message /stmts executed/
                   25020:        jsb     prtmx           # print it
                   25021:        movl    stpti,r5        # reload elapsed time
                   25022:        mull2   intth,r5        # *1000 (microsecs)
                   25023:        bvs     stpr2
                   25024:        divl2   stpsi,r5        # divide by statement count
                   25025:        bvs     stpr2
                   25026:        movl    $stpm4,r9       # point to msg (mcsec per statement /
                   25027:        jsb     prtmx           # print it
                   25028:        #page   
                   25029: #
                   25030: #      STOPR (CONTINUED)
                   25031: #
                   25032: #      MERGE TO SKIP MESSAGE (OVERFLOW OR NEGATIVE STLIMIT)
                   25033: #
                   25034: stpr2: movl    gbcnt,r5        # load count of collections
                   25035:        movl    $stpm5,r9       # point to message /regenerations /
                   25036:        jsb     prtmx           # print it
                   25037:        jsb     prtis           # one more blank for luck
                   25038: #
                   25039: #      CHECK IF DUMP REQUESTED
                   25040: #
                   25041: stpr3: jsb     prflr           # print profile if wanted
                   25042: #
                   25043:        movl    kvdmp,r9        # load dump keyword
                   25044:        jsb     dumpr           # execute dump if requested
                   25045:        movl    r$fcb,r10       # get fcblk chain head
                   25046:        movl    kvabe,r6        # load abend value
                   25047:        movl    kvcod,r7        # load code value
                   25048:        jsb     sysej           # exit to system
                   25049:        #page   
                   25050: #
                   25051: #      SUCCP -- SIGNAL SUCCESSFUL MATCH OF A PATTERN NODE
                   25052: #
                   25053: #      SEE PATTERN MATCH ROUTINES FOR DETAILS
                   25054: #
                   25055: #      (XR)                  CURRENT NODE
                   25056: #      (WB)                  CURRENT CURSOR
                   25057: #      (XL)                  MAY BE NON-COLLECTABLE
                   25058: #      BRN  SUCCP            SIGNAL SUCCESSFUL PATTERN MATCH
                   25059: #
                   25060: #      SUCCP CONTINUES BY MATCHING THE SUCCESSOR NODE
                   25061: #
                   25062: succp: #rtn    
                   25063:        movl    4*pthen(r9),r9  # load successor node
                   25064:        movl    (r9),r10        # load node code entry address
                   25065:        movl    r10,r11         # jump to match successor node
                   25066:        jmp     (r11)
                   25067:        #page   
                   25068: #
                   25069: #      SYSAB -- PRINT /ABNORMAL END/ AND TERMINATE
                   25070: #
                   25071: sysab: #rtn    
                   25072:        movl    $endab,r9       # point to message
                   25073:        movl    $num01,kvabe    # set abend flag
                   25074:        jsb     prtnl           # skip to new line
                   25075:        jmp     stopr           # jump to pack up
                   25076:        #page   
                   25077: #
                   25078: #      SYSTU -- PRINT /TIME UP/ AND TERMINATE
                   25079: #
                   25080: systu: #rtn    
                   25081:        movl    $endtu,r9       # point to message
                   25082:        movl    strtu,r6        # get chars /tu/
                   25083:        movl    r6,kvcod        # put in kvcod
                   25084:        movl    timup,r6        # check state of timeup switch
                   25085:        movl    sp,timup        # set switch
                   25086:        tstl    r6              # stop run if already set
                   25087:        beqlu   0f
                   25088:        jmp     stopr
                   25089: 0:             
                   25090:        jmp     er_245          # translation/execution time expired
                   25091:        #title  s p i t b o l -- stack overflow section
                   25092: #
                   25093: #      CONTROL COMES HERE IF THE MAIN STACK OVERFLOWS
                   25094: #
                   25095: er_001:        movzwl  $1,r6
                   25096:        jmp     error
                   25097: er_002:        movzwl  $2,r6
                   25098:        jmp     error
                   25099: er_003:        movzwl  $3,r6
                   25100:        jmp     error
                   25101: er_004:        movzwl  $4,r6
                   25102:        jmp     error
                   25103: er_005:        movzwl  $5,r6
                   25104:        jmp     error
                   25105: er_006:        movzwl  $6,r6
                   25106:        jmp     error
                   25107: er_007:        movzwl  $7,r6
                   25108:        jmp     error
                   25109: er_008:        movzwl  $8,r6
                   25110:        jmp     error
                   25111: er_009:        movzwl  $9,r6
                   25112:        jmp     error
                   25113: er_010:        movzwl  $10,r6
                   25114:        jmp     error
                   25115: er_011:        movzwl  $11,r6
                   25116:        jmp     error
                   25117: er_012:        movzwl  $12,r6
                   25118:        jmp     error
                   25119: er_013:        movzwl  $13,r6
                   25120:        jmp     error
                   25121: er_014:        movzwl  $14,r6
                   25122:        jmp     error
                   25123: er_015:        movzwl  $15,r6
                   25124:        jmp     error
                   25125: er_016:        movzwl  $16,r6
                   25126:        jmp     error
                   25127: er_017:        movzwl  $17,r6
                   25128:        jmp     error
                   25129: er_018:        movzwl  $18,r6
                   25130:        jmp     error
                   25131: er_019:        movzwl  $19,r6
                   25132:        jmp     error
                   25133: er_020:        movzwl  $20,r6
                   25134:        jmp     error
                   25135: er_021:        movzwl  $21,r6
                   25136:        jmp     error
                   25137: er_022:        movzwl  $22,r6
                   25138:        jmp     error
                   25139: er_023:        movzwl  $23,r6
                   25140:        jmp     error
                   25141: er_024:        movzwl  $24,r6
                   25142:        jmp     error
                   25143: er_025:        movzwl  $25,r6
                   25144:        jmp     error
                   25145: er_026:        movzwl  $26,r6
                   25146:        jmp     error
                   25147: er_027:        movzwl  $27,r6
                   25148:        jmp     error
                   25149: er_028:        movzwl  $28,r6
                   25150:        jmp     error
                   25151: er_029:        movzwl  $29,r6
                   25152:        jmp     error
                   25153: er_030:        movzwl  $30,r6
                   25154:        jmp     error
                   25155: er_031:        movzwl  $31,r6
                   25156:        jmp     error
                   25157: er_032:        movzwl  $32,r6
                   25158:        jmp     error
                   25159: er_033:        movzwl  $33,r6
                   25160:        jmp     error
                   25161: er_034:        movzwl  $34,r6
                   25162:        jmp     error
                   25163: er_035:        movzwl  $35,r6
                   25164:        jmp     error
                   25165: er_036:        movzwl  $36,r6
                   25166:        jmp     error
                   25167: er_037:        movzwl  $37,r6
                   25168:        jmp     error
                   25169: er_038:        movzwl  $38,r6
                   25170:        jmp     error
                   25171: er_039:        movzwl  $39,r6
                   25172:        jmp     error
                   25173: er_040:        movzwl  $40,r6
                   25174:        jmp     error
                   25175: er_041:        movzwl  $41,r6
                   25176:        jmp     error
                   25177: er_042:        movzwl  $42,r6
                   25178:        jmp     error
                   25179: er_043:        movzwl  $43,r6
                   25180:        jmp     error
                   25181: er_044:        movzwl  $44,r6
                   25182:        jmp     error
                   25183: er_045:        movzwl  $45,r6
                   25184:        jmp     error
                   25185: er_046:        movzwl  $46,r6
                   25186:        jmp     error
                   25187: er_047:        movzwl  $47,r6
                   25188:        jmp     error
                   25189: er_048:        movzwl  $48,r6
                   25190:        jmp     error
                   25191: er_049:        movzwl  $49,r6
                   25192:        jmp     error
                   25193: er_050:        movzwl  $50,r6
                   25194:        jmp     error
                   25195: er_051:        movzwl  $51,r6
                   25196:        jmp     error
                   25197: er_052:        movzwl  $52,r6
                   25198:        jmp     error
                   25199: er_053:        movzwl  $53,r6
                   25200:        jmp     error
                   25201: er_054:        movzwl  $54,r6
                   25202:        jmp     error
                   25203: er_055:        movzwl  $55,r6
                   25204:        jmp     error
                   25205: er_056:        movzwl  $56,r6
                   25206:        jmp     error
                   25207: er_057:        movzwl  $57,r6
                   25208:        jmp     error
                   25209: er_058:        movzwl  $58,r6
                   25210:        jmp     error
                   25211: er_059:        movzwl  $59,r6
                   25212:        jmp     error
                   25213: er_060:        movzwl  $60,r6
                   25214:        jmp     error
                   25215: er_061:        movzwl  $61,r6
                   25216:        jmp     error
                   25217: er_062:        movzwl  $62,r6
                   25218:        jmp     error
                   25219: er_063:        movzwl  $63,r6
                   25220:        jmp     error
                   25221: er_064:        movzwl  $64,r6
                   25222:        jmp     error
                   25223: er_065:        movzwl  $65,r6
                   25224:        jmp     error
                   25225: er_066:        movzwl  $66,r6
                   25226:        jmp     error
                   25227: er_067:        movzwl  $67,r6
                   25228:        jmp     error
                   25229: er_068:        movzwl  $68,r6
                   25230:        jmp     error
                   25231: er_069:        movzwl  $69,r6
                   25232:        jmp     error
                   25233: er_070:        movzwl  $70,r6
                   25234:        jmp     error
                   25235: er_071:        movzwl  $71,r6
                   25236:        jmp     error
                   25237: er_072:        movzwl  $72,r6
                   25238:        jmp     error
                   25239: er_073:        movzwl  $73,r6
                   25240:        jmp     error
                   25241: er_074:        movzwl  $74,r6
                   25242:        jmp     error
                   25243: er_075:        movzwl  $75,r6
                   25244:        jmp     error
                   25245: er_076:        movzwl  $76,r6
                   25246:        jmp     error
                   25247: er_077:        movzwl  $77,r6
                   25248:        jmp     error
                   25249: er_078:        movzwl  $78,r6
                   25250:        jmp     error
                   25251: er_079:        movzwl  $79,r6
                   25252:        jmp     error
                   25253: er_080:        movzwl  $80,r6
                   25254:        jmp     error
                   25255: er_081:        movzwl  $81,r6
                   25256:        jmp     error
                   25257: er_082:        movzwl  $82,r6
                   25258:        jmp     error
                   25259: er_083:        movzwl  $83,r6
                   25260:        jmp     error
                   25261: er_084:        movzwl  $84,r6
                   25262:        jmp     error
                   25263: er_085:        movzwl  $85,r6
                   25264:        jmp     error
                   25265: er_086:        movzwl  $86,r6
                   25266:        jmp     error
                   25267: er_087:        movzwl  $87,r6
                   25268:        jmp     error
                   25269: er_088:        movzwl  $88,r6
                   25270:        jmp     error
                   25271: er_089:        movzwl  $89,r6
                   25272:        jmp     error
                   25273: er_090:        movzwl  $90,r6
                   25274:        jmp     error
                   25275: er_091:        movzwl  $91,r6
                   25276:        jmp     error
                   25277: er_092:        movzwl  $92,r6
                   25278:        jmp     error
                   25279: er_093:        movzwl  $93,r6
                   25280:        jmp     error
                   25281: er_094:        movzwl  $94,r6
                   25282:        jmp     error
                   25283: er_095:        movzwl  $95,r6
                   25284:        jmp     error
                   25285: er_096:        movzwl  $96,r6
                   25286:        jmp     error
                   25287: er_097:        movzwl  $97,r6
                   25288:        jmp     error
                   25289: er_098:        movzwl  $98,r6
                   25290:        jmp     error
                   25291: er_099:        movzwl  $99,r6
                   25292:        jmp     error
                   25293: er_100:        movzwl  $100,r6
                   25294:        jmp     error
                   25295: er_101:        movzwl  $101,r6
                   25296:        jmp     error
                   25297: er_102:        movzwl  $102,r6
                   25298:        jmp     error
                   25299: er_103:        movzwl  $103,r6
                   25300:        jmp     error
                   25301: er_104:        movzwl  $104,r6
                   25302:        jmp     error
                   25303: er_105:        movzwl  $105,r6
                   25304:        jmp     error
                   25305: er_106:        movzwl  $106,r6
                   25306:        jmp     error
                   25307: er_107:        movzwl  $107,r6
                   25308:        jmp     error
                   25309: er_108:        movzwl  $108,r6
                   25310:        jmp     error
                   25311: er_109:        movzwl  $109,r6
                   25312:        jmp     error
                   25313: er_110:        movzwl  $110,r6
                   25314:        jmp     error
                   25315: er_111:        movzwl  $111,r6
                   25316:        jmp     error
                   25317: er_112:        movzwl  $112,r6
                   25318:        jmp     error
                   25319: er_113:        movzwl  $113,r6
                   25320:        jmp     error
                   25321: er_114:        movzwl  $114,r6
                   25322:        jmp     error
                   25323: er_115:        movzwl  $115,r6
                   25324:        jmp     error
                   25325: er_116:        movzwl  $116,r6
                   25326:        jmp     error
                   25327: er_117:        movzwl  $117,r6
                   25328:        jmp     error
                   25329: er_118:        movzwl  $118,r6
                   25330:        jmp     error
                   25331: er_119:        movzwl  $119,r6
                   25332:        jmp     error
                   25333: er_120:        movzwl  $120,r6
                   25334:        jmp     error
                   25335: er_121:        movzwl  $121,r6
                   25336:        jmp     error
                   25337: er_122:        movzwl  $122,r6
                   25338:        jmp     error
                   25339: er_123:        movzwl  $123,r6
                   25340:        jmp     error
                   25341: er_124:        movzwl  $124,r6
                   25342:        jmp     error
                   25343: er_125:        movzwl  $125,r6
                   25344:        jmp     error
                   25345: er_126:        movzwl  $126,r6
                   25346:        jmp     error
                   25347: er_127:        movzwl  $127,r6
                   25348:        jmp     error
                   25349: er_128:        movzwl  $128,r6
                   25350:        jmp     error
                   25351: er_129:        movzwl  $129,r6
                   25352:        jmp     error
                   25353: er_130:        movzwl  $130,r6
                   25354:        jmp     error
                   25355: er_131:        movzwl  $131,r6
                   25356:        jmp     error
                   25357: er_132:        movzwl  $132,r6
                   25358:        jmp     error
                   25359: er_133:        movzwl  $133,r6
                   25360:        jmp     error
                   25361: er_134:        movzwl  $134,r6
                   25362:        jmp     error
                   25363: er_135:        movzwl  $135,r6
                   25364:        jmp     error
                   25365: er_136:        movzwl  $136,r6
                   25366:        jmp     error
                   25367: er_137:        movzwl  $137,r6
                   25368:        jmp     error
                   25369: er_138:        movzwl  $138,r6
                   25370:        jmp     error
                   25371: er_139:        movzwl  $139,r6
                   25372:        jmp     error
                   25373: er_140:        movzwl  $140,r6
                   25374:        jmp     error
                   25375: er_141:        movzwl  $141,r6
                   25376:        jmp     error
                   25377: er_142:        movzwl  $142,r6
                   25378:        jmp     error
                   25379: er_143:        movzwl  $143,r6
                   25380:        jmp     error
                   25381: er_144:        movzwl  $144,r6
                   25382:        jmp     error
                   25383: er_145:        movzwl  $145,r6
                   25384:        jmp     error
                   25385: er_146:        movzwl  $146,r6
                   25386:        jmp     error
                   25387: er_147:        movzwl  $147,r6
                   25388:        jmp     error
                   25389: er_148:        movzwl  $148,r6
                   25390:        jmp     error
                   25391: er_149:        movzwl  $149,r6
                   25392:        jmp     error
                   25393: er_150:        movzwl  $150,r6
                   25394:        jmp     error
                   25395: er_151:        movzwl  $151,r6
                   25396:        jmp     error
                   25397: er_152:        movzwl  $152,r6
                   25398:        jmp     error
                   25399: er_153:        movzwl  $153,r6
                   25400:        jmp     error
                   25401: er_154:        movzwl  $154,r6
                   25402:        jmp     error
                   25403: er_155:        movzwl  $155,r6
                   25404:        jmp     error
                   25405: er_156:        movzwl  $156,r6
                   25406:        jmp     error
                   25407: er_157:        movzwl  $157,r6
                   25408:        jmp     error
                   25409: er_158:        movzwl  $158,r6
                   25410:        jmp     error
                   25411: er_159:        movzwl  $159,r6
                   25412:        jmp     error
                   25413: er_160:        movzwl  $160,r6
                   25414:        jmp     error
                   25415: er_161:        movzwl  $161,r6
                   25416:        jmp     error
                   25417: er_162:        movzwl  $162,r6
                   25418:        jmp     error
                   25419: er_163:        movzwl  $163,r6
                   25420:        jmp     error
                   25421: er_164:        movzwl  $164,r6
                   25422:        jmp     error
                   25423: er_165:        movzwl  $165,r6
                   25424:        jmp     error
                   25425: er_166:        movzwl  $166,r6
                   25426:        jmp     error
                   25427: er_167:        movzwl  $167,r6
                   25428:        jmp     error
                   25429: er_168:        movzwl  $168,r6
                   25430:        jmp     error
                   25431: er_169:        movzwl  $169,r6
                   25432:        jmp     error
                   25433: er_170:        movzwl  $170,r6
                   25434:        jmp     error
                   25435: er_171:        movzwl  $171,r6
                   25436:        jmp     error
                   25437: er_172:        movzwl  $172,r6
                   25438:        jmp     error
                   25439: er_173:        movzwl  $173,r6
                   25440:        jmp     error
                   25441: er_174:        movzwl  $174,r6
                   25442:        jmp     error
                   25443: er_175:        movzwl  $175,r6
                   25444:        jmp     error
                   25445: er_176:        movzwl  $176,r6
                   25446:        jmp     error
                   25447: er_177:        movzwl  $177,r6
                   25448:        jmp     error
                   25449: er_178:        movzwl  $178,r6
                   25450:        jmp     error
                   25451: er_179:        movzwl  $179,r6
                   25452:        jmp     error
                   25453: er_180:        movzwl  $180,r6
                   25454:        jmp     error
                   25455: er_181:        movzwl  $181,r6
                   25456:        jmp     error
                   25457: er_182:        movzwl  $182,r6
                   25458:        jmp     error
                   25459: er_183:        movzwl  $183,r6
                   25460:        jmp     error
                   25461: er_184:        movzwl  $184,r6
                   25462:        jmp     error
                   25463: er_185:        movzwl  $185,r6
                   25464:        jmp     error
                   25465: er_186:        movzwl  $186,r6
                   25466:        jmp     error
                   25467: er_187:        movzwl  $187,r6
                   25468:        jmp     error
                   25469: er_188:        movzwl  $188,r6
                   25470:        jmp     error
                   25471: er_189:        movzwl  $189,r6
                   25472:        jmp     error
                   25473: er_190:        movzwl  $190,r6
                   25474:        jmp     error
                   25475: er_191:        movzwl  $191,r6
                   25476:        jmp     error
                   25477: er_192:        movzwl  $192,r6
                   25478:        jmp     error
                   25479: er_193:        movzwl  $193,r6
                   25480:        jmp     error
                   25481: er_194:        movzwl  $194,r6
                   25482:        jmp     error
                   25483: er_195:        movzwl  $195,r6
                   25484:        jmp     error
                   25485: er_196:        movzwl  $196,r6
                   25486:        jmp     error
                   25487: er_197:        movzwl  $197,r6
                   25488:        jmp     error
                   25489: er_198:        movzwl  $198,r6
                   25490:        jmp     error
                   25491: er_199:        movzwl  $199,r6
                   25492:        jmp     error
                   25493: er_200:        movzwl  $200,r6
                   25494:        jmp     error
                   25495: er_201:        movzwl  $201,r6
                   25496:        jmp     error
                   25497: er_202:        movzwl  $202,r6
                   25498:        jmp     error
                   25499: er_203:        movzwl  $203,r6
                   25500:        jmp     error
                   25501: er_204:        movzwl  $204,r6
                   25502:        jmp     error
                   25503: er_205:        movzwl  $205,r6
                   25504:        jmp     error
                   25505: er_206:        movzwl  $206,r6
                   25506:        jmp     error
                   25507: er_207:        movzwl  $207,r6
                   25508:        jmp     error
                   25509: er_208:        movzwl  $208,r6
                   25510:        jmp     error
                   25511: er_209:        movzwl  $209,r6
                   25512:        jmp     error
                   25513: er_210:        movzwl  $210,r6
                   25514:        jmp     error
                   25515: er_211:        movzwl  $211,r6
                   25516:        jmp     error
                   25517: er_212:        movzwl  $212,r6
                   25518:        jmp     error
                   25519: er_213:        movzwl  $213,r6
                   25520:        jmp     error
                   25521: er_214:        movzwl  $214,r6
                   25522:        jmp     error
                   25523: er_215:        movzwl  $215,r6
                   25524:        jmp     error
                   25525: er_216:        movzwl  $216,r6
                   25526:        jmp     error
                   25527: er_217:        movzwl  $217,r6
                   25528:        jmp     error
                   25529: er_218:        movzwl  $218,r6
                   25530:        jmp     error
                   25531: er_219:        movzwl  $219,r6
                   25532:        jmp     error
                   25533: er_220:        movzwl  $220,r6
                   25534:        jmp     error
                   25535: er_221:        movzwl  $221,r6
                   25536:        jmp     error
                   25537: er_222:        movzwl  $222,r6
                   25538:        jmp     error
                   25539: er_223:        movzwl  $223,r6
                   25540:        jmp     error
                   25541: er_224:        movzwl  $224,r6
                   25542:        jmp     error
                   25543: er_225:        movzwl  $225,r6
                   25544:        jmp     error
                   25545: er_226:        movzwl  $226,r6
                   25546:        jmp     error
                   25547: er_227:        movzwl  $227,r6
                   25548:        jmp     error
                   25549: er_228:        movzwl  $228,r6
                   25550:        jmp     error
                   25551: er_229:        movzwl  $229,r6
                   25552:        jmp     error
                   25553: er_230:        movzwl  $230,r6
                   25554:        jmp     error
                   25555: er_231:        movzwl  $231,r6
                   25556:        jmp     error
                   25557: er_232:        movzwl  $232,r6
                   25558:        jmp     error
                   25559: er_233:        movzwl  $233,r6
                   25560:        jmp     error
                   25561: er_234:        movzwl  $234,r6
                   25562:        jmp     error
                   25563: er_235:        movzwl  $235,r6
                   25564:        jmp     error
                   25565: er_236:        movzwl  $236,r6
                   25566:        jmp     error
                   25567: er_237:        movzwl  $237,r6
                   25568:        jmp     error
                   25569: er_238:        movzwl  $238,r6
                   25570:        jmp     error
                   25571: er_239:        movzwl  $239,r6
                   25572:        jmp     error
                   25573: er_240:        movzwl  $240,r6
                   25574:        jmp     error
                   25575: er_241:        movzwl  $241,r6
                   25576:        jmp     error
                   25577: er_242:        movzwl  $242,r6
                   25578:        jmp     error
                   25579: er_243:        movzwl  $243,r6
                   25580:        jmp     error
                   25581: er_244:        movzwl  $244,r6
                   25582:        jmp     error
                   25583: er_245:        movzwl  $245,r6
                   25584:        jmp     error
                   25585: er_246:        movzwl  $246,r6
                   25586:        jmp     error
                   25587: er_247:        movzwl  $247,r6
                   25588:        jmp     error
                   25589: er_248:        movzwl  $248,r6
                   25590:        jmp     error
                   25591: er_249:        movzwl  $249,r6
                   25592:        jmp     error
                   25593: er_250:        movzwl  $250,r6
                   25594:        jmp     error
                   25595: er_251:        movzwl  $251,r6
                   25596:        jmp     error
                   25597: er_252:        movzwl  $252,r6
                   25598:        jmp     error
                   25599: er_253:        movzwl  $253,r6
                   25600:        jmp     error
                   25601: er_254:        movzwl  $254,r6
                   25602:        jmp     error
                   25603: er_255:        movzwl  $255,r6
                   25604:        jmp     error
                   25605: er_256:        movzwl  $256,r6
                   25606:        jmp     error
                   25607: er_257:        movzwl  $257,r6
                   25608:        jmp     error
                   25609: er_258:        movzwl  $258,r6
                   25610:        jmp     error
                   25611: er_259:        movzwl  $259,r6
                   25612:        jmp     error
                   25613: er_260:        movzwl  $260,r6
                   25614:        jmp     error
                   25615: er_261:        movzwl  $261,r6
                   25616:        jmp     error
                   25617: er_262:        movzwl  $262,r6
                   25618:        jmp     error
                   25619: er_263:        movzwl  $263,r6
                   25620:        jmp     error
                   25621: er_264:        movzwl  $264,r6
                   25622:        jmp     error
                   25623: er_265:        movzwl  $265,r6
                   25624:        jmp     error
                   25625: er_266:        movzwl  $266,r6
                   25626:        jmp     error
                   25627: er_267:        movzwl  $267,r6
                   25628:        jmp     error
                   25629: er_268:        movzwl  $268,r6
                   25630:        jmp     error
                   25631: er_269:        movzwl  $269,r6
                   25632:        jmp     error
                   25633: er_270:        movzwl  $270,r6
                   25634:        jmp     error
                   25635: er_271:        movzwl  $271,r6
                   25636:        jmp     error
                   25637: er_272:        movzwl  $272,r6
                   25638:        jmp     error
                   25639: er_273:        movzwl  $273,r6
                   25640:        jmp     error
                   25641: er_274:        movzwl  $274,r6
                   25642:        jmp     error
                   25643: er_275:        movzwl  $275,r6
                   25644:        jmp     error
                   25645: er_276:        movzwl  $276,r6
                   25646:        jmp     error
                   25647: er_277:        movzwl  $277,r6
                   25648:        jmp     error
                   25649: er_278:        movzwl  $278,r6
                   25650:        jmp     error
                   25651: er_279:        movzwl  $279,r6
                   25652:        jmp     error
                   25653: er_280:        movzwl  $280,r6
                   25654:        jmp     error
                   25655: er_281:        movzwl  $281,r6
                   25656:        jmp     error
                   25657: er_282:        movzwl  $282,r6
                   25658:        jmp     error
                   25659: er_283:        movzwl  $283,r6
                   25660:        jmp     error
                   25661: er_284:        movzwl  $284,r6
                   25662:        jmp     error
                   25663: er_285:        movzwl  $285,r6
                   25664:        jmp     error
                   25665: er_286:        movzwl  $286,r6
                   25666:        jmp     error
                   25667: er_287:        movzwl  $287,r6
                   25668:        jmp     error
                   25669: er_288:        movzwl  $288,r6
                   25670:        jmp     error
                   25671: er_289:        movzwl  $289,r6
                   25672:        jmp     error
                   25673: er_290:        movzwl  $290,r6
                   25674:        jmp     error
                   25675: er_291:        movzwl  $291,r6
                   25676:        jmp     error
                   25677: er_292:        movzwl  $292,r6
                   25678:        jmp     error
                   25679: er_293:        movzwl  $293,r6
                   25680:        jmp     error
                   25681: er_294:        movzwl  $294,r6
                   25682:        jmp     error
                   25683: er_295:        movzwl  $295,r6
                   25684:        jmp     error
                   25685: er_296:        movzwl  $296,r6
                   25686:        jmp     error
                   25687: er_297:        movzwl  $297,r6
                   25688:        jmp     error
                   25689:        .globl  sec05
                   25690: sec05:         
                   25691:        #sec                    # start of stack overflow section
                   25692: #
                   25693:        incl    errft           # fatal error
                   25694:        movl    flptr,sp        # pop stack to avoid more fails
                   25695:        tstl    gbcfl           # jump if garbage collecting
                   25696:        bnequ   stak1
                   25697:        jmp     er_246          # stack overflow
                   25698: #
                   25699: #      NO CHANCE OF RECOVERY IN MID GARBAGE COLLECTION
                   25700: #
                   25701: stak1: movl    $endso,r9       # point to message
                   25702:        clrl    kvdmp           # memory is undumpable
                   25703:        jmp     stopr           # give up
                   25704:        #title  s p i t b o l -- error section
                   25705: #
                   25706: #      THIS SECTION OF CODE IS ENTERED WHENEVER A PROCEDURE
                   25707: #      RETURN VIA AN ERR PARAMETER OR AN ERB OPCODE IS OBEYED.
                   25708: #
                   25709: #      (WA)                  IS THE ERROR CODE
                   25710: #
                   25711: #      THE GLOBAL VARIABLE STAGE INDICATES THE POINT AT WHICH
                   25712: #      THE ERROR OCCURED AS FOLLOWS.
                   25713: #
                   25714: #      STAGE=STGIC           ERROR DURING INITIAL COMPILE
                   25715: #
                   25716: #      STAGE=STGXC           ERROR DURING COMPILE AT EXECUTE
                   25717: #                            TIME (CODE, CONVERT FUNCTION CALLS)
                   25718: #
                   25719: #      STAGE=STGEV           ERROR DURING COMPILATION OF
                   25720: #                            EXPRESSION AT EXECUTION TIME
                   25721: #                            (EVAL, CONVERT FUNCTION CALL).
                   25722: #
                   25723: #      STAGE=STGXT           ERROR AT EXECUTE TIME. COMPILER
                   25724: #                            NOT ACTIVE.
                   25725: #
                   25726: #      STAGE=STGCE           ERROR DURING INITIAL COMPILE AFTER
                   25727: #                            SCANNING OUT THE END LINE.
                   25728: #
                   25729: #      STAGE=STGXE           ERROR DURING COMPILE AT EXECUTE
                   25730: #                            TIME AFTER SCANNING END LINE.
                   25731: #
                   25732: #      STAGE=STGEE           ERROR DURING EXPRESSION EVALUATION
                   25733: #
                   25734:        #sec                    # start of error section
                   25735: #
                   25736: error: cmpl    r$cim,$cmlab    # jump if error in scanning label
                   25737:        bnequ   0f
                   25738:        jmp     cmple
                   25739: 0:             
                   25740:        movl    r6,kvert        # save error code
                   25741:        clrl    scnrs           # reset rescan switch for scane
                   25742:        clrl    scngo           # reset goto switch for scane
                   25743:        movl    stage,r9        # load current stage
                   25744:        casel   r9,$0,$stgno    # jump to appropriate error circuit
                   25745: 5:             
                   25746:        .word   err01-5b        # initial compile
                   25747:        .word   err04-5b        # execute time compile
                   25748:        .word   err04-5b        # eval compiling expr.
                   25749:        .word   err05-5b        # execute time
                   25750:        .word   err01-5b        # compile - after end
                   25751:        .word   err04-5b        # xeq compile-past end
                   25752:        .word   err04-5b        # eval evaluating expr
                   25753:        #esw                    # end switch on error type
                   25754:        #page   
                   25755: #
                   25756: #      ERROR DURING INITIAL COMPILE
                   25757: #
                   25758: #      THE ERROR MESSAGE IS PRINTED AS PART OF THE COMPILER
                   25759: #      OUTPUT. THIS PRINTOUT INCLUDES THE OFFENDING LINE (IF NOT
                   25760: #      PRINTED ALREADY) AND AN ERROR FLAG UNDER THE APPROPRIATE
                   25761: #      COLUMN AS INDICATED BY SCNSE UNLESS SCNSE IS SET TO ZERO.
                   25762: #
                   25763: #      AFTER PRINTING THE MESSAGE, THE GENERATED CODE IS
                   25764: #      MODIFIED TO AN ERROR CALL AND CONTROL IS RETURNED TO
                   25765: #      THE CMPIL PROCEDURE AFTER RESETTING THE STACK POINTER.
                   25766: #
                   25767: #      IF THE ERROR OCCURS AFTER THE END LINE, CONTROL RETURNS
                   25768: #      IN A SLIGHTLY DIFFERENT MANNER TO ENSURE PROPER CLEANUP.
                   25769: #
                   25770: err01: movl    cmpxs,sp        # reset stack pointer
                   25771:        #ssl    cmpss           # restore s-r stack ptr for cmpil
                   25772:        tstl    errsp           # jump if error suppress flag set
                   25773:        beqlu   0f
                   25774:        jmp     err03
                   25775: 0:             
                   25776:        movl    erich,erlst     # set flag for listr
                   25777:        jsb     listr           # list line
                   25778:        jsb     prtis           # terminate listing
                   25779:        clrl    erlst           # clear listr flag
                   25780:        movl    scnse,r6        # load scan element offset
                   25781:        beqlu   err02           # skip if not set
                   25782:        movl    r6,r7           # loop counter
                   25783:        incl    r6              # increase for ch$ex
                   25784:        jsb     alocs           # string block for error flag
                   25785:        movl    r9,r6           # remember string ptr
                   25786:        movab   cfp$f(r9),r9    # ready for character storing
                   25787:        movl    r$cim,r10       # point to bad statement
                   25788:        movab   cfp$f(r10),r10  # ready to get chars
                   25789: #
                   25790: #      LOOP TO REPLACE ALL CHARS BUT TABS BY BLANKS
                   25791: #
                   25792: erra1: movzbl  (r10)+,r8       # get next char
                   25793:        cmpl    r8,$ch$ht       # skip if tab
                   25794:        beqlu   erra2
                   25795:        movl    $ch$bl,r8       # get a blank
                   25796:        #page   
                   25797: #
                   25798: #      MERGE TO STORE BLANK OR TAB IN ERROR LINE
                   25799: #
                   25800: erra2: movb    r8,(r9)+        # store char
                   25801:        sobgtr  r7,erra1        # loop
                   25802:        movl    $ch$ex,r10      # exclamation mark
                   25803:        movb    r10,(r9)        # store at end of error line
                   25804:        #csc    r9              # end of sch loop
                   25805:        movl    $stnpd,profs    # allow for statement number
                   25806:        movl    r6,r9           # point to error line
                   25807:        jsb     prtst           # print error line
                   25808: #
                   25809: #      HERE AFTER PLACING ERROR FLAG AS REQUIRED
                   25810: #
                   25811: err02: jsb     ermsg           # generate flag and error message
                   25812:        addl2   $num03,lstlc    # bump page ctr for blank, error, blk
                   25813:        clrl    r9              # in case of fatal error
                   25814:        cmpl    errft,$num03    # pack up if several fatals
                   25815:        blssu   0f
                   25816:        jmp     stopr
                   25817: 0:             
                   25818: #
                   25819: #      COUNT ERROR, INHIBIT EXECUTION IF REQUIRED
                   25820: #
                   25821:        incl    cmerc           # bump error count
                   25822:        addl2   cswer,noxeq     # inhibit xeq if -noerrors
                   25823:        cmpl    stage,$stgic    # special return if after end line
                   25824:        beqlu   0f
                   25825:        jmp     cmp10
                   25826: 0:             
                   25827:        #page   
                   25828: #
                   25829: #      LOOP TO SCAN TO END OF STATEMENT
                   25830: #
                   25831: err03: movl    r$cim,r9        # point to start of image
                   25832:        movab   cfp$f(r9),r9    # point to first char
                   25833:        movzbl  (r9),r9         # get first char
                   25834:        cmpl    r9,$ch$mn       # jump if error in control card
                   25835:        bnequ   0f
                   25836:        jmp     cmpce
                   25837: 0:             
                   25838:        clrl    scnrs           # clear rescan flag
                   25839:        movl    sp,errsp        # set error suppress flag
                   25840:        jsb     scane           # scan next element
                   25841:        cmpl    r10,$t$smc      # loop back if not statement end
                   25842:        beqlu   0f
                   25843:        jmp     err03
                   25844: 0:             
                   25845:        clrl    errsp           # clear error suppress flag
                   25846: #
                   25847: #      GENERATE ERROR CALL IN CODE AND RETURN TO CMPIL
                   25848: #
                   25849:        movl    $4*cdcod,cwcof  # reset offset in ccblk
                   25850:        movl    $ocer$,r6       # load compile error call
                   25851:        jsb     cdwrd           # generate it
                   25852:        movl    cwcof,4*cmsoc(sp)# set success fill in offset
                   25853:        movl    sp,4*cmffc(sp)  # set failure fill in flag
                   25854:        jsb     cdwrd           # generate succ. fill in word
                   25855:        jmp     cmpse           # merge to generate error as cdfal
                   25856: #
                   25857: #      ERROR DURING EXECUTE TIME COMPILE OR EXPRESSION EVALUATIO
                   25858: #
                   25859: #      EXECUTE TIME COMPILATION IS INITIATED THROUGH GTCOD OR
                   25860: #      GTEXP WHICH ARE CALLED BY COMPILE, CODE OR EVAL.
                   25861: #      BEFORE CAUSING STATEMENT FAILURE THROUGH EXFAL IT IS
                   25862: #      HELPFUL TO SET KEYWORD ERRTEXT AND FOR GENERALITY
                   25863: #      THESE ERRORS MAY BE HANDLED BY THE SETEXIT MECHANISM.
                   25864: #
                   25865: err04: clrl    r$ccb           # forget garbage code block
                   25866:        #ssl    iniss           # restore main prog s-r stack ptr
                   25867:        jsb     ertex           # get fail message text
                   25868:        subl2   $4,sp           # ensure stack ok on loop start
                   25869: #
                   25870: #      POP STACK UNTIL FIND FLPTR FOR MOST DEEPLY NESTED PROG.
                   25871: #      DEFINED FUNCTION CALL OR CALL OF EVAL / CODE.
                   25872: #
                   25873: erra4: addl2   $4,sp           # pop stack
                   25874:        cmpl    sp,flprt        # jump if prog defined fn call found
                   25875:        beqlu   errc4
                   25876:        cmpl    sp,gtcef        # loop if not eval or code call yet
                   25877:        bnequ   erra4
                   25878:        movl    $stgxt,stage    # re-set stage for execute
                   25879:        movl    r$gtc,r$cod     # recover code ptr
                   25880:        movl    sp,flptr        # restore fail pointer
                   25881:        clrl    r$cim           # forget possible image
                   25882: #
                   25883: #      TEST ERRLIMIT
                   25884: #
                   25885: errb4: tstl    kverl           # jump if errlimit non-zero
                   25886:        bnequ   err07
                   25887:        jmp     exfal           # fail
                   25888: #
                   25889: #      RETURN FROM PROG. DEFINED FUNCTION IS OUTSTANDING
                   25890: #
                   25891: errc4: movl    flptr,sp        # restore stack from flptr
                   25892:        jmp     errb4           # merge
                   25893:        #page   
                   25894: #
                   25895: #      ERROR AT EXECUTE TIME.
                   25896: #
                   25897: #      THE ACTION TAKEN ON AN ERROR IS AS FOLLOWS.
                   25898: #
                   25899: #      IF ERRLIMIT KEYWORD IS ZERO, AN ABORT IS SIGNALLED,
                   25900: #      SEE CODING FOR SYSTEM LABEL ABORT AT L$ABO.
                   25901: #
                   25902: #      OTHERWISE, ERRLIMIT IS DECREMENTED AND AN ERRTYPE TRACE
                   25903: #      GENERATED IF REQUIRED. CONTROL RETURNS EITHER VIA A JUMP
                   25904: #      TO CONTINUE (TO TAKE THE FAILURE EXIT) OR A SPECIFIED
                   25905: #      SETEXIT TRAP IS EXECUTED AND CONTROL PASSES TO THE TRAP.
                   25906: #      IF 3 OR MORE FATAL ERRORS OCCUR AN ABORT IS SIGNALLED
                   25907: #      REGARDLESS OF ERRLIMIT AND SETEXIT - LOOPING IS ALL TOO
                   25908: #      PROBABLE OTHERWISE. FATAL ERRORS INCLUDE STACK OVERFLOW
                   25909: #      AND EXCEEDING STLIMIT.
                   25910: #
                   25911: err05: #ssl    iniss           # restore main prog s-r stack ptr
                   25912:        tstl    dmvch           # jump if in mid-dump
                   25913:        bnequ   err08
                   25914: #
                   25915: #      MERGE HERE FROM ERR08
                   25916: #
                   25917: err06: tstl    kverl           # abort if errlimit is zero
                   25918:        bnequ   0f
                   25919:        jmp     labo1
                   25920: 0:             
                   25921:        jsb     ertex           # get fail message text
                   25922: #
                   25923: #      MERGE FROM ERR04
                   25924: #
                   25925: err07: cmpl    errft,$num03    # abort if too many fatal errors
                   25926:        blssu   0f
                   25927:        jmp     labo1
                   25928: 0:             
                   25929:        decl    kverl           # decrement errlimit
                   25930:        movl    r$ert,r10       # load errtype trace pointer
                   25931:        jsb     ktrex           # generate errtype trace if required
                   25932:        movl    r$cod,r$cnt     # set cdblk ptr for continuation
                   25933:        movl    flptr,r9        # set ptr to failure offset
                   25934:        movl    (r9),stxof      # save failure offset for continue
                   25935:        movl    r$sxc,r9        # load setexit cdblk pointer
                   25936:        bnequ   0f              # continue if no setexit trap
                   25937:        jmp     lcnt1
                   25938: 0:             
                   25939:        clrl    r$sxc           # else reset trap
                   25940:        movl    $nulls,stxvr    # reset setexit arg to null
                   25941:        movl    (r9),r10        # load ptr to code block routine
                   25942:        movl    r10,r11         # execute first trap statement
                   25943:        jmp     (r11)
                   25944: #
                   25945: #      INTERRUPTED PARTLY THROUGH A DUMP WHILST STORE IS IN A
                   25946: #      MESS SO DO A TIDY UP OPERATION. SEE DUMPR FOR DETAILS.
                   25947: #
                   25948: err08: movl    dmvch,r9        # chain head for affected vrblks
                   25949:        beqlu   err06           # done if zero
                   25950:        movl    (r9),dmvch      # set next link as chain head
                   25951:        jsb     setvr           # restore vrget field
                   25952:        jmp     err08           # loop through chain
                   25953:        #title  s p i t b o l -- here endeth the code
                   25954: #
                   25955: #      END OF ASSEMBLY
                   25956: #
                   25957:        #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.