|
|
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: bnequ 0f; jmp cnc08; 0: ! 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: blequ 0f; jmp srh03; 0: ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.